mirror of
				https://github.com/rtlduino/RTL8710AF_GCC.git
				synced 2025-07-31 20:21:04 +00:00 
			
		
		
		
	rtlduino rtl8710af gcc base version
This commit is contained in:
		
							parent
							
								
									7675bdb95f
								
							
						
					
					
						commit
						9c0c9edf61
					
				
					 2097 changed files with 779974 additions and 2 deletions
				
			
		
							
								
								
									
										596
									
								
								component/common/utilities/cJSON.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								component/common/utilities/cJSON.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,596 @@ | |||
| /*
 | ||||
|   Copyright (c) 2009 Dave Gamble | ||||
| 
 | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
|   The above copyright notice and this permission notice shall be included in | ||||
|   all copies or substantial portions of the Software. | ||||
| 
 | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|   THE SOFTWARE. | ||||
| */ | ||||
| 
 | ||||
| /* cJSON */ | ||||
| /* JSON parser in C. */ | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| #include <float.h> | ||||
| #include <limits.h> | ||||
| #include <ctype.h> | ||||
| #include "cJSON.h" | ||||
| 
 | ||||
| static const char *ep; | ||||
| 
 | ||||
| const char *cJSON_GetErrorPtr(void) {return ep;} | ||||
| 
 | ||||
| static int cJSON_strcasecmp(const char *s1,const char *s2) | ||||
| { | ||||
| 	if (!s1) return (s1==s2)?0:1;if (!s2) return 1; | ||||
| 	for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if(*s1 == 0)	return 0; | ||||
| 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); | ||||
| } | ||||
| 
 | ||||
| static void *(*cJSON_malloc)(size_t sz) = malloc; | ||||
| static void (*cJSON_free)(void *ptr) = free; | ||||
| 
 | ||||
| static char* cJSON_strdup(const char* str) | ||||
| { | ||||
|       size_t len; | ||||
|       char* copy; | ||||
| 
 | ||||
|       len = strlen(str) + 1; | ||||
|       if (!(copy = (char*)cJSON_malloc(len))) return 0; | ||||
|       memcpy(copy,str,len); | ||||
|       return copy; | ||||
| } | ||||
| 
 | ||||
| void cJSON_InitHooks(cJSON_Hooks* hooks) | ||||
| { | ||||
|     if (!hooks) { /* Reset hooks */ | ||||
|         cJSON_malloc = malloc; | ||||
|         cJSON_free = free; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| 	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; | ||||
| 	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free; | ||||
| } | ||||
| 
 | ||||
| /* Internal constructor. */ | ||||
| static cJSON *cJSON_New_Item(void) | ||||
| { | ||||
| 	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); | ||||
| 	if (node) memset(node,0,sizeof(cJSON)); | ||||
| 	return node; | ||||
| } | ||||
| 
 | ||||
| /* Delete a cJSON structure. */ | ||||
| void cJSON_Delete(cJSON *c) | ||||
| { | ||||
| 	cJSON *next; | ||||
| 	while (c) | ||||
| 	{ | ||||
| 		next=c->next; | ||||
| 		if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); | ||||
| 		if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); | ||||
| 		if (c->string) cJSON_free(c->string); | ||||
| 		cJSON_free(c); | ||||
| 		c=next; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Parse the input text to generate a number, and populate the result into item. */ | ||||
| const char *parse_number(cJSON *item,const char *num) | ||||
| { | ||||
| 	double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; | ||||
| 
 | ||||
| 	if (*num=='-') sign=-1,num++;	/* Has sign? */ | ||||
| 	if (*num=='0') num++;			/* is zero */ | ||||
| 	if (*num>='1' && *num<='9')	do	n=(n*10.0)+(*num++ -'0');	while (*num>='0' && *num<='9');	/* Number? */ | ||||
| 	if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;		do	n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}	/* Fractional part? */ | ||||
| 	if (*num=='e' || *num=='E')		/* Exponent? */ | ||||
| 	{	num++;if (*num=='+') num++;	else if (*num=='-') signsubscale=-1,num++;		/* With sign? */ | ||||
| 		while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');	/* Number? */ | ||||
| 	} | ||||
| 
 | ||||
| 	n=sign*n*pow(10.0,(scale+subscale*signsubscale));	/* number = +/- number.fraction * 10^+/- exponent */ | ||||
| 	 | ||||
| 	item->valuedouble=n; | ||||
| 	item->valueint=(int)n; | ||||
| 	item->type=cJSON_Number; | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| /* Render the number nicely from the given item into a string. */ | ||||
| static char *print_number(cJSON *item) | ||||
| { | ||||
| 	char *str; | ||||
| 	double d=item->valuedouble; | ||||
| 	if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) | ||||
| 	{ | ||||
| 		str=(char*)cJSON_malloc(21);	/* 2^64+1 can be represented in 21 chars. */ | ||||
| 		if (str) sprintf(str,"%d",item->valueint); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		str=(char*)cJSON_malloc(64);	/* This is a nice tradeoff. */ | ||||
| 		if (str) | ||||
| 		{ | ||||
| 			if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); | ||||
| 			else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)			sprintf(str,"%e",d); | ||||
| 			else												sprintf(str,"%f",d); | ||||
| 		} | ||||
| 	} | ||||
| 	return str; | ||||
| } | ||||
| 
 | ||||
| static unsigned parse_hex4(const char *str) | ||||
| { | ||||
| 	unsigned h=0; | ||||
| 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; | ||||
| 	h=h<<4;str++; | ||||
| 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; | ||||
| 	h=h<<4;str++; | ||||
| 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; | ||||
| 	h=h<<4;str++; | ||||
| 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; | ||||
| 	return h; | ||||
| } | ||||
| 
 | ||||
| /* Parse the input text into an unescaped cstring, and populate item. */ | ||||
| static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; | ||||
| static const char *parse_string(cJSON *item,const char *str) | ||||
| { | ||||
| 	const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; | ||||
| 	if (*str!='\"') {ep=str;return 0;}	/* not a string! */ | ||||
| 	 | ||||
| 	while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;	/* Skip escaped quotes. */ | ||||
| 	 | ||||
| 	out=(char*)cJSON_malloc(len+1);	/* This is how long we need for the string, roughly. */ | ||||
| 	if (!out) return 0; | ||||
| 	 | ||||
| 	ptr=str+1;ptr2=out; | ||||
| 	while (*ptr!='\"' && *ptr) | ||||
| 	{ | ||||
| 		if (*ptr!='\\') *ptr2++=*ptr++; | ||||
| 		else | ||||
| 		{ | ||||
| 			ptr++; | ||||
| 			switch (*ptr) | ||||
| 			{ | ||||
| 				case 'b': *ptr2++='\b';	break; | ||||
| 				case 'f': *ptr2++='\f';	break; | ||||
| 				case 'n': *ptr2++='\n';	break; | ||||
| 				case 'r': *ptr2++='\r';	break; | ||||
| 				case 't': *ptr2++='\t';	break; | ||||
| 				case 'u':	 /* transcode utf16 to utf8. */ | ||||
| 					uc=parse_hex4(ptr+1);ptr+=4;	/* get the unicode char. */ | ||||
| 
 | ||||
| 					if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)	break;	/* check for invalid.	*/ | ||||
| 
 | ||||
| 					if (uc>=0xD800 && uc<=0xDBFF)	/* UTF16 surrogate pairs.	*/ | ||||
| 					{ | ||||
| 						if (ptr[1]!='\\' || ptr[2]!='u')	break;	/* missing second-half of surrogate.	*/ | ||||
| 						uc2=parse_hex4(ptr+3);ptr+=6; | ||||
| 						if (uc2<0xDC00 || uc2>0xDFFF)		break;	/* invalid second-half of surrogate.	*/ | ||||
| 						uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); | ||||
| 					} | ||||
| 
 | ||||
| 					len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; | ||||
| 					 | ||||
| 					switch (len) { | ||||
| 						case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; | ||||
| 						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; | ||||
| 						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; | ||||
| 						case 1: *--ptr2 =(uc | firstByteMark[len]); | ||||
| 					} | ||||
| 					ptr2+=len; | ||||
| 					break; | ||||
| 				default:  *ptr2++=*ptr; break; | ||||
| 			} | ||||
| 			ptr++; | ||||
| 		} | ||||
| 	} | ||||
| 	*ptr2=0; | ||||
| 	if (*ptr=='\"') ptr++; | ||||
| 	item->valuestring=out; | ||||
| 	item->type=cJSON_String; | ||||
| 	return ptr; | ||||
| } | ||||
| 
 | ||||
| /* Render the cstring provided to an escaped version that can be printed. */ | ||||
| static char *print_string_ptr(const char *str) | ||||
| { | ||||
| 	const char *ptr;char *ptr2,*out;int len=0;unsigned char token; | ||||
| 	 | ||||
| 	if (!str) return cJSON_strdup(""); | ||||
| 	ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} | ||||
| 	 | ||||
| 	out=(char*)cJSON_malloc(len+3); | ||||
| 	if (!out) return 0; | ||||
| 
 | ||||
| 	ptr2=out;ptr=str; | ||||
| 	*ptr2++='\"'; | ||||
| 	while (*ptr) | ||||
| 	{ | ||||
| 		if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; | ||||
| 		else | ||||
| 		{ | ||||
| 			*ptr2++='\\'; | ||||
| 			switch (token=*ptr++) | ||||
| 			{ | ||||
| 				case '\\':	*ptr2++='\\';	break; | ||||
| 				case '\"':	*ptr2++='\"';	break; | ||||
| 				case '\b':	*ptr2++='b';	break; | ||||
| 				case '\f':	*ptr2++='f';	break; | ||||
| 				case '\n':	*ptr2++='n';	break; | ||||
| 				case '\r':	*ptr2++='r';	break; | ||||
| 				case '\t':	*ptr2++='t';	break; | ||||
| 				default: sprintf(ptr2,"u%04x",token);ptr2+=5;	break;	/* escape and print */ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	*ptr2++='\"';*ptr2++=0; | ||||
| 	return out; | ||||
| } | ||||
| /* Invote print_string_ptr (which is useful) on an item. */ | ||||
| static char *print_string(cJSON *item)	{return print_string_ptr(item->valuestring);} | ||||
| 
 | ||||
| /* Predeclare these prototypes. */ | ||||
| static const char *parse_value(cJSON *item,const char *value); | ||||
| static char *print_value(cJSON *item,int depth,int fmt); | ||||
| static const char *parse_array(cJSON *item,const char *value); | ||||
| static char *print_array(cJSON *item,int depth,int fmt); | ||||
| static const char *parse_object(cJSON *item,const char *value); | ||||
| static char *print_object(cJSON *item,int depth,int fmt); | ||||
| 
 | ||||
| /* Utility to jump whitespace and cr/lf */ | ||||
| static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} | ||||
| 
 | ||||
| /* Parse an object - create a new root, and populate. */ | ||||
| cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) | ||||
| { | ||||
| 	const char *end=0; | ||||
| 	cJSON *c=cJSON_New_Item(); | ||||
| 	ep=0; | ||||
| 	if (!c) return 0;       /* memory fail */ | ||||
| 
 | ||||
| 	end=parse_value(c,skip(value)); | ||||
| 	if (!end)	{cJSON_Delete(c);return 0;}	/* parse failure. ep is set. */ | ||||
| 
 | ||||
| 	/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ | ||||
| 	if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} | ||||
| 	if (return_parse_end) *return_parse_end=end; | ||||
| 	return c; | ||||
| } | ||||
| /* Default options for cJSON_Parse */ | ||||
| cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} | ||||
| 
 | ||||
| /* Render a cJSON item/entity/structure to text. */ | ||||
| char *cJSON_Print(cJSON *item)				{return print_value(item,0,1);} | ||||
| char *cJSON_PrintUnformatted(cJSON *item)	{return print_value(item,0,0);} | ||||
| 
 | ||||
| /* Parser core - when encountering text, process appropriately. */ | ||||
| static const char *parse_value(cJSON *item,const char *value) | ||||
| { | ||||
| 	if (!value)						return 0;	/* Fail on null. */ | ||||
| 	if (!strncmp(value,"null",4))	{ item->type=cJSON_NULL;  return value+4; } | ||||
| 	if (!strncmp(value,"false",5))	{ item->type=cJSON_False; return value+5; } | ||||
| 	if (!strncmp(value,"true",4))	{ item->type=cJSON_True; item->valueint=1;	return value+4; } | ||||
| 	if (*value=='\"')				{ return parse_string(item,value); } | ||||
| 	if (*value=='-' || (*value>='0' && *value<='9'))	{ return parse_number(item,value); } | ||||
| 	if (*value=='[')				{ return parse_array(item,value); } | ||||
| 	if (*value=='{')				{ return parse_object(item,value); } | ||||
| 
 | ||||
| 	ep=value;return 0;	/* failure. */ | ||||
| } | ||||
| 
 | ||||
| /* Render a value to text. */ | ||||
| static char *print_value(cJSON *item,int depth,int fmt) | ||||
| { | ||||
| 	char *out=0; | ||||
| 	if (!item) return 0; | ||||
| 	switch ((item->type)&255) | ||||
| 	{ | ||||
| 		case cJSON_NULL:	out=cJSON_strdup("null");	break; | ||||
| 		case cJSON_False:	out=cJSON_strdup("false");break; | ||||
| 		case cJSON_True:	out=cJSON_strdup("true"); break; | ||||
| 		case cJSON_Number:	out=print_number(item);break; | ||||
| 		case cJSON_String:	out=print_string(item);break; | ||||
| 		case cJSON_Array:	out=print_array(item,depth,fmt);break; | ||||
| 		case cJSON_Object:	out=print_object(item,depth,fmt);break; | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| /* Build an array from input text. */ | ||||
| static const char *parse_array(cJSON *item,const char *value) | ||||
| { | ||||
| 	cJSON *child; | ||||
| 	if (*value!='[')	{ep=value;return 0;}	/* not an array! */ | ||||
| 
 | ||||
| 	item->type=cJSON_Array; | ||||
| 	value=skip(value+1); | ||||
| 	if (*value==']') return value+1;	/* empty array. */ | ||||
| 
 | ||||
| 	item->child=child=cJSON_New_Item(); | ||||
| 	if (!item->child) return 0;		 /* memory fail */ | ||||
| 	value=skip(parse_value(child,skip(value)));	/* skip any spacing, get the value. */ | ||||
| 	if (!value) return 0; | ||||
| 
 | ||||
| 	while (*value==',') | ||||
| 	{ | ||||
| 		cJSON *new_item; | ||||
| 		if (!(new_item=cJSON_New_Item())) return 0; 	/* memory fail */ | ||||
| 		child->next=new_item;new_item->prev=child;child=new_item; | ||||
| 		value=skip(parse_value(child,skip(value+1))); | ||||
| 		if (!value) return 0;	/* memory fail */ | ||||
| 	} | ||||
| 
 | ||||
| 	if (*value==']') return value+1;	/* end of array */ | ||||
| 	ep=value;return 0;	/* malformed. */ | ||||
| } | ||||
| 
 | ||||
| /* Render an array to text */ | ||||
| static char *print_array(cJSON *item,int depth,int fmt) | ||||
| { | ||||
| 	char **entries; | ||||
| 	char *out=0,*ptr,*ret;int len=5; | ||||
| 	cJSON *child=item->child; | ||||
| 	int numentries=0,i=0,fail=0; | ||||
| 	 | ||||
| 	/* How many entries in the array? */ | ||||
| 	while (child) numentries++,child=child->next; | ||||
| 	/* Explicitly handle numentries==0 */ | ||||
| 	if (!numentries) | ||||
| 	{ | ||||
| 		out=(char*)cJSON_malloc(3); | ||||
| 		if (out) strcpy(out,"[]"); | ||||
| 		return out; | ||||
| 	} | ||||
| 	/* Allocate an array to hold the values for each */ | ||||
| 	entries=(char**)cJSON_malloc(numentries*sizeof(char*)); | ||||
| 	if (!entries) return 0; | ||||
| 	memset(entries,0,numentries*sizeof(char*)); | ||||
| 	/* Retrieve all the results: */ | ||||
| 	child=item->child; | ||||
| 	while (child && !fail) | ||||
| 	{ | ||||
| 		ret=print_value(child,depth+1,fmt); | ||||
| 		entries[i++]=ret; | ||||
| 		if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; | ||||
| 		child=child->next; | ||||
| 	} | ||||
| 	 | ||||
| 	/* If we didn't fail, try to malloc the output string */ | ||||
| 	if (!fail) out=(char*)cJSON_malloc(len); | ||||
| 	/* If that fails, we fail. */ | ||||
| 	if (!out) fail=1; | ||||
| 
 | ||||
| 	/* Handle failure. */ | ||||
| 	if (fail) | ||||
| 	{ | ||||
| 		for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]); | ||||
| 		cJSON_free(entries); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	/* Compose the output array. */ | ||||
| 	*out='['; | ||||
| 	ptr=out+1;*ptr=0; | ||||
| 	for (i=0;i<numentries;i++) | ||||
| 	{ | ||||
| 		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); | ||||
| 		if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;} | ||||
| 		cJSON_free(entries[i]); | ||||
| 	} | ||||
| 	cJSON_free(entries); | ||||
| 	*ptr++=']';*ptr++=0; | ||||
| 	return out;	 | ||||
| } | ||||
| 
 | ||||
| /* Build an object from the text. */ | ||||
| static const char *parse_object(cJSON *item,const char *value) | ||||
| { | ||||
| 	cJSON *child; | ||||
| 	if (*value!='{')	{ep=value;return 0;}	/* not an object! */ | ||||
| 	 | ||||
| 	item->type=cJSON_Object; | ||||
| 	value=skip(value+1); | ||||
| 	if (*value=='}') return value+1;	/* empty array. */ | ||||
| 	 | ||||
| 	item->child=child=cJSON_New_Item(); | ||||
| 	if (!item->child) return 0; | ||||
| 	value=skip(parse_string(child,skip(value))); | ||||
| 	if (!value) return 0; | ||||
| 	child->string=child->valuestring;child->valuestring=0; | ||||
| 	if (*value!=':') {ep=value;return 0;}	/* fail! */ | ||||
| 	value=skip(parse_value(child,skip(value+1)));	/* skip any spacing, get the value. */ | ||||
| 	if (!value) return 0; | ||||
| 	 | ||||
| 	while (*value==',') | ||||
| 	{ | ||||
| 		cJSON *new_item; | ||||
| 		if (!(new_item=cJSON_New_Item()))	return 0; /* memory fail */ | ||||
| 		child->next=new_item;new_item->prev=child;child=new_item; | ||||
| 		value=skip(parse_string(child,skip(value+1))); | ||||
| 		if (!value) return 0; | ||||
| 		child->string=child->valuestring;child->valuestring=0; | ||||
| 		if (*value!=':') {ep=value;return 0;}	/* fail! */ | ||||
| 		value=skip(parse_value(child,skip(value+1)));	/* skip any spacing, get the value. */ | ||||
| 		if (!value) return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	if (*value=='}') return value+1;	/* end of array */ | ||||
| 	ep=value;return 0;	/* malformed. */ | ||||
| } | ||||
| 
 | ||||
| /* Render an object to text. */ | ||||
| static char *print_object(cJSON *item,int depth,int fmt) | ||||
| { | ||||
| 	char **entries=0,**names=0; | ||||
| 	char *out=0,*ptr,*ret,*str;int len=7,i=0,j; | ||||
| 	cJSON *child=item->child; | ||||
| 	int numentries=0,fail=0; | ||||
| 	/* Count the number of entries. */ | ||||
| 	while (child) numentries++,child=child->next; | ||||
| 	/* Explicitly handle empty object case */ | ||||
| 	if (!numentries) | ||||
| 	{ | ||||
| 		out=(char*)cJSON_malloc(fmt?depth+4:3); | ||||
| 		if (!out)	return 0; | ||||
| 		ptr=out;*ptr++='{'; | ||||
| 		if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';} | ||||
| 		*ptr++='}';*ptr++=0; | ||||
| 		return out; | ||||
| 	} | ||||
| 	/* Allocate space for the names and the objects */ | ||||
| 	entries=(char**)cJSON_malloc(numentries*sizeof(char*)); | ||||
| 	if (!entries) return 0; | ||||
| 	names=(char**)cJSON_malloc(numentries*sizeof(char*)); | ||||
| 	if (!names) {cJSON_free(entries);return 0;} | ||||
| 	memset(entries,0,sizeof(char*)*numentries); | ||||
| 	memset(names,0,sizeof(char*)*numentries); | ||||
| 
 | ||||
| 	/* Collect all the results into our arrays: */ | ||||
| 	child=item->child;depth++;if (fmt) len+=depth; | ||||
| 	while (child) | ||||
| 	{ | ||||
| 		names[i]=str=print_string_ptr(child->string); | ||||
| 		entries[i++]=ret=print_value(child,depth,fmt); | ||||
| 		if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; | ||||
| 		child=child->next; | ||||
| 	} | ||||
| 	 | ||||
| 	/* Try to allocate the output string */ | ||||
| 	if (!fail) out=(char*)cJSON_malloc(len); | ||||
| 	if (!out) fail=1; | ||||
| 
 | ||||
| 	/* Handle failure */ | ||||
| 	if (fail) | ||||
| 	{ | ||||
| 		for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);} | ||||
| 		cJSON_free(names);cJSON_free(entries); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	/* Compose the output: */ | ||||
| 	*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0; | ||||
| 	for (i=0;i<numentries;i++) | ||||
| 	{ | ||||
| 		if (fmt) for (j=0;j<depth;j++) *ptr++='\t'; | ||||
| 		strcpy(ptr,names[i]);ptr+=strlen(names[i]); | ||||
| 		*ptr++=':';if (fmt) *ptr++='\t'; | ||||
| 		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); | ||||
| 		if (i!=numentries-1) *ptr++=','; | ||||
| 		if (fmt) *ptr++='\n';*ptr=0; | ||||
| 		cJSON_free(names[i]);cJSON_free(entries[i]); | ||||
| 	} | ||||
| 	 | ||||
| 	cJSON_free(names);cJSON_free(entries); | ||||
| 	if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t'; | ||||
| 	*ptr++='}';*ptr++=0; | ||||
| 	return out;	 | ||||
| } | ||||
| 
 | ||||
| /* Get Array size/item / object item. */ | ||||
| int    cJSON_GetArraySize(cJSON *array)							{cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;} | ||||
| cJSON *cJSON_GetArrayItem(cJSON *array,int item)				{cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;} | ||||
| cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} | ||||
| 
 | ||||
| /* Utility for array list handling. */ | ||||
| static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} | ||||
| /* Utility for handling references. */ | ||||
| static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} | ||||
| 
 | ||||
| /* Add item to array/object. */ | ||||
| void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} | ||||
| void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} | ||||
| void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));} | ||||
| void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));} | ||||
| 
 | ||||
| cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)			{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; | ||||
| 	if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} | ||||
| void   cJSON_DeleteItemFromArray(cJSON *array,int which)			{cJSON_Delete(cJSON_DetachItemFromArray(array,which));} | ||||
| cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} | ||||
| void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} | ||||
| 
 | ||||
| /* Replace array/object items with new ones. */ | ||||
| void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; | ||||
| 	newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; | ||||
| 	if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} | ||||
| void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){if(newitem->string) cJSON_free(newitem->string);newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} | ||||
| 
 | ||||
| /* Create basic types: */ | ||||
| cJSON *cJSON_CreateNull(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} | ||||
| cJSON *cJSON_CreateTrue(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} | ||||
| cJSON *cJSON_CreateFalse(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} | ||||
| cJSON *cJSON_CreateBool(int b)					{cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} | ||||
| cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} | ||||
| cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} | ||||
| cJSON *cJSON_CreateArray(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} | ||||
| cJSON *cJSON_CreateObject(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} | ||||
| 
 | ||||
| /* Create Arrays: */ | ||||
| cJSON *cJSON_CreateIntArray(const int *numbers,int count)		{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;} | ||||
| cJSON *cJSON_CreateFloatArray(const float *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;} | ||||
| cJSON *cJSON_CreateDoubleArray(const double *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;} | ||||
| cJSON *cJSON_CreateStringArray(const char **strings,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;} | ||||
| 
 | ||||
| /* Duplication */ | ||||
| cJSON *cJSON_Duplicate(cJSON *item,int recurse) | ||||
| { | ||||
| 	cJSON *newitem,*cptr,*nptr=0,*newchild; | ||||
| 	/* Bail on bad ptr */ | ||||
| 	if (!item) return 0; | ||||
| 	/* Create new item */ | ||||
| 	newitem=cJSON_New_Item(); | ||||
| 	if (!newitem) return 0; | ||||
| 	/* Copy over all vars */ | ||||
| 	newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; | ||||
| 	if (item->valuestring)	{newitem->valuestring=cJSON_strdup(item->valuestring);	if (!newitem->valuestring)	{cJSON_Delete(newitem);return 0;}} | ||||
| 	if (item->string)		{newitem->string=cJSON_strdup(item->string);			if (!newitem->string)		{cJSON_Delete(newitem);return 0;}} | ||||
| 	/* If non-recursive, then we're done! */ | ||||
| 	if (!recurse) return newitem; | ||||
| 	/* Walk the ->next chain for the child. */ | ||||
| 	cptr=item->child; | ||||
| 	while (cptr) | ||||
| 	{ | ||||
| 		newchild=cJSON_Duplicate(cptr,1);		/* Duplicate (with recurse) each item in the ->next chain */ | ||||
| 		if (!newchild) {cJSON_Delete(newitem);return 0;} | ||||
| 		if (nptr)	{nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}	/* If newitem->child already set, then crosswire ->prev and ->next and move on */ | ||||
| 		else		{newitem->child=newchild;nptr=newchild;}					/* Set newitem->child and move to it */ | ||||
| 		cptr=cptr->next; | ||||
| 	} | ||||
| 	return newitem; | ||||
| } | ||||
| 
 | ||||
| void cJSON_Minify(char *json) | ||||
| { | ||||
| 	char *into=json; | ||||
| 	while (*json) | ||||
| 	{ | ||||
| 		if (*json==' ') json++; | ||||
| 		else if (*json=='\t') json++;	// Whitespace characters.
 | ||||
| 		else if (*json=='\r') json++; | ||||
| 		else if (*json=='\n') json++; | ||||
| 		else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;	// double-slash comments, to end of line.
 | ||||
| 		else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}	// multiline comments.
 | ||||
| 		else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
 | ||||
| 		else *into++=*json++;			// All other characters.
 | ||||
| 	} | ||||
| 	*into=0;	// and null-terminate.
 | ||||
| } | ||||
							
								
								
									
										145
									
								
								component/common/utilities/cJSON.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								component/common/utilities/cJSON.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,145 @@ | |||
| /*
 | ||||
|   Copyright (c) 2009 Dave Gamble | ||||
|   | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|   | ||||
|   The above copyright notice and this permission notice shall be included in | ||||
|   all copies or substantial portions of the Software. | ||||
|   | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|   THE SOFTWARE. | ||||
| */ | ||||
| 
 | ||||
| #ifndef cJSON__h | ||||
| #define cJSON__h | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| /* cJSON Types: */ | ||||
| #define cJSON_False 0 | ||||
| #define cJSON_True 1 | ||||
| #define cJSON_NULL 2 | ||||
| #define cJSON_Number 3 | ||||
| #define cJSON_String 4 | ||||
| #define cJSON_Array 5 | ||||
| #define cJSON_Object 6 | ||||
| 	 | ||||
| #define cJSON_IsReference 256 | ||||
| 
 | ||||
| /* The cJSON structure: */ | ||||
| typedef struct cJSON { | ||||
| 	struct cJSON *next,*prev;	/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ | ||||
| 	struct cJSON *child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ | ||||
| 
 | ||||
| 	int type;					/* The type of the item, as above. */ | ||||
| 
 | ||||
| 	char *valuestring;			/* The item's string, if type==cJSON_String */ | ||||
| 	int valueint;				/* The item's number, if type==cJSON_Number */ | ||||
| 	double valuedouble;			/* The item's number, if type==cJSON_Number */ | ||||
| 
 | ||||
| 	char *string;				/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ | ||||
| } cJSON; | ||||
| 
 | ||||
| typedef struct cJSON_Hooks { | ||||
|       void *(*malloc_fn)(size_t sz); | ||||
|       void (*free_fn)(void *ptr); | ||||
| } cJSON_Hooks; | ||||
| 
 | ||||
| /* Supply malloc, realloc and free functions to cJSON */ | ||||
| extern void cJSON_InitHooks(cJSON_Hooks* hooks); | ||||
| 
 | ||||
| 
 | ||||
| /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ | ||||
| extern cJSON *cJSON_Parse(const char *value); | ||||
| /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ | ||||
| extern char  *cJSON_Print(cJSON *item); | ||||
| /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ | ||||
| extern char  *cJSON_PrintUnformatted(cJSON *item); | ||||
| /* Delete a cJSON entity and all subentities. */ | ||||
| extern void   cJSON_Delete(cJSON *c); | ||||
| 
 | ||||
| /* Returns the number of items in an array (or object). */ | ||||
| extern int	  cJSON_GetArraySize(cJSON *array); | ||||
| /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ | ||||
| extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); | ||||
| /* Get item "string" from object. Case insensitive. */ | ||||
| extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); | ||||
| 
 | ||||
| /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ | ||||
| extern const char *cJSON_GetErrorPtr(void); | ||||
| 	 | ||||
| /* These calls create a cJSON item of the appropriate type. */ | ||||
| extern cJSON *cJSON_CreateNull(void); | ||||
| extern cJSON *cJSON_CreateTrue(void); | ||||
| extern cJSON *cJSON_CreateFalse(void); | ||||
| extern cJSON *cJSON_CreateBool(int b); | ||||
| extern cJSON *cJSON_CreateNumber(double num); | ||||
| extern cJSON *cJSON_CreateString(const char *string); | ||||
| extern cJSON *cJSON_CreateArray(void); | ||||
| extern cJSON *cJSON_CreateObject(void); | ||||
| 
 | ||||
| /* These utilities create an Array of count items. */ | ||||
| extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); | ||||
| extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); | ||||
| extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); | ||||
| extern cJSON *cJSON_CreateStringArray(const char **strings,int count); | ||||
| 
 | ||||
| /* Append item to the specified array/object. */ | ||||
| extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); | ||||
| extern void	cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); | ||||
| /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ | ||||
| extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); | ||||
| extern void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); | ||||
| 
 | ||||
| /* Remove/Detatch items from Arrays/Objects. */ | ||||
| extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); | ||||
| extern void   cJSON_DeleteItemFromArray(cJSON *array,int which); | ||||
| extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); | ||||
| extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string); | ||||
| 	 | ||||
| /* Update array items. */ | ||||
| extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); | ||||
| extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); | ||||
| 
 | ||||
| /* Duplicate a cJSON item */ | ||||
| extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); | ||||
| /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
 | ||||
| need to be released. With recurse!=0, it will duplicate any children connected to the item. | ||||
| The item->next and ->prev pointers are always zero on return from Duplicate. */ | ||||
| 
 | ||||
| /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ | ||||
| extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); | ||||
| 
 | ||||
| extern void cJSON_Minify(char *json); | ||||
| 
 | ||||
| /* Macros for creating things quickly. */ | ||||
| #define cJSON_AddNullToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateNull()) | ||||
| #define cJSON_AddTrueToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) | ||||
| #define cJSON_AddFalseToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) | ||||
| #define cJSON_AddBoolToObject(object,name,b)	cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) | ||||
| #define cJSON_AddNumberToObject(object,name,n)	cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) | ||||
| #define cJSON_AddStringToObject(object,name,s)	cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) | ||||
| 
 | ||||
| /* When assigning an integer value, it needs to be propagated to valuedouble too. */ | ||||
| #define cJSON_SetIntValue(object,val)			((object)?(object)->valueint=(object)->valuedouble=(val):(val)) | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										137
									
								
								component/common/utilities/http_client.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								component/common/utilities/http_client.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| //#include <stdio.h>
 | ||||
| //#include <stdlib.h>
 | ||||
| //#include <string.h>
 | ||||
| 
 | ||||
| #include "platform/platform_stdlib.h" | ||||
| 
 | ||||
| #include "FreeRTOS.h" | ||||
| 
 | ||||
| const char * http_strstr(const char *str1, const char *str2) { | ||||
| 	char *a, *b; | ||||
| 
 | ||||
| 	/* First scan quickly through the two strings looking for a
 | ||||
| 	* single-character match.  When it's found, then compare the | ||||
| 	* rest of the substring. | ||||
| 	*/ | ||||
| 
 | ||||
| 	b = (char *)str2; | ||||
| 	if (*b == 0) { | ||||
| 		return str1; | ||||
| 	} | ||||
| 	for ( ; *str1 != 0; str1 += 1) { | ||||
| 		if (*str1 != *b) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		a = (char *)str1; | ||||
| 		while (1) { | ||||
| 			if (*b == 0) { | ||||
| 				return str1; | ||||
| 			} | ||||
| 			if (*a++ != *b++) { | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		b = (char *)str2; | ||||
| 	} | ||||
| 	return (char *) 0; | ||||
| } | ||||
| 
 | ||||
| static void* http_malloc(unsigned int size) | ||||
| { | ||||
| 	return pvPortMalloc(size); | ||||
| } | ||||
| 
 | ||||
| void http_free(void *buf) | ||||
| { | ||||
| 	vPortFree(buf); | ||||
| } | ||||
| 
 | ||||
| static char *http_itoa(int value) | ||||
| { | ||||
| 	char *val_str; | ||||
| 	int tmp = value, len = 1; | ||||
| 
 | ||||
| 	while((tmp /= 10) > 0) | ||||
| 		len ++; | ||||
| 
 | ||||
| 	val_str = (char *) http_malloc(len + 1); | ||||
| 	sprintf(val_str, "%d", value); | ||||
| 
 | ||||
| 	return val_str; | ||||
| } | ||||
| 
 | ||||
| char *http_post_header(char *host, char *resource, char *type, int data_len) | ||||
| { | ||||
| 	char *len_str = http_itoa(data_len); | ||||
| 	char *header = (char *) http_malloc(strlen("POST ") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ") + strlen(host) +  | ||||
| 		strlen("\r\nContent-Type: ") + strlen(type) + strlen("\r\nContent-Length: ") + strlen(len_str) + strlen("\r\n\r\n") + 1); | ||||
| 	sprintf(header, "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n", resource, host, type, len_str); | ||||
| 	http_free(len_str); | ||||
| 
 | ||||
| 	return header; | ||||
| } | ||||
| 
 | ||||
| char *http_get_header(char *host, char *resource) | ||||
| { | ||||
| 	char *header = (char *) http_malloc(strlen("GET ") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ") + strlen(host) + strlen("\r\n\r\n") + 1); | ||||
| 	sprintf(header, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", resource, host); | ||||
| 
 | ||||
| 	return header; | ||||
| } | ||||
| 
 | ||||
| char *http_response_header(char *buf, int response_len) | ||||
| { | ||||
| 	char *http_response, *http_header = NULL, *header_end; | ||||
| 	int header_len; | ||||
| 
 | ||||
| 	http_response = (char *) http_malloc(response_len + 1); | ||||
| 	memcpy(http_response, buf, response_len); | ||||
| 	http_response[response_len] = '\0'; | ||||
| 
 | ||||
| 	if(strncmp(http_response, "HTTP", 4) == 0) { | ||||
| 		if((header_end = (char *)http_strstr(http_response, "\r\n\r\n")) != NULL) { | ||||
| 			header_end += 4; | ||||
| 			header_len = header_end - http_response; | ||||
| 			http_header = (char *) http_malloc(header_len + 1); | ||||
| 			memcpy(http_header, http_response, header_len); | ||||
| 			http_header[header_len] = '\0'; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	http_free(http_response); | ||||
| 
 | ||||
| 	return http_header; | ||||
| } | ||||
| 
 | ||||
| char *http_response_body(char *buf, int response_len) | ||||
| { | ||||
| 	char *http_response, *http_body = NULL, *body_start; | ||||
| 	int body_len; | ||||
| 
 | ||||
| 	http_response = (char *) http_malloc(response_len + 1); | ||||
| 	memcpy(http_response, buf, response_len); | ||||
| 	http_response[response_len] = '\0'; | ||||
| 
 | ||||
| 	if(strncmp(http_response, "HTTP", 4) == 0) { | ||||
| 		if((body_start = (char *)http_strstr(http_response, "\r\n\r\n")) != NULL) { | ||||
| 			body_start += 4; | ||||
| 			body_len = http_response + response_len - body_start; | ||||
| 
 | ||||
| 			if(body_len > 0) { | ||||
| 				http_body = (char *) http_malloc(body_len + 1); | ||||
| 				memcpy(http_body, body_start, body_len); | ||||
| 				http_body[body_len] = '\0'; | ||||
| 			} | ||||
| 
 | ||||
| 			http_free(http_response); | ||||
| 		} | ||||
| 		else { | ||||
| 			http_body = http_response; | ||||
| 		} | ||||
| 	} | ||||
| 	else { | ||||
| 		http_body = http_response; | ||||
| 	} | ||||
| 
 | ||||
| 	return http_body; | ||||
| } | ||||
							
								
								
									
										10
									
								
								component/common/utilities/http_client.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								component/common/utilities/http_client.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| #ifndef _HTTP_H_ | ||||
| #define _HTTP_H_ | ||||
| 
 | ||||
| char *http_post_header(char *address, char *resource, char *type, int data_len); | ||||
| char *http_get_header(char *address, char *resource); | ||||
| char *http_response_header(char *buf, int response_len); | ||||
| char *http_response_body(char *buf, int response_len); | ||||
| void http_free(void *buf); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										243
									
								
								component/common/utilities/ssl_client.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								component/common/utilities/ssl_client.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,243 @@ | |||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
| #include "polarssl/config.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "polarssl/net.h" | ||||
| #include "polarssl/ssl.h" | ||||
| #include "polarssl/error.h" | ||||
| #include "polarssl/memory.h" | ||||
| 
 | ||||
| #define SERVER_PORT   443 | ||||
| #define SERVER_HOST   "192.168.13.15" | ||||
| #define GET_REQUEST   "GET / HTTP/1.0\r\n\r\n" | ||||
| #define DEBUG_LEVEL   0 | ||||
| 
 | ||||
| //#define SSL_CLIENT_EXT
 | ||||
| #ifdef SSL_CLIENT_EXT | ||||
| #define STACKSIZE     2048 | ||||
| #else | ||||
| #define STACKSIZE     1150 | ||||
| #endif | ||||
| 
 | ||||
| static int is_task = 0; | ||||
| static char server_host[16]; | ||||
| static size_t min_heap_size = 0; | ||||
| 
 | ||||
| static void my_debug(void *ctx, int level, const char *str) | ||||
| { | ||||
| 	if(level <= DEBUG_LEVEL) { | ||||
| 		printf("\n\r%s", str); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int my_random(void *p_rng, unsigned char *output, size_t output_len) | ||||
| { | ||||
| 	rtw_get_random_bytes(output, output_len); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void* my_malloc(size_t size) | ||||
| { | ||||
| 	void *ptr = pvPortMalloc(size); | ||||
| 	size_t current_heap_size = xPortGetFreeHeapSize(); | ||||
| 
 | ||||
| 	if((current_heap_size < min_heap_size) || (min_heap_size == 0)) | ||||
| 		min_heap_size = current_heap_size; | ||||
| 
 | ||||
| 	return ptr; | ||||
| } | ||||
| 
 | ||||
| #define my_free		vPortFree | ||||
| 
 | ||||
| static void ssl_client(void *param) | ||||
| { | ||||
| 	int ret, len, server_fd = -1; | ||||
| 	unsigned char buf[512]; | ||||
| 	ssl_context ssl; | ||||
| 	int retry_count = 0; | ||||
| 
 | ||||
| 	memory_set_own(my_malloc, my_free); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 1. Start the connection | ||||
| 	 */ | ||||
| 	printf("\n\r  . Connecting to tcp/%s/%d...", server_host, SERVER_PORT); | ||||
| 
 | ||||
| 	if((ret = net_connect(&server_fd, server_host, SERVER_PORT)) != 0) { | ||||
| 		printf(" failed\n\r  ! net_connect returned %d\n", ret); | ||||
| 		goto exit1; | ||||
| 	} | ||||
| 
 | ||||
| 	printf(" ok\n"); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 2. Setup stuff | ||||
| 	 */ | ||||
| 	printf("\n\r  . Setting up the SSL/TLS structure..." ); | ||||
| 
 | ||||
| 	if((ret = ssl_init(&ssl)) != 0) { | ||||
| 		printf(" failed\n\r  ! ssl_init returned %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| #ifdef SSL_CLIENT_EXT | ||||
| 	if((ret = ssl_client_ext_init()) != 0) { | ||||
| 		printf(" failed\n\r  ! ssl_client_ext_init returned %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| #endif | ||||
| 	ssl_set_endpoint(&ssl, SSL_IS_CLIENT); | ||||
| 	ssl_set_authmode(&ssl, SSL_VERIFY_NONE); | ||||
| 	ssl_set_rng(&ssl, my_random, NULL); | ||||
| 	ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd); | ||||
| 	ssl_set_dbg(&ssl, my_debug, NULL); | ||||
| #ifdef POLARSSL_DEBUG_C | ||||
| 	debug_set_threshold(DEBUG_LEVEL); | ||||
| #endif | ||||
| #ifdef SSL_CLIENT_EXT | ||||
| 	if((ret = ssl_client_ext_setup(&ssl)) != 0) { | ||||
| 		printf(" failed\n\r  ! ssl_client_ext_setup returned %d\n", ret); | ||||
| 		goto exit; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	printf(" ok\n"); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 3. Handshake | ||||
| 	 */ | ||||
| 	printf("\n\r  . Performing the SSL/TLS handshake..."); | ||||
| 
 | ||||
| 	while((ret = ssl_handshake(&ssl)) != 0) { | ||||
| 		if((ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE   | ||||
| 			&& ret != POLARSSL_ERR_NET_RECV_FAILED) || retry_count >= 5) { | ||||
| 			printf(" failed\n\r  ! ssl_handshake returned -0x%x\n", -ret); | ||||
| 			goto exit; | ||||
| 		} | ||||
| 		retry_count++; | ||||
| 	} | ||||
| 
 | ||||
| 	printf(" ok\n"); | ||||
| 	printf("\n\r  . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl)); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 4. Write the GET request | ||||
| 	 */ | ||||
| 	printf("\n\r  > Write to server:"); | ||||
| 
 | ||||
| 	len = sprintf((char *) buf, GET_REQUEST); | ||||
| 
 | ||||
| 	while((ret = ssl_write(&ssl, buf, len)) <= 0) { | ||||
| 		if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { | ||||
| 			printf(" failed\n\r  ! ssl_write returned %d\n", ret); | ||||
| 			goto exit; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	len = ret; | ||||
| 	printf(" %d bytes written\n\r\n\r%s\n", len, (char *) buf); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 5. Read the HTTP response | ||||
| 	 */ | ||||
| 	printf("\n\r  < Read from server:"); | ||||
| 
 | ||||
| 	do { | ||||
| 		len = sizeof(buf) - 1; | ||||
| 		memset(buf, 0, sizeof(buf)); | ||||
| 		ret = ssl_read(&ssl, buf, len); | ||||
| 
 | ||||
| 		if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) | ||||
| 			break; | ||||
| 
 | ||||
| 		if(ret < 0) { | ||||
| 			printf(" failed\n\r  ! ssl_read returned %d\n", ret); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if(ret == 0) { | ||||
| 			printf("\n\rEOF\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		len = ret; | ||||
| 		printf(" %d bytes read\n\r\n\r%s\n", len, (char *) buf); | ||||
| 	} | ||||
| 	while(1); | ||||
| 
 | ||||
| 	ssl_close_notify(&ssl); | ||||
| 
 | ||||
| exit: | ||||
| 
 | ||||
| #ifdef POLARSSL_ERROR_C | ||||
| 	if(ret != 0) { | ||||
| 		char error_buf[100]; | ||||
| 		polarssl_strerror(ret, error_buf, 100); | ||||
| 		printf("\n\rLast error was: %d - %s\n", ret, error_buf); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	net_close(server_fd); | ||||
| 	ssl_free(&ssl); | ||||
| #ifdef SSL_CLIENT_EXT | ||||
| 	ssl_client_ext_free(); | ||||
| #endif | ||||
| exit1: | ||||
| 
 | ||||
| 	if(is_task) { | ||||
| #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) | ||||
| 		printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); | ||||
| #endif | ||||
| 
 | ||||
| 		if(min_heap_size > 0) | ||||
| 			printf("\n\rMin available heap size = %d bytes during %s\n\r", min_heap_size, __FUNCTION__); | ||||
| 
 | ||||
| 		vTaskDelete(NULL); | ||||
| 	} | ||||
| 
 | ||||
| 	if(param != NULL) | ||||
| 		*((int *) param) = ret; | ||||
| } | ||||
| 
 | ||||
| void start_ssl_client(void) | ||||
| { | ||||
| 	is_task = 1; | ||||
| 	//strcpy(server_host, SERVER_HOST);
 | ||||
| 
 | ||||
| 	if(xTaskCreate(ssl_client, "ssl_client", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) | ||||
| 		printf("\n\r%s xTaskCreate failed", __FUNCTION__); | ||||
| } | ||||
| 
 | ||||
| void do_ssl_connect(void) | ||||
| { | ||||
| 	int ret; | ||||
| 	static int success = 0; | ||||
| 	static int fail = 0; | ||||
| 
 | ||||
| 	is_task = 0; | ||||
| 	strcpy(server_host, SERVER_HOST); | ||||
| 	ssl_client(&ret); | ||||
| 
 | ||||
| 	if(ret != 0) | ||||
| 		printf("\n\r%s fail (success %d times, fail %d times)\n\r", __FUNCTION__, success, ++ fail); | ||||
| 	else | ||||
| 		printf("\n\r%s success (success %d times, fail %d times)\n\r", __FUNCTION__, ++ success, fail); | ||||
| } | ||||
| 
 | ||||
| void cmd_ssl_client(int argc, char **argv) | ||||
| { | ||||
| 	if(argc == 2) { | ||||
| 		strcpy(server_host, argv[1]); | ||||
| 	} | ||||
| 	else { | ||||
| 		printf("\n\rUsage: %s SSL_SERVER_HOST", argv[0]); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	start_ssl_client(); | ||||
| } | ||||
							
								
								
									
										180
									
								
								component/common/utilities/ssl_client_ext.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								component/common/utilities/ssl_client_ext.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,180 @@ | |||
| #include <polarssl/ssl.h> | ||||
| #include <polarssl/memory.h> | ||||
| 
 | ||||
| //#define SSL_VERIFY_CLIENT
 | ||||
| //#define SSL_VERIFY_SERVER
 | ||||
| 
 | ||||
| #ifdef SSL_VERIFY_CLIENT | ||||
| static x509_crt* _cli_crt = NULL; | ||||
| static pk_context* _clikey_rsa = NULL; | ||||
| 
 | ||||
| static const char *test_client_key = \ | ||||
| "-----BEGIN RSA PRIVATE KEY-----\r\n" \ | ||||
| "MIICXgIBAAKBgQDKLbkPtV0uhoqkHxHl/sZlq5TrUqu6pScqGkMnEUDKIFR5QMNf\r\n" \ | ||||
| "qLgbGPwbreN4AkHQlvqnn/2Swz1uurUH4pxcGp54j7QmANXvd5hJtCMhPpDcPS6k\r\n" \ | ||||
| "ldlIJ8y3KoCoqAot6uo9IL/IKKk3aOQqeHKayIyjOOksjMkgeE8/gCpmFQIDAQAB\r\n" \ | ||||
| "AoGBAKoSBj+Bh83wXUWr4SmAxLGXwSCnHVBXRveyudRuPfsJcSXCZdbdHWml/cTm\r\n" \ | ||||
| "5Jb6BxUJO/avreW8GLxBkLD+XhnXlkw1RJ8FYZPXdzlNJzoYyVK0GZ/qyGacEEFt\r\n" \ | ||||
| "ekvGfBJIq+7ksKcJt5c9qARClOvauYLRGwubl64xD6PupSINAkEA+5C395h227nc\r\n" \ | ||||
| "5zF8s2rYBP78i5uS7hKqqVjGy8pcIFHiM/0ehzcN3V3gJXLjkAbXfvP0h/tm8eQG\r\n" \ | ||||
| "QUpJBY/YLwJBAM2+IOfTmEBxrpASUeN1Lx9yg0+Swyz8oz2a2blfFwbpCWBi18M2\r\n" \ | ||||
| "huo+YECeMggqBBYwgQ9J2ixpaj/e9+0pkPsCQQDztTWkFf4/y4WoLBcEseNoo6YB\r\n" \ | ||||
| "kcv7+/V9bdXZI8ewP+OGPhdPIxS5efJmFTFEHHy0Lp6dBf6rJB6zLcYkL0BdAkEA\r\n" \ | ||||
| "nGBqeknlavX9DBwgiZXD308WZyDRoBvVpzlPSwnvYp01N0FpZULIgLowRmz28iWd\r\n" \ | ||||
| "PZBYR9qGLUNiMnGyV1xEiQJAOdlBM4M9Xj2Z9inCdkgFkbIOSe5kvIPC24CjZyyG\r\n" \ | ||||
| "g3lK/YezoDmdD//OLoY81y6VdO5dwjm7P0wZB63EDRidHA==\r\n" \ | ||||
| "-----END RSA PRIVATE KEY-----\r\n"; | ||||
| 
 | ||||
| static const char *test_client_cert = \ | ||||
| "-----BEGIN CERTIFICATE-----\r\n" \ | ||||
| "MIIC4DCCAkmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB7MQswCQYDVQQGEwJDTjEL\r\n" \ | ||||
| "MAkGA1UECAwCSlMxCzAJBgNVBAcMAlNaMRAwDgYDVQQKDAdSZWFsc2lsMRAwDgYD\r\n" \ | ||||
| "VQQLDAdSZWFsdGVrMRAwDgYDVQQDDAdSZWFsc2lsMRwwGgYJKoZIhvcNAQkBFg1h\r\n" \ | ||||
| "QHJlYWxzaWwuY29tMB4XDTE1MTIyMzA2NTI0MFoXDTE2MTIyMjA2NTI0MFowdDEL\r\n" \ | ||||
| "MAkGA1UEBhMCQ04xCzAJBgNVBAgMAkpTMRAwDgYDVQQKDAdSZWFsc2lsMRAwDgYD\r\n" \ | ||||
| "VQQLDAdSZWFsdGVrMRYwFAYDVQQDDA0xOTIuMTY4LjEuMTQxMRwwGgYJKoZIhvcN\r\n" \ | ||||
| "AQkBFg1jQHJlYWxzaWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK\r\n" \ | ||||
| "LbkPtV0uhoqkHxHl/sZlq5TrUqu6pScqGkMnEUDKIFR5QMNfqLgbGPwbreN4AkHQ\r\n" \ | ||||
| "lvqnn/2Swz1uurUH4pxcGp54j7QmANXvd5hJtCMhPpDcPS6kldlIJ8y3KoCoqAot\r\n" \ | ||||
| "6uo9IL/IKKk3aOQqeHKayIyjOOksjMkgeE8/gCpmFQIDAQABo3sweTAJBgNVHRME\r\n" \ | ||||
| "AjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0\r\n" \ | ||||
| "ZTAdBgNVHQ4EFgQUJLmwJNyKHCTEspNTPNpbPjXkjnQwHwYDVR0jBBgwFoAUAfLa\r\n" \ | ||||
| "cSF933h+3pYNcs36lvm7yEkwDQYJKoZIhvcNAQELBQADgYEAlo495gu94nMHFYx4\r\n" \ | ||||
| "+V7PjwGIqanqwLjsem9qvwJa/K1QoM4JxnqRXFUdSfZMhnlrMgPer4fDHpWAutWB\r\n" \ | ||||
| "X2Fiww+VVJSn8Go0seK8RQf8n/n3rJ5B3lef1Po2zHchELWhlFT6k5Won7gp64RN\r\n" \ | ||||
| "9PcwFFy0Va/bkJsot//kdZNKs/g=\r\n" \ | ||||
| "-----END CERTIFICATE-----\r\n"; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef SSL_VERIFY_SERVER | ||||
| static x509_crt* _ca_crt = NULL; | ||||
| 
 | ||||
| static const char *test_ca_cert = \ | ||||
| "-----BEGIN CERTIFICATE-----\r\n" \ | ||||
| "MIICxDCCAi2gAwIBAgIJANdeY8UOfqpBMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNV\r\n" \ | ||||
| "BAYTAkNOMQswCQYDVQQIDAJKUzELMAkGA1UEBwwCU1oxEDAOBgNVBAoMB1JlYWxz\r\n" \ | ||||
| "aWwxEDAOBgNVBAsMB1JlYWx0ZWsxEDAOBgNVBAMMB1JlYWxzaWwxHDAaBgkqhkiG\r\n" \ | ||||
| "9w0BCQEWDWFAcmVhbHNpbC5jb20wHhcNMTUxMjIzMDYzMDA1WhcNMTYxMjIyMDYz\r\n" \ | ||||
| "MDA1WjB7MQswCQYDVQQGEwJDTjELMAkGA1UECAwCSlMxCzAJBgNVBAcMAlNaMRAw\r\n" \ | ||||
| "DgYDVQQKDAdSZWFsc2lsMRAwDgYDVQQLDAdSZWFsdGVrMRAwDgYDVQQDDAdSZWFs\r\n" \ | ||||
| "c2lsMRwwGgYJKoZIhvcNAQkBFg1hQHJlYWxzaWwuY29tMIGfMA0GCSqGSIb3DQEB\r\n" \ | ||||
| "AQUAA4GNADCBiQKBgQCmfNpluJZP0Sla+MIYzRGA1rljK5VncuBKQiKBF4BdO73H\r\n" \ | ||||
| "OTUoT0ydR7x7lS2Ns1HQop2oldroJVBj38+pLci1i/3flkONCDfsWOzfcGZ9RItq\r\n" \ | ||||
| "Zf9eQI8CEZI5i0Fvi3mgaoqCXvutFBrtTQRNsKQD69SqxEWWPb1y+Fd2nONeawID\r\n" \ | ||||
| "AQABo1AwTjAdBgNVHQ4EFgQUAfLacSF933h+3pYNcs36lvm7yEkwHwYDVR0jBBgw\r\n" \ | ||||
| "FoAUAfLacSF933h+3pYNcs36lvm7yEkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\r\n" \ | ||||
| "AQsFAAOBgQA6McwC1Vk4k/5Bh/sf9cfwSK9A0ecaIH0NizYoWpWRAsv7TDgj0PbO\r\n" \ | ||||
| "Qqxi/QhpuYezgRqKqAv7QYNSQa39X7opzSsdSGtTnId374PZZeCDqZpfcAbsNk5o\r\n" \ | ||||
| "6HLpJ27esFa/flTL0FtmO+AT2uiPMvRP0a4u4uuLQK2Jgm/CmzJ47w==\r\n" \ | ||||
| "-----END CERTIFICATE-----\r\n"; | ||||
| 
 | ||||
| static int my_verify(void *data, x509_crt *crt, int depth, int *flags)  | ||||
| { | ||||
| 	char buf[1024]; | ||||
| 	((void) data); | ||||
| 
 | ||||
| 	printf("Verify requested for (Depth %d):\n", depth); | ||||
| 	x509_crt_info(buf, sizeof(buf) - 1, "", crt); | ||||
| 	printf("%s", buf); | ||||
| 
 | ||||
| 	if(((*flags) & BADCERT_EXPIRED) != 0) | ||||
| 		printf("server certificate has expired\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCERT_REVOKED) != 0) | ||||
| 		printf("  ! server certificate has been revoked\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCERT_CN_MISMATCH) != 0) | ||||
| 		printf("  ! CN mismatch\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCERT_NOT_TRUSTED) != 0) | ||||
| 		printf("  ! self-signed or not signed by a trusted CA\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCRL_NOT_TRUSTED) != 0) | ||||
| 		printf("  ! CRL not trusted\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCRL_EXPIRED) != 0) | ||||
| 		printf("  ! CRL expired\n"); | ||||
| 
 | ||||
| 	if(((*flags) & BADCERT_OTHER) != 0) | ||||
| 		printf("  ! other (unknown) flag\n"); | ||||
| 
 | ||||
| 	if((*flags) == 0) | ||||
| 		printf("  Certificate verified without error flags\n"); | ||||
| 
 | ||||
| 	return(0); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int ssl_client_ext_init(void) | ||||
| { | ||||
| #ifdef SSL_VERIFY_CLIENT | ||||
| 	_cli_crt = polarssl_malloc(sizeof(x509_crt)); | ||||
| 	 | ||||
| 	if(_cli_crt) | ||||
| 		x509_crt_init(_cli_crt); | ||||
| 	else | ||||
| 		return -1; | ||||
| 
 | ||||
| 	_clikey_rsa = polarssl_malloc(sizeof(pk_context)); | ||||
| 
 | ||||
| 	if(_clikey_rsa) | ||||
| 		pk_init(_clikey_rsa); | ||||
| 	else | ||||
| 		return -1; | ||||
| #endif | ||||
| #ifdef SSL_VERIFY_SERVER | ||||
| 	_ca_crt = polarssl_malloc(sizeof(x509_crt)); | ||||
| 
 | ||||
| 	if(_ca_crt) | ||||
| 		x509_crt_init(_ca_crt); | ||||
| 	else | ||||
| 		return -1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void ssl_client_ext_free(void) | ||||
| { | ||||
| #ifdef SSL_VERIFY_CLIENT | ||||
| 	if(_cli_crt) { | ||||
| 		x509_crt_free(_cli_crt); | ||||
| 		polarssl_free(_cli_crt); | ||||
| 		_cli_crt = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if(_clikey_rsa) { | ||||
| 		pk_free(_clikey_rsa); | ||||
| 		polarssl_free(_clikey_rsa); | ||||
| 		_clikey_rsa = NULL; | ||||
| 	} | ||||
| #endif	 | ||||
| #ifdef SSL_VERIFY_SERVER | ||||
| 	if(_ca_crt) { | ||||
| 		x509_crt_free(_ca_crt); | ||||
| 		polarssl_free(_ca_crt); | ||||
| 		_ca_crt = NULL; | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| int ssl_client_ext_setup(ssl_context *ssl) | ||||
| { | ||||
| #ifdef SSL_VERIFY_CLIENT | ||||
| 	if(x509_crt_parse(_cli_crt, test_client_cert, strlen(test_client_cert)) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	if(pk_parse_key(_clikey_rsa, test_client_key, strlen(test_client_key), NULL, 0) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	ssl_set_own_cert(ssl, _cli_crt, _clikey_rsa); | ||||
| #endif | ||||
| #ifdef SSL_VERIFY_SERVER | ||||
| 	if(x509_crt_parse(_ca_crt, test_ca_cert, strlen(test_ca_cert)) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	ssl_set_ca_chain(ssl, _ca_crt, NULL, NULL); | ||||
| 	ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED); | ||||
| 	ssl_set_verify(ssl, my_verify, NULL); | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										121
									
								
								component/common/utilities/tcpecho.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								component/common/utilities/tcpecho.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,121 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2001-2003 Swedish Institute of Computer Science. | ||||
|  * All rights reserved.  | ||||
|  *  | ||||
|  * Redistribution and use in source and binary forms, with or without modification,  | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer in the documentation | ||||
|  *    and/or other materials provided with the distribution. | ||||
|  * 3. The name of the author may not be used to endorse or promote products | ||||
|  *    derived from this software without specific prior written permission.  | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  | ||||
|  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  | ||||
|  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  | ||||
|  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  | ||||
|  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  | ||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  | ||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  | ||||
|  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  | ||||
|  * OF SUCH DAMAGE. | ||||
|  * | ||||
|  * This file is part of the lwIP TCP/IP stack. | ||||
|  *  | ||||
|  * Author: Adam Dunkels <adam@sics.se> | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #include "lwip/opt.h" | ||||
| 
 | ||||
| #if LWIP_NETCONN | ||||
| 
 | ||||
| #include "lwip/sys.h" | ||||
| #include "lwip/api.h" | ||||
| 
 | ||||
| #define TCPECHO_THREAD_PRIO  ( tskIDLE_PRIORITY + 3 ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*-----------------------------------------------------------------------------------*/ | ||||
| static void tcpecho_thread(void *arg) | ||||
| { | ||||
|   struct netconn *conn, *newconn; | ||||
|   err_t err; | ||||
| 
 | ||||
|   LWIP_UNUSED_ARG(arg); | ||||
| 
 | ||||
|   /* Create a new connection identifier. */ | ||||
|   conn = netconn_new(NETCONN_TCP); | ||||
|    | ||||
|   if (conn!=NULL) | ||||
|   {   | ||||
|     /* Bind connection to well known port number 7. */ | ||||
|     err = netconn_bind(conn, NULL, 7); | ||||
|      | ||||
|     if (err == ERR_OK) | ||||
|     { | ||||
|       /* Tell connection to go into listening mode. */ | ||||
|       netconn_listen(conn); | ||||
|      | ||||
|       while (1)  | ||||
|       { | ||||
|         /* Grab new connection. */ | ||||
|         newconn = netconn_accept(conn); | ||||
|      | ||||
|         /* Process the new connection. */ | ||||
|         if (newconn)  | ||||
|         { | ||||
|           struct netbuf *buf; | ||||
|           void *data; | ||||
|           u16_t len; | ||||
|        | ||||
|           while ((buf = netconn_recv(newconn)) != NULL)  | ||||
|           { | ||||
|             do  | ||||
|             { | ||||
|               netbuf_data(buf, &data, &len); | ||||
|               netconn_write(newconn, data, len, NETCONN_COPY); | ||||
|            | ||||
|             }  | ||||
|             while (netbuf_next(buf) >= 0); | ||||
|            | ||||
|             netbuf_delete(buf); | ||||
|           } | ||||
|          | ||||
|           /* Close connection and discard connection identifier. */ | ||||
|           netconn_close(newconn); | ||||
|           netconn_delete(newconn); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       printf(" can not bind TCP netconn"); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     printf("can not create TCP netconn"); | ||||
|   } | ||||
| } | ||||
| /*-----------------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| void tcpecho_init(void) | ||||
| { | ||||
|   sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO); | ||||
| } | ||||
| /*-----------------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| void cmd_tcpecho(int argc, char **argv) | ||||
| { | ||||
| 	printf("\n\rInit TCP ECHO Server ..."); | ||||
| 	tcpecho_init(); | ||||
| 	printf("\n\r\nPlease use echotool to connect to this echo server. ex. echotool 192.168.0.1 /p tcp /r 7 /n 0"); | ||||
| } | ||||
| #endif /* LWIP_NETCONN */ | ||||
							
								
								
									
										928
									
								
								component/common/utilities/tcptest.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										928
									
								
								component/common/utilities/tcptest.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,928 @@ | |||
| #include "FreeRTOS.h" | ||||
| #include "task.h" | ||||
| #include "main.h" | ||||
| 
 | ||||
| #include <lwip/sockets.h> | ||||
| #include <lwip/raw.h> | ||||
| #include <lwip/icmp.h> | ||||
| #include <lwip/inet_chksum.h> | ||||
| #include <platform/platform_stdlib.h> | ||||
| 
 | ||||
| #define PER_SECOND_REPORT       1 | ||||
| #define BSD_STACK_SIZE		    2048 | ||||
| #define DEFAULT_PORT            5001 | ||||
| #define DEFAULT_TIME            10 | ||||
| #define SERVER_BUF_SIZE         1500 | ||||
| #define CLIENT_BUF_SIZE         1460 | ||||
| #define KB                      1024 | ||||
| #define MB                      1048576//1024*1024
 | ||||
| #define DEFAULT_TCP_BANDWIDTH   131072 //128*1024Bytes = 1Mbits
 | ||||
| #define DEFAULT_UDP_BANDWIDTH   131072 //128*1024Bytes = 1Mbits
 | ||||
| #define DEFAULT_UDP_TOS_VALUE   96 // BE=96
 | ||||
| 
 | ||||
| 
 | ||||
| struct iperf_data_t{ | ||||
|     char server_ip[16]; | ||||
|     int  server_fd; | ||||
|     int  client_fd; | ||||
|     uint16_t port; | ||||
|     unsigned char start; | ||||
|     unsigned int buf_size; | ||||
|     uint32_t time; | ||||
|     uint64_t total_size; | ||||
|     uint64_t bandwidth; | ||||
|     uint8_t tos_value; | ||||
| }; | ||||
| 
 | ||||
| struct iperf_data_t tcp_server_data,tcp_client_data,udp_server_data,udp_client_data; | ||||
| 
 | ||||
| xTaskHandle g_tcp_server_task = NULL; | ||||
| xTaskHandle g_tcp_client_task = NULL; | ||||
| xTaskHandle g_udp_client_task = NULL; | ||||
| xTaskHandle g_udp_server_task = NULL; | ||||
| unsigned char g_tcp_terminate = 0; | ||||
| unsigned char g_udp_terminate = 0; | ||||
| 
 | ||||
| int tcp_client_func(struct iperf_data_t iperf_data) | ||||
| { | ||||
|     struct sockaddr_in  ser_addr; | ||||
|     char                *buffer = NULL; | ||||
|     int                 i=0; | ||||
|     uint32_t            start_time, end_time, report_start_time; | ||||
|     uint64_t            total_size=0,report_size=0; | ||||
| 
 | ||||
| 	buffer = pvPortMalloc(iperf_data.buf_size); | ||||
| 	if(!buffer){ | ||||
| 		printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); | ||||
|         goto Exit2; | ||||
| 	} | ||||
|     //filling the buffer
 | ||||
|     for (i = 0; i < iperf_data.buf_size; i++){ | ||||
|         buffer[i] = (char)(i % 10); | ||||
|     } | ||||
| 
 | ||||
|     //create socket
 | ||||
|     if( (iperf_data.client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Create TCP socket failed",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
| 
 | ||||
|     //initialize value in dest
 | ||||
|     memset(&ser_addr, 0, sizeof(ser_addr)); | ||||
|     ser_addr.sin_family = AF_INET; | ||||
|     ser_addr.sin_port = htons(iperf_data.port); | ||||
|     ser_addr.sin_addr.s_addr = inet_addr(iperf_data.server_ip); | ||||
| 
 | ||||
|     printf("\n\r%s: Server IP=%s, port=%d", __func__,iperf_data.server_ip, iperf_data.port); | ||||
|     printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.client_fd); | ||||
| 
 | ||||
|     //Connecting to server
 | ||||
|     if( connect(iperf_data.client_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Connect to server failed",__func__); | ||||
|         goto Exit1; | ||||
|     } | ||||
|     printf("\n\r%s: Connect to server successfully",__func__); | ||||
|     if(iperf_data.total_size == 0){ | ||||
|         start_time = xTaskGetTickCount(); | ||||
|         end_time = start_time; | ||||
|         report_start_time = start_time; | ||||
|         while ( ((end_time - start_time) <= (configTICK_RATE_HZ * iperf_data.time)) && (!g_tcp_terminate) ) { | ||||
|             if( send(iperf_data.client_fd, buffer, iperf_data.buf_size,0) <= 0){ | ||||
|                 printf("\n\r[ERROR] %s: TCP client send data error",__func__); | ||||
|                 goto Exit1; | ||||
|             } | ||||
|             total_size+=iperf_data.buf_size; | ||||
|             report_size+=iperf_data.buf_size; | ||||
|             end_time = xTaskGetTickCount(); | ||||
|             if(((end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { | ||||
| #if PER_SECOND_REPORT | ||||
|                 printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); | ||||
| #endif | ||||
|                 report_start_time = end_time; | ||||
|                 report_size = 0; | ||||
|             } | ||||
|             else if( (iperf_data.bandwidth!=0) && (report_size >= iperf_data.bandwidth) ){ | ||||
|             	while((end_time - report_start_time) < configTICK_RATE_HZ){ | ||||
| 					end_time = xTaskGetTickCount(); | ||||
| 				} | ||||
| #if PER_SECOND_REPORT | ||||
|             	printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); | ||||
| #endif | ||||
|             	report_start_time = end_time; | ||||
|                 report_size = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     else{ | ||||
|     	start_time = xTaskGetTickCount(); | ||||
| 		end_time = start_time; | ||||
| 		report_start_time = start_time; | ||||
|         while ( (total_size < iperf_data.total_size) && (!g_tcp_terminate) ) { | ||||
|             if( send(iperf_data.client_fd, buffer, iperf_data.buf_size,0) <= 0){ | ||||
|                 printf("\n\r[ERROR] %s: TCP client send data error",__func__); | ||||
|                 goto Exit1; | ||||
|             } | ||||
|             total_size+=iperf_data.buf_size; | ||||
|             report_size+=iperf_data.buf_size; | ||||
|             end_time = xTaskGetTickCount(); | ||||
|             if(((end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { | ||||
| #if PER_SECOND_REPORT | ||||
|             	printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); | ||||
| #endif | ||||
|             	report_start_time = end_time; | ||||
|                 report_size = 0; | ||||
|             } | ||||
|             else if( (iperf_data.bandwidth!=0) && (report_size >= iperf_data.bandwidth) ){ | ||||
|             	while((end_time - report_start_time) < configTICK_RATE_HZ){ | ||||
| 					end_time = xTaskGetTickCount(); | ||||
| 				} | ||||
| #if PER_SECOND_REPORT | ||||
| 				printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); | ||||
| #endif | ||||
| 				report_start_time = end_time; | ||||
|                 report_size = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     printf("\n\r%s: [END] Totally send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(total_size/KB),(uint32_t)(end_time-start_time),((uint32_t)(total_size*8)/(end_time - start_time))); | ||||
| 
 | ||||
| Exit1: | ||||
|     closesocket(iperf_data.client_fd); | ||||
| Exit2: | ||||
|     printf("\n\r%s: Close client socket",__func__); | ||||
| 	if(buffer) | ||||
| 		vPortFree(buffer); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int tcp_server_func(struct iperf_data_t iperf_data) | ||||
| { | ||||
|     struct sockaddr_in   ser_addr , client_addr; | ||||
|     char                 *buffer = NULL; | ||||
|     int                  addrlen = sizeof(struct sockaddr_in); | ||||
|     int                  n = 1; | ||||
|     int                  recv_size=0; | ||||
|     uint64_t             total_size=0,report_size=0; | ||||
|     uint32_t             start_time, report_start_time, report_end_time; | ||||
| 
 | ||||
| 	buffer = pvPortMalloc(iperf_data.buf_size); | ||||
| 	if(!buffer){ | ||||
| 		printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); | ||||
|         goto Exit3; | ||||
| 	} | ||||
| 
 | ||||
|     //create socket
 | ||||
|     if((iperf_data.server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Create socket failed",__func__); | ||||
|         goto Exit3; | ||||
|     } | ||||
| 
 | ||||
|     printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.server_fd); | ||||
| 
 | ||||
|     setsockopt( iperf_data.server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); | ||||
| 
 | ||||
|     //initialize structure dest
 | ||||
|     memset(&ser_addr, 0, sizeof(ser_addr)); | ||||
|     ser_addr.sin_family = AF_INET; | ||||
|     ser_addr.sin_port = htons(iperf_data.port); | ||||
|     ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
| 
 | ||||
|     // binding the TCP socket to the TCP server address
 | ||||
|     if( bind(iperf_data.server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Bind socket failed",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
|     printf("\n\r%s: Bind socket successfully",__func__); | ||||
| 
 | ||||
|     //Make it listen to socket with max 20 connections
 | ||||
|     if( listen(iperf_data.server_fd, 20) != 0){ | ||||
|         printf("\n\r[ERROR] %s: Listen socket failed",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
|     printf("\n\r%s: Listen port %d",__func__,iperf_data.port); | ||||
| 
 | ||||
| Restart: | ||||
|     if( (iperf_data.client_fd = accept(iperf_data.server_fd, (struct sockaddr*)&client_addr, &addrlen)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Accept TCP client socket error!",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
|     printf("\n\r%s: Accept connection successfully",__func__); | ||||
| 
 | ||||
|     start_time = xTaskGetTickCount(); | ||||
|     report_start_time = start_time; | ||||
|     while (!g_tcp_terminate) { | ||||
|         recv_size = recv(iperf_data.client_fd, buffer, iperf_data.buf_size, 0);  //MSG_DONTWAIT   MSG_WAITALL
 | ||||
|         if( recv_size < 0){ | ||||
|             printf("\n\r[ERROR] %s: Receive data failed",__func__); | ||||
|             goto Exit1; | ||||
|         } | ||||
|         else if(recv_size == 0){ | ||||
|         	printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (total_size/KB),(uint32_t) (report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); | ||||
|             total_size=0; | ||||
|             close(iperf_data.client_fd); | ||||
|             goto Restart; | ||||
|         } | ||||
|         report_end_time = xTaskGetTickCount(); | ||||
|         total_size+=recv_size; | ||||
|         report_size+=recv_size; | ||||
|         if(((report_end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((report_end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { | ||||
| #if PER_SECOND_REPORT | ||||
|         	printf("\n\r%s: Receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (report_size/KB),(uint32_t) (report_end_time-report_start_time),((uint32_t)(report_size*8)/(report_end_time - report_start_time))); | ||||
| #endif | ||||
|         	report_start_time = report_end_time; | ||||
|             report_size = 0; | ||||
|         } | ||||
|         else if((report_end_time - report_start_time) > (configTICK_RATE_HZ * 2)){ | ||||
|             report_start_time = report_end_time; | ||||
|             start_time = report_end_time; | ||||
|             report_size = 0; | ||||
|         } | ||||
|     } | ||||
|     printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (total_size/KB),(uint32_t) (report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); | ||||
| 
 | ||||
| Exit1: | ||||
|     // close the connected socket after receiving from connected TCP client
 | ||||
|     close(iperf_data.client_fd); | ||||
| 
 | ||||
| Exit2: | ||||
|     // close the listening socket
 | ||||
|     close(iperf_data.server_fd); | ||||
| 
 | ||||
| Exit3: | ||||
| 	if(buffer) | ||||
| 		vPortFree(buffer); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int udp_client_func(struct iperf_data_t iperf_data) | ||||
| { | ||||
|     struct sockaddr_in  ser_addr; | ||||
|     char                *buffer = NULL; | ||||
|     int                 i=0; | ||||
|     int                 addrlen = sizeof(struct sockaddr_in); | ||||
|     uint32_t            start_time, end_time, bandwidth_time; | ||||
|     uint64_t            total_size=0, bandwidth_size=0; | ||||
| 
 | ||||
| 
 | ||||
| 	buffer = pvPortMalloc(iperf_data.buf_size); | ||||
| 	if(!buffer){ | ||||
| 		printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); | ||||
|         goto Exit2; | ||||
| 	} | ||||
| 
 | ||||
|     //filling the buffer
 | ||||
| 	for (i = 0; i < iperf_data.buf_size; i++){ | ||||
| 		buffer[i] = (char)(i % 10); | ||||
| 	} | ||||
| 
 | ||||
|     //create socket
 | ||||
|     if( (iperf_data.client_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Create UDP socket failed",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
| 
 | ||||
|     //initialize value in dest
 | ||||
|     memset(&ser_addr, 0, sizeof(ser_addr)); | ||||
|     ser_addr.sin_family = AF_INET; | ||||
|     ser_addr.sin_port = htons(iperf_data.port); | ||||
|     ser_addr.sin_addr.s_addr = inet_addr(iperf_data.server_ip); | ||||
| 
 | ||||
|     printf("\n\r%s: Server IP=%s, port=%d", __func__,iperf_data.server_ip, iperf_data.port); | ||||
|     printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.client_fd); | ||||
| 
 | ||||
|     lwip_setsockopt(iperf_data.client_fd,IPPROTO_IP,IP_TOS,&iperf_data.tos_value,sizeof(iperf_data.tos_value)); | ||||
| 
 | ||||
|     if(iperf_data.total_size == 0){ | ||||
|         start_time = xTaskGetTickCount(); | ||||
|         end_time = start_time; | ||||
|         bandwidth_time = start_time; | ||||
|         while ( ((end_time - start_time) <= (configTICK_RATE_HZ * iperf_data.time)) && (!g_udp_terminate) ) { | ||||
|             if( sendto(iperf_data.client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){ | ||||
|                 //printf("\n\r[ERROR] %s: UDP client send data error",__func__);
 | ||||
|             }else{ | ||||
|                 total_size+=iperf_data.buf_size; | ||||
|                 bandwidth_size+=iperf_data.buf_size; | ||||
|             } | ||||
| 
 | ||||
|             if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){ | ||||
| #if PER_SECOND_REPORT | ||||
|                 printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t)( bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); | ||||
| #endif | ||||
|                 bandwidth_time = end_time; | ||||
|                 bandwidth_size = 0; | ||||
|             }else{ | ||||
|                 if(bandwidth_size >= iperf_data.bandwidth){ | ||||
|                     while((end_time - bandwidth_time) < configTICK_RATE_HZ){ | ||||
|                         end_time = xTaskGetTickCount(); | ||||
|                     } | ||||
| #if PER_SECOND_REPORT | ||||
|                     printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); | ||||
| #endif | ||||
|                     bandwidth_time = end_time; | ||||
|                     bandwidth_size = 0; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             end_time = xTaskGetTickCount(); | ||||
|         } | ||||
|     } | ||||
|     else{ | ||||
|     	start_time = xTaskGetTickCount(); | ||||
| 		end_time = start_time; | ||||
| 		bandwidth_time = start_time; | ||||
|         while ( (total_size < iperf_data.total_size) && (!g_udp_terminate) ) { | ||||
|             if( sendto(iperf_data.client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){ | ||||
|                 //printf("\n\r[ERROR] %s: UDP client send data error",__func__);
 | ||||
|             }else{ | ||||
|                 total_size+=iperf_data.buf_size; | ||||
|                 bandwidth_size+=iperf_data.buf_size; | ||||
|             } | ||||
|             if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){ | ||||
| #if PER_SECOND_REPORT | ||||
|                 printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); | ||||
| #endif | ||||
|                 bandwidth_time = end_time; | ||||
|                 bandwidth_size = 0; | ||||
|             }else{ | ||||
|                 if(bandwidth_size >= iperf_data.bandwidth){ | ||||
|                     while((end_time - bandwidth_time) < (configTICK_RATE_HZ*1)){ | ||||
|                         end_time = xTaskGetTickCount(); | ||||
|                     } | ||||
| #if PER_SECOND_REPORT | ||||
|                     printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); | ||||
| #endif | ||||
|                     bandwidth_time = end_time; | ||||
|                     bandwidth_size = 0; | ||||
|                 } | ||||
|             } | ||||
|             end_time = xTaskGetTickCount(); | ||||
|         } | ||||
|     } | ||||
|     printf("\n\r%s: [END] Totally send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(total_size/KB),(uint32_t)(end_time-start_time),((uint32_t)(total_size*8)/(end_time - start_time))); | ||||
| 
 | ||||
| Exit1: | ||||
|     close(iperf_data.client_fd); | ||||
| Exit2: | ||||
|     printf("\n\r%s: Close client socket",__func__); | ||||
| 	if(buffer) | ||||
| 		vPortFree(buffer); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int udp_server_func(struct iperf_data_t iperf_data) | ||||
| { | ||||
|     int                  server_fd; | ||||
|     struct sockaddr_in   ser_addr , client_addr; | ||||
|     char                 *buffer = NULL; | ||||
|     int                  addrlen = sizeof(struct sockaddr_in); | ||||
|     int                  n = 1; | ||||
|     uint32_t             start_time, report_start_time, report_end_time; | ||||
|     int                  recv_size=0; | ||||
|     uint64_t             total_size=0,report_size=0; | ||||
| 
 | ||||
| 	buffer = pvPortMalloc(iperf_data.buf_size); | ||||
| 	if(!buffer){ | ||||
| 		printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); | ||||
|         goto Exit2; | ||||
| 	} | ||||
| 
 | ||||
|     //create socket
 | ||||
|     if((iperf_data.server_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Create socket failed",__func__); | ||||
|         goto Exit2; | ||||
|     } | ||||
| 
 | ||||
|     printf("\n\r%s: Create socket fd = %d, port = %d", __func__,iperf_data.server_fd,iperf_data.port); | ||||
| 
 | ||||
|     setsockopt( iperf_data.server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); | ||||
| 
 | ||||
|     //initialize structure dest
 | ||||
|     memset(&ser_addr, 0, sizeof(ser_addr)); | ||||
|     ser_addr.sin_family = AF_INET; | ||||
|     ser_addr.sin_port = htons(iperf_data.port); | ||||
|     ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
| 
 | ||||
|     // binding the TCP socket to the TCP server address
 | ||||
|     if( bind(iperf_data.server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ | ||||
|         printf("\n\r[ERROR] %s: Bind socket failed",__func__); | ||||
|         goto Exit1; | ||||
|     } | ||||
| 
 | ||||
|     printf("\n\r%s: Bind socket successfully",__func__); | ||||
| 
 | ||||
|     start_time = xTaskGetTickCount(); | ||||
|     report_start_time = start_time; | ||||
| 
 | ||||
|     while (!g_udp_terminate) { | ||||
|         recv_size = recvfrom(iperf_data.server_fd,buffer,iperf_data.buf_size,0,(struct sockaddr *) &client_addr,&addrlen); | ||||
|         if( recv_size < 0){ | ||||
|             printf("\n\r[ERROR] %s: Receive data failed",__func__); | ||||
|             goto Exit1; | ||||
|         } | ||||
|         // ack data to client
 | ||||
|         // Not send ack to prevent send fail due to limited skb, but it will have warning at iperf client
 | ||||
|         //sendto(server_fd,buffer,ret,0,(struct sockaddr*)&client_addr,sizeof(client_addr));
 | ||||
| 
 | ||||
|         report_end_time = xTaskGetTickCount(); | ||||
|         total_size+=recv_size; | ||||
|         report_size+=recv_size; | ||||
|         if(((report_end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((report_end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { | ||||
| #if PER_SECOND_REPORT | ||||
|         	printf("\n\r%s: Receive %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t) (report_size/KB),(uint32_t)(report_end_time-report_start_time),((uint32_t)(report_size*8)/(report_end_time - report_start_time))); | ||||
| #endif | ||||
|         	report_start_time = report_end_time; | ||||
|             report_size = 0; | ||||
|         } | ||||
|         else if((report_end_time - report_start_time) > (configTICK_RATE_HZ * 2)){ | ||||
|             report_start_time = report_end_time; | ||||
|             start_time = report_end_time; | ||||
|             report_size = 0; | ||||
|         } | ||||
|     } | ||||
|     printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t) (total_size/KB),(uint32_t)(report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); | ||||
| 
 | ||||
| Exit1: | ||||
|     // close the listening socket
 | ||||
|     close(iperf_data.server_fd); | ||||
| 
 | ||||
| Exit2: | ||||
| 	if(buffer) | ||||
| 		vPortFree(buffer); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void tcp_client_handler(void *param) | ||||
| { | ||||
|     vTaskDelay(100); | ||||
|     if(tcp_client_data.port == 0) | ||||
|         tcp_client_data.port = DEFAULT_PORT; | ||||
|     if(tcp_client_data.time == 0) | ||||
|         tcp_client_data.time = DEFAULT_TIME; | ||||
|     if(tcp_client_data.buf_size == 0) | ||||
|         tcp_client_data.buf_size = CLIENT_BUF_SIZE; | ||||
| 
 | ||||
|     printf("\n\rTCP: Start TCP client!"); | ||||
|     tcp_client_func(tcp_client_data); | ||||
| 
 | ||||
| #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) | ||||
|     printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); | ||||
| #endif | ||||
|     printf("\n\rTCP: TCP client stopped!"); | ||||
|     g_tcp_client_task = NULL; | ||||
|     vTaskDelete(NULL); | ||||
| } | ||||
| 
 | ||||
| static void tcp_server_handler(void *param) | ||||
| { | ||||
|     vTaskDelay(100); | ||||
|     if(tcp_server_data.port == 0) | ||||
|         tcp_server_data.port = DEFAULT_PORT; | ||||
|     if(tcp_server_data.buf_size == 0) | ||||
|         tcp_server_data.buf_size = SERVER_BUF_SIZE; | ||||
| 
 | ||||
|     printf("\n\rTCP: Start TCP server!"); | ||||
|     tcp_server_func(tcp_server_data); | ||||
| 
 | ||||
| #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) | ||||
|     printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); | ||||
| #endif | ||||
|     printf("\n\rTCP: TCP server stopped!"); | ||||
|     g_tcp_server_task = NULL; | ||||
|     vTaskDelete(NULL); | ||||
| } | ||||
| 
 | ||||
| void udp_client_handler(void *param) | ||||
| { | ||||
|     vTaskDelay(100); | ||||
|     if(udp_client_data.port == 0) | ||||
|         udp_client_data.port = DEFAULT_PORT; | ||||
|     if(udp_client_data.time == 0) | ||||
|         udp_client_data.time = DEFAULT_TIME; | ||||
|     if(udp_client_data.bandwidth == 0) | ||||
|         udp_client_data.bandwidth = DEFAULT_UDP_BANDWIDTH; | ||||
|     if(udp_client_data.buf_size == 0) | ||||
|         udp_client_data.buf_size = CLIENT_BUF_SIZE; | ||||
|     if(udp_client_data.tos_value == 0) | ||||
|     	udp_client_data.tos_value = DEFAULT_UDP_TOS_VALUE; | ||||
| 
 | ||||
|     printf("\n\rUDP: Start UDP client!"); | ||||
| 	udp_client_func(udp_client_data); | ||||
| 
 | ||||
| #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) | ||||
| 	printf("\n\rMin available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); | ||||
| #endif | ||||
| 
 | ||||
| 	printf("\n\rUDP: UDP client stopped!"); | ||||
| 	g_udp_client_task = NULL; | ||||
| 	vTaskDelete(NULL);	 | ||||
| } | ||||
| 
 | ||||
| void udp_server_handler(void *param) | ||||
| { | ||||
|     vTaskDelay(100); | ||||
|     if(udp_server_data.port == 0) | ||||
|         udp_server_data.port = DEFAULT_PORT; | ||||
|     if(udp_server_data.buf_size == 0) | ||||
|         udp_server_data.buf_size = SERVER_BUF_SIZE; | ||||
| 
 | ||||
|     printf("\n\rUDP: Start UDP server!"); | ||||
| 	udp_server_func(udp_server_data); | ||||
| 
 | ||||
| #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) | ||||
| 	printf("\n\rMin available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); | ||||
| #endif | ||||
| 
 | ||||
| 	printf("\n\rUDP: UDP server stopped!"); | ||||
| 	g_udp_server_task = NULL; | ||||
| 	vTaskDelete(NULL);	 | ||||
| } | ||||
| 
 | ||||
| uint64_t km_parser(char *buf, int len) | ||||
| { | ||||
|     uint64_t ret=0; | ||||
|     int keyword_num=0; | ||||
|     char num_str[17] = "\0"; | ||||
|     uint64_t num; | ||||
| 
 | ||||
|     if(len>16) | ||||
|         return ret; | ||||
| 
 | ||||
|     while((buf[keyword_num] != '\0')&&(keyword_num<len)){ | ||||
|         if((buf[keyword_num] == 'k')||(buf[keyword_num] == 'K')){ | ||||
|             strncpy(num_str,buf,keyword_num); | ||||
|             num = strtol(num_str,NULL,10); | ||||
|             ret = num * KB; | ||||
|             break; | ||||
|         } | ||||
|         else if((buf[keyword_num] == 'm')||(buf[keyword_num] == 'M')){ | ||||
|             strncpy(num_str,buf,keyword_num); | ||||
|             num = strtol(num_str,NULL,10); | ||||
|             ret = num * MB; | ||||
|             break; | ||||
|         } | ||||
|         keyword_num++; | ||||
|         if(keyword_num == len){ | ||||
|             strncpy(num_str,buf,keyword_num); | ||||
|             num = strtol(num_str,NULL,10); | ||||
|             ret = num; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void cmd_tcp(int argc, char **argv) | ||||
| { | ||||
|     int argv_count = 2; | ||||
| 
 | ||||
| 	if(argc < 2) | ||||
| 	    goto Exit; | ||||
| 
 | ||||
| 	g_tcp_terminate = 0; | ||||
| 
 | ||||
| 	while(argv_count<=argc){ | ||||
| 	    //first operation
 | ||||
| 	    if(argv_count == 2){ | ||||
| 	        if(strcmp(argv[argv_count-1], "-s") == 0){ | ||||
|                 if(g_tcp_server_task){ | ||||
|                     printf("\n\rTCP: TCP Server is already running."); | ||||
|                     return; | ||||
|                 }else{ | ||||
|                     memset(&tcp_server_data,0,sizeof(struct iperf_data_t)); | ||||
|                     tcp_server_data.start = 1; | ||||
|                     argv_count++; | ||||
|                 } | ||||
| 	        } | ||||
| 	        else if(strcmp(argv[argv_count-1], "stop") == 0){ | ||||
| 	            if(argc == 2){ | ||||
| 	                vTaskDelay(100); | ||||
| 	                g_tcp_terminate = 1; | ||||
| 	                tcp_server_data.start = 0; | ||||
|                     tcp_client_data.start = 0; | ||||
| 
 | ||||
|                     if(g_tcp_server_task){ | ||||
|                     	if(tcp_server_data.server_fd >=0){ | ||||
|                     		close(tcp_server_data.server_fd); | ||||
|                     	} | ||||
|                     	if(tcp_server_data.client_fd >=0){ | ||||
| 							close(tcp_server_data.client_fd); | ||||
| 						} | ||||
|                     	printf("\n\rTCP server stopped!\n"); | ||||
|                     	vTaskDelete(g_tcp_server_task); | ||||
|                     	g_tcp_server_task = NULL; | ||||
|                     } | ||||
| 
 | ||||
|                     return; | ||||
| 	            } | ||||
| 	            else{ | ||||
| 	                goto Exit; | ||||
| 	            } | ||||
| 	        } | ||||
| 	        else if(strcmp(argv[argv_count-1], "-c") == 0){ | ||||
| 	            if(g_tcp_client_task){ | ||||
|                     printf("\n\rTCP: TCP client is already running. Please enter \"ATWT=stop\" to stop it."); | ||||
|                     return; | ||||
|                 }else{ | ||||
|                     if(argc < (argv_count+1)) | ||||
|                         goto Exit; | ||||
|                     memset(&tcp_client_data,0,sizeof(struct iperf_data_t)); | ||||
|                     tcp_client_data.start = 1; | ||||
|                     strncpy(tcp_client_data.server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2])); | ||||
|                     argv_count+=2; | ||||
|                 } | ||||
| 	        } | ||||
| 	        else{ | ||||
| 	            goto Exit; | ||||
| 	        } | ||||
| 	    } | ||||
| 	    else{ | ||||
| 	        if(strcmp(argv[argv_count-1], "-t") == 0){ | ||||
| 	            if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(tcp_client_data.start){ | ||||
|                     tcp_client_data.time = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
| 	        else if(strcmp(argv[argv_count-1], "-p") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(tcp_server_data.start){ | ||||
|                     tcp_server_data.port = (uint16_t) atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else if(tcp_client_data.start){ | ||||
|                     tcp_client_data.port = (uint16_t) atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
| 	        else if(strcmp(argv[argv_count-1], "-n") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(tcp_client_data.start){ | ||||
|                     tcp_client_data.total_size = km_parser(argv[argv_count],strlen(argv[argv_count])); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
| 	        else if(strcmp(argv[argv_count-1], "-d") == 0){ | ||||
| 				if(tcp_client_data.start){ | ||||
| 					tcp_client_data.bandwidth = DEFAULT_TCP_BANDWIDTH; | ||||
| 				} | ||||
| 				else{ | ||||
| 					goto Exit; | ||||
| 				} | ||||
| 				argv_count+=2; | ||||
| 			} | ||||
| 	        else if(strcmp(argv[argv_count-1], "-l") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(tcp_server_data.start){ | ||||
|                     tcp_server_data.buf_size = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else if(tcp_client_data.start){ | ||||
|                     tcp_client_data.buf_size = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else{ | ||||
|                 goto Exit; | ||||
|             } | ||||
| 	    } | ||||
|     } | ||||
| 
 | ||||
| 	if(tcp_server_data.start && (NULL == g_tcp_server_task)){ | ||||
| 		if(xTaskCreate(tcp_server_handler, "tcp_server_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_tcp_server_task) != pdPASS) | ||||
| 			printf("\n\rTCP ERROR: Create TCP server task failed."); | ||||
| 	} | ||||
| 	if(tcp_client_data.start && (NULL == g_tcp_client_task)){ | ||||
| 		if(xTaskCreate(tcp_client_handler, "tcp_client_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_tcp_client_task) != pdPASS) | ||||
| 			printf("\n\rTCP ERROR: Create TCP client task failed."); | ||||
| 	} | ||||
| 
 | ||||
| 	return; | ||||
| Exit: | ||||
| 	printf("\n\r[ATWT] Command format ERROR!\n"); | ||||
| 	printf("\n\r[ATWT] Usage: ATWT=[-s|-c,host|stop],[options]\n"); | ||||
|     printf("\n\r   Client/Server:\n"); | ||||
|     printf("  \r     stop           terminate client & server\n"); | ||||
|     printf("  \r     -l    #        length of buffer to read or write (default 1460 Bytes)\n"); | ||||
|     printf("  \r     -p    #        server port to listen on/connect to (default 5001)\n"); | ||||
|     printf("\n\r   Server specific:\n"); | ||||
|     printf("  \r     -s             run in server mode\n"); | ||||
|     printf("\n\r   Client specific:\n"); | ||||
|     printf("  \r     -c    <host>   run in client mode, connecting to <host>\n"); | ||||
|     printf("  \r     -d             Do a bidirectional test simultaneously\n"); | ||||
|     printf("  \r     -t    #        time in seconds to transmit for (default 10 secs)\n"); | ||||
|     printf("  \r     -n    #[KM]    number of bytes to transmit (instead of -t)\n"); | ||||
|     printf("\n\r   Example:\n"); | ||||
|     printf("  \r     ATWT=-s,-p,5002\n"); | ||||
|     printf("  \r     ATWT=-c,192.168.1.2,-t,100,-p,5002\n"); | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void cmd_udp(int argc, char **argv) | ||||
| { | ||||
|     int argv_count = 2; | ||||
|     uint8_t tos_value = 0; | ||||
| 
 | ||||
| 	if(argc < 2) | ||||
| 	    goto Exit; | ||||
| 
 | ||||
| 	g_udp_terminate = 0; | ||||
| 
 | ||||
| 	while(argv_count<=argc){ | ||||
|         //first operation
 | ||||
|         if(argv_count == 2){ | ||||
|             if(strcmp(argv[argv_count-1], "-s") == 0){ | ||||
|                 if(g_udp_server_task){ | ||||
|                     printf("\n\rUDP: UDP Server is already running."); | ||||
|                     return; | ||||
|                 }else{ | ||||
|                     memset(&udp_server_data,0,sizeof(struct iperf_data_t)); | ||||
|                     udp_server_data.start = 1; | ||||
|                     argv_count++; | ||||
|                 } | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "stop") == 0){ | ||||
|                 if(argc == 2){ | ||||
|                     vTaskDelay(100); | ||||
|                     g_udp_terminate = 1; | ||||
|                     udp_server_data.start = 0; | ||||
|                     udp_client_data.start = 0; | ||||
| 
 | ||||
|                     if(g_udp_server_task){ | ||||
| 						if(udp_server_data.server_fd >=0){ | ||||
| 							close(udp_server_data.server_fd); | ||||
| 						} | ||||
| 						printf("\n\rUDP server stopped!\n"); | ||||
| 						vTaskDelete(g_udp_server_task); | ||||
| 						g_udp_server_task = NULL; | ||||
| 					} | ||||
| 
 | ||||
|                     return; | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "-c") == 0){ | ||||
|                 if(g_udp_client_task){ | ||||
|                     printf("\n\rUDP: UDP client is already running. Please enter \"ATWU=stop\" to stop it."); | ||||
|                     return; | ||||
|                 }else{ | ||||
|                     if(argc < (argv_count+1)) | ||||
|                         goto Exit; | ||||
|                     memset(&udp_client_data,0,sizeof(struct iperf_data_t)); | ||||
|                     udp_client_data.start = 1; | ||||
|                     strncpy(udp_client_data.server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2])); | ||||
|                     argv_count+=2; | ||||
|                 } | ||||
|             } | ||||
|             else{ | ||||
|                 goto Exit; | ||||
|             } | ||||
|         } | ||||
|         else{ | ||||
|             if(strcmp(argv[argv_count-1], "-t") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(udp_client_data.start){ | ||||
|                     udp_client_data.time = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "-p") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(udp_server_data.start){ | ||||
|                     udp_server_data.port = (uint16_t) atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else if(udp_client_data.start){ | ||||
|                     udp_client_data.port = (uint16_t) atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "-n") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(udp_client_data.start){ | ||||
|                     udp_client_data.total_size = km_parser(argv[argv_count],strlen(argv[argv_count])); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "-b") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(udp_client_data.start){ | ||||
|                     udp_client_data.bandwidth = km_parser(argv[argv_count],strlen(argv[argv_count])); | ||||
|                     udp_client_data.bandwidth = udp_client_data.bandwidth/8;//bits to Bytes
 | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else if(strcmp(argv[argv_count-1], "-d") == 0){ | ||||
| 				if(udp_client_data.start){ | ||||
| 					udp_client_data.bandwidth = DEFAULT_UDP_BANDWIDTH; | ||||
| 				} | ||||
| 				else{ | ||||
| 					goto Exit; | ||||
| 				} | ||||
| 				argv_count+=1; | ||||
| 			} | ||||
| #if CONFIG_WLAN | ||||
|             else if(strcmp(argv[argv_count-1], "-S") == 0){ //for wmm test
 | ||||
| 				if(argc < (argv_count+1)) | ||||
| 					goto Exit; | ||||
| 				if(udp_client_data.start){ | ||||
| 					if(atoi(argv[argv_count]) >= 0 && atoi(argv[argv_count]) <= 255){ | ||||
| 						tos_value = (uint8_t) atoi(argv[argv_count]); | ||||
| 						wext_set_tos_value(WLAN0_NAME, &tos_value); | ||||
| 						udp_client_data.tos_value = tos_value; | ||||
| 					} | ||||
| 					else{ | ||||
| 						goto Exit; | ||||
| 					} | ||||
| 				} | ||||
| 				else{ | ||||
| 					goto Exit; | ||||
| 				} | ||||
| 				argv_count+=2; | ||||
| 			} | ||||
| #endif			 | ||||
|             else if(strcmp(argv[argv_count-1], "-l") == 0){ | ||||
|                 if(argc < (argv_count+1)) | ||||
|                     goto Exit; | ||||
|                 if(udp_server_data.start){ | ||||
|                     udp_server_data.buf_size = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else if(udp_client_data.start){ | ||||
|                     udp_client_data.buf_size = atoi(argv[argv_count]); | ||||
|                 } | ||||
|                 else{ | ||||
|                     goto Exit; | ||||
|                 } | ||||
|                 argv_count+=2; | ||||
|             } | ||||
|             else{ | ||||
|                 goto Exit; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	if(udp_server_data.start && (NULL == g_udp_server_task)){ | ||||
| 		if(xTaskCreate(udp_server_handler, "udp_server_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_udp_server_task) != pdPASS) | ||||
| 			printf("\r\nUDP ERROR: Create UDP server task failed."); | ||||
| 	} | ||||
| 	 | ||||
| 	if(udp_client_data.start && (NULL == g_udp_client_task)){ | ||||
| 		if(xTaskCreate(udp_client_handler, "udp_client_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_udp_client_task) != pdPASS) | ||||
| 			printf("\r\nUDP ERROR: Create UDP client task failed."); | ||||
| 	} | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| Exit: | ||||
|     printf("\n\r[ATWU] Command format ERROR!\n"); | ||||
| 	printf("\n\r[ATWU] Usage: ATWU=[-s|-c,host|stop][options]\n"); | ||||
| 	printf("\n\r   Client/Server:\n"); | ||||
| 	printf("  \r     stop           terminate client & server\n"); | ||||
| 	printf("  \r     -l    #        length of buffer to read or write (default 1460 Bytes)\n"); | ||||
| 	printf("  \r     -p    #        server port to listen on/connect to (default 5001)\n"); | ||||
| 	printf("\n\r   Server specific:\n"); | ||||
| 	printf("  \r     -s             run in server mode\n"); | ||||
| 	printf("\n\r   Client specific:\n"); | ||||
| 	printf("  \r     -b    #[KM]    for UDP, bandwidth to send at in bits/sec (default 1 Mbit/sec)\n"); | ||||
| 	printf("  \r     -c    <host>   run in client mode, connecting to <host>\n"); | ||||
| 	printf("  \r     -d             Do a bidirectional test simultaneously\n"); | ||||
| 	printf("  \r     -t    #        time in seconds to transmit for (default 10 secs)\n"); | ||||
| 	printf("  \r     -n    #[KM]    number of bytes to transmit (instead of -t)\n"); | ||||
| #if CONFIG_WLAN | ||||
| 	printf("  \r     -S    #        set the IP 'type of service'\n"); | ||||
| #endif | ||||
| 	printf("\n\r   Example:\n"); | ||||
| 	printf("  \r     ATWU=-s,-p,5002\n"); | ||||
| 	printf("  \r     ATWU=-c,192.168.1.2,-t,100,-p,5002\n"); | ||||
| 	return; | ||||
| } | ||||
							
								
								
									
										368
									
								
								component/common/utilities/uart_socket.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								component/common/utilities/uart_socket.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,368 @@ | |||
| #include "lwip/api.h" | ||||
| #include "PinNames.h" | ||||
| #include "sockets.h" | ||||
| #include "uart_socket.h" | ||||
| #include "autoconf.h" | ||||
| #define UART_SOCKET_USE_DMA_TX 1 | ||||
| /***********************************************************************
 | ||||
|  *                                Macros                               * | ||||
|  ***********************************************************************/ | ||||
| #define uart_printf printf | ||||
| #define uart_print_data(x, d, l) \ | ||||
| do{\ | ||||
| 	int i;\ | ||||
| 	uart_printf("\n%s: Len=%d\n", (x), (l));\ | ||||
| 	for(i = 0; i < (l); i++)\ | ||||
| 		uart_printf("%02x ", (d)[i]);\ | ||||
| 	uart_printf("\n");\ | ||||
| }while(0); | ||||
| 
 | ||||
| /************************************************************************
 | ||||
|  *                        extern funtions                               * | ||||
|  ************************************************************************/ | ||||
| extern void lwip_selectevindicate(int fd); | ||||
| extern void lwip_setsockrcvevent(int fd, int rcvevent); | ||||
| extern int lwip_allocsocketsd(); | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| *                               uart releated  fuantions                          * | ||||
| *************************************************************************/ | ||||
| static void uart_irq(uint32_t id, SerialIrq event) | ||||
| { | ||||
| 	uart_socket_t *u = (uart_socket_t *)id; | ||||
| 
 | ||||
| 	if(event == RxIrq) { | ||||
| 		if( u->rx_start == 0 ){ | ||||
| 			RtlUpSemaFromISR(&u->action_sema);	//up action semaphore 
 | ||||
| 			u->rx_start = 1; // set this flag in uart_irq to indicate data recved
 | ||||
| 		} | ||||
| 		u->recv_buf[u->prxwrite++] = serial_getc(&u->sobj); | ||||
| 		if(u->prxwrite > (UART_RECV_BUFFER_LEN -1)){	//restart from  head if  reach tail
 | ||||
| 			u->prxwrite = 0; | ||||
| 			u->rxoverlap = 1;							//set overlap indicated that overlaped 
 | ||||
| 		} | ||||
| 		if(u->rxoverlap && (u->prxwrite + 1) > u->prxread ){ | ||||
| 			u->prxread = u->prxwrite;		//if pwrite overhead pread ,pread is always flow rwrite 
 | ||||
| 		} | ||||
| 		u->last_update =  xTaskGetTickCountFromISR();	// update tick everytime recved data
 | ||||
| 	} | ||||
| 
 | ||||
| 	if(event == TxIrq){ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void uart_send_stream_done(uint32_t id) | ||||
| { | ||||
| 	uart_socket_t *u = (uart_socket_t *)id; | ||||
| 	 | ||||
| 	//u->tx_start = 0;
 | ||||
| 	memset(u->send_buf,0, UART_SEND_BUFFER_LEN);	//zero set uart_send_buf
 | ||||
| 	RtlUpSemaFromISR(&u->tx_sema); | ||||
| 	RtlUpSemaFromISR(&u->dma_tx_sema); | ||||
| } | ||||
| 
 | ||||
| static int uart_send_stream(uart_socket_t *u, char* pbuf, int len) | ||||
| { | ||||
| 	int ret; | ||||
| 	 | ||||
| 	if(!len || (!pbuf) || !u){ | ||||
| 		uart_printf("input error,size should not be null\r\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| #if UART_SOCKET_USE_DMA_TX | ||||
| 	while(RtlDownSema(&u->dma_tx_sema) == pdTRUE){			 | ||||
| 	    	ret = serial_send_stream_dma(&u->sobj, pbuf, len); | ||||
| 	    	if(ret != HAL_OK){ | ||||
| 			RtlUpSema(&u->dma_tx_sema); | ||||
| 			return -1; | ||||
| 		}else{ | ||||
| 			return 0; | ||||
| 	    	} | ||||
| 	} | ||||
| #else | ||||
| 	while (len){ | ||||
| 		serial_putc(&u->sobj, *pbuf); | ||||
|        	len--; | ||||
| 		pbuf++; | ||||
| 	} | ||||
| #endif	 | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static s32 uart_wait_rx_complete(uart_socket_t *u) | ||||
| { | ||||
| 	s32 tick_current = xTaskGetTickCount(); | ||||
| 
 | ||||
| 	while((tick_current -u->last_update) < UART_MAX_DELAY_TIME ){ | ||||
| 		vTaskDelay(5); | ||||
| 		tick_current = xTaskGetTickCount(); | ||||
| 	}	 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void uart_action_handler(void* param) | ||||
| { | ||||
| 	uart_socket_t *u = (uart_socket_t*)param; | ||||
| 	if(!u) | ||||
| 		goto Exit; | ||||
| 	 | ||||
| 	while(RtlDownSema(&u->action_sema) == pdTRUE) { | ||||
| 		if(u->fd == -1) | ||||
| 			goto Exit; | ||||
| 		if(u->rx_start){ | ||||
| 			/* Blocked here to wait uart rx data completed */ | ||||
| 			uart_wait_rx_complete(u); | ||||
| 
 | ||||
| 			/* As we did not register netconn callback function.,so call lwip_selectevindicate unblocking select */ | ||||
| 			lwip_setsockrcvevent(u->fd, 1); | ||||
| 			lwip_selectevindicate(u->fd);	//unblocking select()
 | ||||
| 			u->rx_start = 0; | ||||
| 		} | ||||
| 		if(u->tx_start){ | ||||
| #if 1			 | ||||
| 			if (u->tx_bytes < 128) { | ||||
| 				uart_print_data("TX:", u->send_buf, u->tx_bytes); | ||||
| 			} else { | ||||
| 				uart_printf("\nTX:: Len=%d\n", u->tx_bytes); | ||||
| 			} | ||||
| #endif | ||||
| 			//if(serial_send_stream_dma(&u->sobj, (char*)u->send_buf, u->tx_bytes) == -1){
 | ||||
| 			if(uart_send_stream(u, (char*)u->send_buf, u->tx_bytes) == -1){ | ||||
| 				uart_printf("uart send data error!"); | ||||
| 			} else { | ||||
| 				u->tx_start = 0; | ||||
| #if (UART_SOCKET_USE_DMA_TX == 0) | ||||
| 				memset(u->send_buf,0, UART_SEND_BUFFER_LEN);	//zero set uart_send_buf
 | ||||
| 				RtlUpSema(&u->tx_sema); | ||||
| #endif				 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| Exit:	 | ||||
| 	vTaskDelete(NULL); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| uart_socket_t* uart_open(uart_set_str *puartpara) | ||||
| { | ||||
| 	PinName uart_tx = PA_7;//PA_4; //PA_7
 | ||||
| 	PinName uart_rx = PA_6;//PA_0; //PA_6
 | ||||
| 	uart_socket_t *u; | ||||
| 
 | ||||
| 	u = (uart_socket_t *)RtlZmalloc(sizeof(uart_socket_t)); | ||||
| 	if(!u){ | ||||
| 		uart_printf("%s(): Alloc memory for uart_socket failed!\n", __func__); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	 | ||||
| 	/*initial uart */ | ||||
| 	serial_init(&u->sobj, uart_tx,uart_rx); | ||||
| 	serial_baud(&u->sobj,puartpara->BaudRate); | ||||
| 	serial_format(&u->sobj, puartpara->number, (SerialParity)puartpara->parity, puartpara->StopBits); | ||||
| 
 | ||||
| 	/*uart irq handle*/ | ||||
| 	serial_irq_handler(&u->sobj, uart_irq, (int)u); | ||||
| 	serial_irq_set(&u->sobj, RxIrq, 1); | ||||
| 	serial_irq_set(&u->sobj, TxIrq, 1); | ||||
| 
 | ||||
| #if UART_SOCKET_USE_DMA_TX | ||||
|    	serial_send_comp_handler(&u->sobj, (void*)uart_send_stream_done, (uint32_t)u); | ||||
| #endif | ||||
| 
 | ||||
| 	/*alloc a socket*/ | ||||
|  	u->fd = lwip_allocsocketsd(); | ||||
| 	if(u->fd == -1){ | ||||
| 		uart_printf("Failed to alloc uart socket!\n"); | ||||
| 		goto Exit2; | ||||
| 	} | ||||
| 	/*init uart related semaphore*/ | ||||
| 	RtlInitSema(&u->action_sema, 0); | ||||
| 	RtlInitSema(&u->tx_sema, 1); | ||||
| 	RtlInitSema(&u->dma_tx_sema, 1); | ||||
| 	 | ||||
| 	/*create uart_thread to handle send&recv data*/ | ||||
| 	{ | ||||
| #define	UART_ACTION_STACKSIZE 256 //USE_MIN_STACK_SIZE modify from 512 to 256
 | ||||
| #define	UART_ACTION_PRIORITY	1 | ||||
| 		if(xTaskCreate(uart_action_handler, ((const char*)"uart_action"), UART_ACTION_STACKSIZE, u, UART_ACTION_PRIORITY, NULL) != pdPASS){ | ||||
| 			uart_printf("%s xTaskCreate(uart_action) failed", __FUNCTION__); | ||||
| 			goto Exit1; | ||||
| 		} | ||||
| 	} | ||||
| 	return u; | ||||
| Exit1: | ||||
| 	/* Free uart related semaphore */ | ||||
| 	RtlFreeSema(&u->action_sema); | ||||
| 	RtlFreeSema(&u->tx_sema);	 | ||||
| 	RtlFreeSema(&u->dma_tx_sema);		 | ||||
| Exit2: | ||||
| 	RtlMfree((u8*)u, sizeof(uart_socket_t)); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| int uart_close(uart_socket_t *u) | ||||
| { | ||||
| 	if(!u){ | ||||
| 		uart_printf("uart_close(): u is NULL!\r\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	/* Close uart socket */ | ||||
| 	if(lwip_close(u->fd) == -1){ | ||||
| 		uart_printf("%s(): close uart failed!", __func__); | ||||
| 	} | ||||
| 	/* Delete uart_action task */ | ||||
| 	u->fd = -1; | ||||
| 	RtlUpSema(&u->action_sema); | ||||
| 	RtlMsleepOS(20); | ||||
| 
 | ||||
| 	/* Free uart related semaphore */ | ||||
| 	RtlFreeSema(&u->action_sema); | ||||
| 	RtlFreeSema(&u->tx_sema); | ||||
| 	RtlFreeSema(&u->dma_tx_sema); | ||||
| 	 | ||||
| 	/* Free serial */ | ||||
| 	serial_free(&u->sobj); | ||||
| 	 | ||||
| 	RtlMfree((u8 *)u, sizeof(uart_socket_t)); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int uart_read(uart_socket_t *u, void *read_buf, size_t size) | ||||
| { | ||||
| 	/*the same as socket*/ | ||||
| 	int read_bytes = 0; | ||||
| 	int pread_local,pwrite_local; | ||||
| 	char *ptr = (char *)read_buf; | ||||
| 
 | ||||
| 	uart_printf("==>uart_read()\n"); | ||||
| 	if(!size || !read_buf || !u){ | ||||
| 		uart_printf("uart_read(): input error,size should not be null\r\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	 | ||||
| 	pread_local = u->prxread; | ||||
| 	pwrite_local = u->prxwrite; | ||||
| 	/*calculate how much data not read */ | ||||
| 	if(!u->rxoverlap){ | ||||
| 		read_bytes = pwrite_local - pread_local; | ||||
| 	} else { | ||||
| 		read_bytes = (UART_RECV_BUFFER_LEN - pread_local) + pwrite_local; | ||||
| 	} | ||||
| 	/*decide how much data shoule copy to application*/ | ||||
| 	if(size < read_bytes) | ||||
| 		read_bytes = size; | ||||
| 	 | ||||
| 	if(!u->rxoverlap){ | ||||
| 		memcpy(ptr, (u->recv_buf+ pread_local), read_bytes ); | ||||
| 	} else { | ||||
| 		uart_printf("uart recv buf is write through!!\n"); | ||||
| 		if((pread_local + read_bytes) > UART_RECV_BUFFER_LEN){ | ||||
| 			memcpy(ptr,(u->recv_buf+ pread_local), (UART_RECV_BUFFER_LEN-pread_local)); | ||||
| 			memcpy(ptr+(UART_RECV_BUFFER_LEN-pread_local), u->recv_buf, read_bytes-(UART_RECV_BUFFER_LEN- pread_local)); | ||||
| 		} else | ||||
| 			memcpy(ptr,(u->recv_buf+ pread_local), read_bytes); | ||||
| 	} | ||||
| 	lwip_setsockrcvevent(u->fd, 0); | ||||
| 	 | ||||
| 	if((pread_local + read_bytes) >= UART_RECV_BUFFER_LEN){		//update pread
 | ||||
| 		u->prxread = (pread_local + read_bytes) - UART_RECV_BUFFER_LEN; | ||||
| 		u->rxoverlap = 0;		//clean overlap flags
 | ||||
| 	} else | ||||
| 		u->prxread = pread_local + read_bytes; | ||||
| 	 | ||||
| 	return read_bytes; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int uart_write(uart_socket_t *u, void *pbuf, size_t size) | ||||
| { | ||||
| 	if(!size || !pbuf || !u){ | ||||
| 		uart_printf("input error,please check!"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if(RtlDownSema(&u->tx_sema)){ | ||||
| 		//uart_printf("[%d]:uart_write %d!\n", xTaskGetTickCount(), size);
 | ||||
| 		memcpy(u->send_buf, pbuf, size); | ||||
| 		u->tx_bytes = size; | ||||
| 		u->tx_start = 1;	//set uart tx start 
 | ||||
| 		RtlUpSema(&u->action_sema);	// let uart_handle_run through
 | ||||
| 	} else { | ||||
| 		uart_printf("uart write buf error!"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return size; | ||||
| } | ||||
| 
 | ||||
| void uart_socket_example(void *param) | ||||
| { | ||||
| 	char tx_data[] = {0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; | ||||
| 	uart_set_str uartset; | ||||
| 	struct timeval tv; | ||||
| 	fd_set readfds; | ||||
| 	int read_len = 0, count = 0; | ||||
| 	int ret = 0; | ||||
| 	char rxbuf[512]; | ||||
| 	int uart_fd; | ||||
| 	uart_socket_t *uart_socket = NULL; | ||||
| 
 | ||||
| 	uartset.BaudRate = 9600; | ||||
| 	uartset.number = 8; | ||||
| 	uartset.StopBits = 0; | ||||
| 	uartset.FlowControl = 0; | ||||
| 	uartset.parity = 0; | ||||
| 	strcpy(uartset.UartName, "uart0"); | ||||
| 
 | ||||
| 	uart_socket = uart_open(&uartset); | ||||
| 	if(uart_socket == NULL){ | ||||
| 		uart_printf("Init uart socket failed!\n"); | ||||
| 		goto Exit; | ||||
| 	} | ||||
| 	uart_fd = uart_socket->fd; | ||||
| 	uart_printf("\nOpen uart socket: %d\n", uart_fd); | ||||
| 	while(1) | ||||
| 	{ | ||||
| 		FD_ZERO(&readfds); | ||||
| 		FD_SET(uart_fd, &readfds); | ||||
| 		tv.tv_sec = 0; | ||||
| 		tv.tv_usec = 20000; | ||||
| 		if(count++ == 50){ | ||||
| 			uart_write(uart_socket, tx_data, sizeof(tx_data)); | ||||
| 			//uart_print_data("TX:", tx_data, sizeof(tx_data));
 | ||||
| 			count = 0; | ||||
| 		} | ||||
| 		ret = select(uart_fd + 1, &readfds, NULL, NULL, &tv); | ||||
| 		//uart_printf("[%d] select ret = %x count=%d\n", xTaskGetTickCount(), ret, count);	
 | ||||
| 		if(ret > 0) | ||||
| 		{ | ||||
| 			if(FD_ISSET(uart_fd, &readfds)) | ||||
| 			{ | ||||
| 				read_len = uart_read(uart_socket, rxbuf, sizeof(rxbuf)); | ||||
| 				if(read_len > 0) | ||||
| 				{ | ||||
| 					uart_print_data("RX:", rxbuf, read_len); | ||||
| 					if(rtl_strncmp(rxbuf, "close", 5) == 0) | ||||
| 						break; | ||||
| 				} | ||||
| 			} | ||||
| 			//else for other sockets
 | ||||
| 		} | ||||
| 	} | ||||
| 	uart_printf("Exit uart socket example!\n"); | ||||
| 	uart_close(uart_socket); | ||||
| Exit: | ||||
| 	vTaskDelete(NULL); | ||||
| } | ||||
| 
 | ||||
| void uart_socket() | ||||
| { | ||||
| #define 	UART_SOCKET_STACK_SIZE		512 | ||||
| #define 	UART_SOCKET_PRIORITY		1 | ||||
| 	if(xTaskCreate(uart_socket_example, "uart_socket", UART_SOCKET_STACK_SIZE, NULL, UART_SOCKET_PRIORITY, NULL) != pdPASS) | ||||
| 		uart_printf("%s xTaskCreate failed", __FUNCTION__); | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										50
									
								
								component/common/utilities/uart_socket.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								component/common/utilities/uart_socket.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| #ifndef __UART_SOCKET_H_ | ||||
| #define __UART_SOCKET_H_ | ||||
| 
 | ||||
| #include "osdep_api.h" | ||||
| #include "serial_api.h" | ||||
| #include "serial_ex_api.h" | ||||
| 
 | ||||
| #define UART_SEND_BUFFER_LEN	512 | ||||
| #define UART_RECV_BUFFER_LEN	1024 | ||||
| #define UART_MAX_DELAY_TIME   20 | ||||
| 
 | ||||
| typedef struct _uart_set_str  | ||||
| {  | ||||
|     char UartName[8];    // the name of uart 
 | ||||
|     int BaudRate;    //The baud rate 
 | ||||
|     char number;     //The number of data bits 
 | ||||
|     char parity;     //The parity(default NONE) 
 | ||||
|     char StopBits;      //The number of stop bits 
 | ||||
|     char FlowControl;    //support flow control is 1 
 | ||||
| }uart_set_str; | ||||
| 
 | ||||
| typedef struct _uart_socket_t | ||||
| { | ||||
| 	serial_t sobj; | ||||
| 	int fd; | ||||
| 
 | ||||
| 	/* Used for UART RX */ | ||||
| 	u32 rx_start; | ||||
| 	//u32 rx_bytes;
 | ||||
| 	u32 prxread; | ||||
| 	u32 prxwrite; | ||||
| 	u32 rxoverlap; | ||||
| 	u32 last_update;  //tick count when rx byte
 | ||||
| 	u8 recv_buf[UART_RECV_BUFFER_LEN]; | ||||
| 
 | ||||
| 	u32 tx_start; | ||||
| 	u32 tx_bytes; | ||||
| 	u8 send_buf[UART_SEND_BUFFER_LEN]; | ||||
| 	_Sema tx_sema; | ||||
| 	_Sema dma_tx_sema;	 | ||||
| 
 | ||||
| 	_Sema action_sema; | ||||
| }uart_socket_t; | ||||
| 
 | ||||
| uart_socket_t* uart_open(uart_set_str *puartpara); | ||||
| int uart_close(uart_socket_t *u); | ||||
| int uart_read(uart_socket_t *u, void *read_buf, size_t size); | ||||
| int uart_write(uart_socket_t *u, void *pbuf, size_t size); | ||||
| 
 | ||||
| #endif //__UART_SOCKET_H_
 | ||||
							
								
								
									
										654
									
								
								component/common/utilities/uart_ymodem.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										654
									
								
								component/common/utilities/uart_ymodem.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,654 @@ | |||
| /****************************************uart _ymodem.c**************************************************/ | ||||
| 
 | ||||
| #include "uart_ymodem.h" | ||||
| #include "osdep_service.h" | ||||
| #include "PinNames.h" | ||||
| 
 | ||||
| /*****************************************************************************************
 | ||||
| *                                uart basic functions                                    * | ||||
| ******************************************************************************************/ | ||||
|  void uarty_irq(uint32_t id, SerialIrq event) | ||||
| { | ||||
| 	uart_ymodem_t *ptr = (uart_ymodem_t *)id; | ||||
| 	//u8 ch = 0;
 | ||||
| 	if(event == RxIrq) { | ||||
| 		if(ptr->uart_recv_index == 0){ | ||||
| 			RtlUpSemaFromISR(&ptr->uart_rx_sema);//up uart rx semaphore
 | ||||
| 		} | ||||
| 		if(ptr->uart_recv_index == RCV_BUF_SIZE) | ||||
| 			ptr->uart_recv_index = 0; | ||||
| 		//ch = serial_getc(&ptr->sobj);
 | ||||
| 	//	printf("[%d] 0x%x\r\n", ptr->uart_recv_index, ch);
 | ||||
| 		ptr->uart_irq_buf[ptr->uart_recv_index++] = serial_getc(&ptr->sobj); | ||||
| 		ptr->tick_last_update =  xTaskGetTickCountFromISR();	// update tick everytime recved data 
 | ||||
| 	} | ||||
| 	 | ||||
| 	if(event == TxIrq){ | ||||
| //		uart_send_string(sobj, "\r\n8195a$");
 | ||||
| //		rcv_ch = 0;
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void uart_init(uart_ymodem_t *ptr) | ||||
| { | ||||
| //	serial_t sobj;
 | ||||
| 
 | ||||
| 	//uart init
 | ||||
| 	serial_init(&ptr->sobj,UART_TX,UART_RX); | ||||
| 	serial_baud(&ptr->sobj,UART_BAUDRATE);		//set baudrate 38400
 | ||||
| 	serial_format(&ptr->sobj, 8, ParityNone, 0); | ||||
| 
 | ||||
| 	serial_irq_handler(&ptr->sobj, uarty_irq, (int)ptr); | ||||
| 	serial_irq_set(&ptr->sobj, RxIrq, 1); | ||||
| 	serial_irq_set(&ptr->sobj, TxIrq, 1); | ||||
| 	 | ||||
| 	RtlInitSema(&ptr->uart_rx_sema, 0); | ||||
| } | ||||
| void uart_sendbyte(uart_ymodem_t *ptr,u8 sendc ) | ||||
| { | ||||
| 
 | ||||
| 	serial_putc(&ptr->sobj, sendc); | ||||
| //	printf(" uart send 0x%x\r\n",sendc);
 | ||||
| } | ||||
| 
 | ||||
| int uart_recvbytetimeout(uart_ymodem_t *uart_ymodem,u8 *ptr) | ||||
| { | ||||
| 	int ret = 0; | ||||
| //	static int uart_recv_buf_index = 0;
 | ||||
| 
 | ||||
| //	printf(" [%d] = %x\r\n",uart_ymodem->uart_recv_buf_index,uart_ymodem->uart_irq_buf[uart_ymodem->uart_recv_buf_index]);
 | ||||
| 	*ptr = uart_ymodem->uart_irq_buf[uart_ymodem->uart_recv_buf_index]; | ||||
| 	uart_ymodem->uart_recv_buf_index++; | ||||
| 	if(uart_ymodem->uart_recv_buf_index == RCV_BUF_SIZE) | ||||
| 		uart_ymodem->uart_recv_buf_index = 0; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void uart_rxempty(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	/*clean uart recv buf*/ | ||||
| //	printf("Uart_RxEmpty\r\n");
 | ||||
| 	memset(ptr->uart_irq_buf, 0, RCV_BUF_SIZE); | ||||
| 	memset(ptr->uart_rcv_buf, 0, RCV_BUF_SIZE); | ||||
| 	ptr->uart_recv_buf_index = 0; | ||||
| 	ptr->uart_recv_index = 0; | ||||
| } | ||||
| /*****************************************************************************************
 | ||||
| *                                       flash function                                                   * | ||||
| ******************************************************************************************/ | ||||
| int ymodem_flashwrite(int flashadd, u8 *pbuf, int len) | ||||
| { | ||||
| 	 | ||||
| 	int ret = 0; | ||||
| 	flash_t flash; | ||||
| 	 | ||||
| //	if(!FLASH_ADDRESS_CHECK_WRITE_ERASE(flashadd)){
 | ||||
| //		ret = -1;
 | ||||
| //		return ret;
 | ||||
| //		}
 | ||||
| 	if( len == 0){ | ||||
| 		printf("input error,data length should not be null!\r\n"); | ||||
| 		ret = -1; | ||||
| 		return ret; | ||||
| 		} | ||||
| 	else	//as 8711am only canbe r/w in words.so make len is 4-bytes aligmented.
 | ||||
| 		len += 4 - ((len%4)==0 ? 4 : (len%4)); | ||||
| 	 | ||||
| 	while(len){ | ||||
| 		if(flash_write_word(&flash, flashadd, *(unsigned int *)pbuf) !=1 ){ | ||||
| 			printf("write flash error!\r\n"); | ||||
| 			ret = -1; | ||||
| 			return ret; | ||||
| 		} | ||||
| 		len -= 4; | ||||
| 		pbuf += 4; | ||||
| 		flashadd += 4; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| /****************************uart_ymodem_init**********************************/ | ||||
| void uart_ymodem_init(uart_ymodem_t *uart_ymodem_ptr) | ||||
| { | ||||
| //	u32 ret = 0;
 | ||||
| #if CONFIG_CALC_FILE_SIZE | ||||
| 	u8 filename[33] = {0}; //file name: max 32 bytes+ '\0'=33
 | ||||
| #endif | ||||
| 	//init uart struct 
 | ||||
| 	uart_ymodem_ptr->cur_num = 0; | ||||
| 	uart_ymodem_ptr->filelen = 0 ; | ||||
| #if CONFIG_CALC_FILE_SIZE | ||||
| 	uart_ymodem_ptr->filename = &filename[0]; | ||||
| #endif | ||||
| 	uart_ymodem_ptr->len = 0; | ||||
| 	uart_ymodem_ptr->nxt_num = 0; | ||||
| 	uart_ymodem_ptr->modemtype = 2;	 //ymodem protocol 
 | ||||
| 	uart_ymodem_ptr->rec_err = 0; | ||||
| 	uart_ymodem_ptr->crc_mode = 1;	//crc check
 | ||||
| 	uart_ymodem_ptr->uart_recv_buf_index = 0; | ||||
| 	uart_ymodem_ptr->uart_recv_index = 0; | ||||
| 	uart_ymodem_ptr->image_address = IMAGE_TWO; | ||||
| 
 | ||||
| //	return uart_ymodem_ptr;
 | ||||
| } | ||||
| 
 | ||||
| void uart_ymodem_deinit(uart_ymodem_t *ptr) | ||||
| { | ||||
| 
 | ||||
| 	/* Free uart_rx-sema */ | ||||
| 	RtlFreeSema(&ptr->uart_rx_sema); | ||||
| 	 | ||||
| 	/* Free serial */ | ||||
| 	serial_free(&ptr->sobj); | ||||
| 
 | ||||
| 	/* Free uart_ymodem_t */ | ||||
| 	RtlMfree((u8 *)ptr,sizeof(uart_ymodem_t)); | ||||
| } | ||||
| 
 | ||||
| #if CONFIG_CALC_FILE_SIZE | ||||
| unsigned int buf_filelen(u8 *ptr) | ||||
| { | ||||
| 	int datatype=10, result=0; | ||||
| 
 | ||||
| 	if (ptr[0]=='0' && (ptr[1]=='x' && ptr[1]=='X')) | ||||
| 	{ | ||||
| 		datatype = 16; | ||||
| 		ptr += 2; | ||||
| 	} | ||||
| 
 | ||||
| 	for ( ; *ptr!='\0'; ptr++) | ||||
| 	{ | ||||
| 		if (*ptr>= '0' && *ptr<='9') | ||||
| 		{ | ||||
| 			result =result*datatype+*ptr-'0'; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (datatype == 10) | ||||
| 			{ | ||||
| 				return result; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (*ptr>='A' && *ptr<='F') | ||||
| 				{ | ||||
| 					result = result*16 + *ptr-55;             //55 = 'A'-10
 | ||||
| 				} | ||||
| 				else if (*ptr>='a' && *ptr<='f') | ||||
| 				{ | ||||
| 					result = result*16 + *ptr-87;             //87 = 'a'-10
 | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					return result; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
| #endif | ||||
| void modem_cancle(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	uart_sendbyte(ptr,0x18); | ||||
| 	uart_sendbyte(ptr,0x18); | ||||
| 	uart_sendbyte(ptr,0x18); | ||||
| 	uart_sendbyte(ptr,0x18); | ||||
| 	uart_sendbyte(ptr,0x18); | ||||
| } | ||||
| 
 | ||||
| int start_next_round(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	 | ||||
| //	printf(" uart ymodedm transfer %d block\r\n",ptr->nxt_num);
 | ||||
| 	//clean recv buf
 | ||||
| 	if(!ptr->rec_err){ | ||||
| 		uart_rxempty(ptr); | ||||
| 	}  | ||||
| 	else{ | ||||
| 		ret = -1; | ||||
| 		printf("\r\n recv data error!"); | ||||
| 	} | ||||
| 	 | ||||
| 	if (ptr->nxt_num == 0) | ||||
| 	{ | ||||
| 		if (ptr->crc_mode) | ||||
| 		{ | ||||
| 			uart_sendbyte(ptr,MODEM_C);	//first receiver send c
 | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			uart_sendbyte(ptr,MODEM_NAK); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if (ptr->rec_err) | ||||
| 		{ | ||||
| 			uart_sendbyte(ptr,MODEM_NAK); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (ptr->nxt_num == 1) | ||||
| 			{ | ||||
| 				if (ptr->crc_mode) | ||||
| 				{ | ||||
| 					uart_sendbyte(ptr,MODEM_ACK); | ||||
| 					uart_sendbyte(ptr,MODEM_C); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					uart_sendbyte(ptr,MODEM_NAK); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				uart_sendbyte(ptr,MODEM_ACK); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| int data_write_to_flash(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	int ret = 0; | ||||
| //	uint32_t update_image_address = IMAGE_TWO;
 | ||||
| 	static int offset = 0x0; | ||||
| 	u32 data; | ||||
| 	static int flags = 1;	//write update image header only once
 | ||||
| //  int file_blk_size = 0
 | ||||
| 	 | ||||
| 	flash_read_word(&ptr->flash, OFFSET_DATA, &data); | ||||
| //	file_blk_size = ((ptr->filelen - 1)/4096) + 1;
 | ||||
| 	if(data == ~0x0){ | ||||
| 		flash_write_word(&ptr->flash, OFFSET_DATA, ptr->image_address); | ||||
| 	} | ||||
| //	printf("image_address get from flash =  0x%x\n\r",ptr->image_address);
 | ||||
| 	//erase flash where to be written,since ymodem blk size can be 128 or 1024,so, erase once when gather 4096
 | ||||
| 	if(offset ==0 || (offset % 4096)==0){ | ||||
| 		flash_erase_sector(&ptr->flash, ptr->image_address + offset); | ||||
| 	} | ||||
| 	//write to flash
 | ||||
| 	//write back image size and address
 | ||||
| 	if(!flags){ | ||||
| 		flash_write_word(&ptr->flash, ptr->image_address, ptr->filelen); | ||||
| 		flash_write_word(&ptr->flash, ptr->image_address+4,0x10004000); | ||||
| 		flags = 1; | ||||
| 	} | ||||
| //	ymodem_flashwrite(update_image_address + offset, ptr->uart_rcv_buf, ptr->len);
 | ||||
| 	device_mutex_lock(RT_DEV_LOCK_FLASH); | ||||
| 	flash_stream_write(&ptr->flash, ptr->image_address+offset, ptr->len, ptr->uart_rcv_buf); | ||||
| 	device_mutex_unlock(RT_DEV_LOCK_FLASH); | ||||
| 	offset += ptr->len; | ||||
| 	 | ||||
| 	return ret; | ||||
| } | ||||
| int block_num_check(uart_ymodem_t *ptr) | ||||
| { | ||||
| 
 | ||||
| 	u8 blk,cblk; | ||||
| 	int stat, ret = 0; | ||||
| 	/**************** check blk and blk complement *********************/ | ||||
| 	stat = uart_recvbytetimeout(ptr,&blk);	//blk num,bytes 2
 | ||||
| 	if (stat != 0) | ||||
| 	{ | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 	printf(" blk num = %x\r\n", blk); | ||||
| 
 | ||||
| 	stat = uart_recvbytetimeout(ptr,&cblk);	//block num complement,bytes 3
 | ||||
| 	if (stat != 0) | ||||
| 	{ | ||||
| 		ret = -1; | ||||
| 	} | ||||
| //	printf(" block num cmpl = %x\r\n",cblk);
 | ||||
| 
 | ||||
| 	if (blk+cblk != 0xff) | ||||
| 	{ | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 	return ret; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| int calc_file_name_size(uart_ymodem_t *ptr,u8* bufptr) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	u8* nameptr = ptr->filename; | ||||
| 	 | ||||
| 	while (*bufptr != '\0'){ | ||||
| 		*nameptr++ = *bufptr++; | ||||
| 	} | ||||
| 	*nameptr = '\0'; | ||||
| 	bufptr++; | ||||
| 	while (*bufptr == ' ') | ||||
| 	{ | ||||
| 		bufptr++; | ||||
| 	} | ||||
| 	//file length
 | ||||
| 	ptr->filelen = buf_filelen(bufptr); | ||||
| 	 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int crc_check(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	u8 crch, crcl; | ||||
| 	u8 *in_ptr; | ||||
| 	int stat,i,ret = 0; | ||||
| 	u32 cksum = 0; | ||||
| 
 | ||||
| 	stat = uart_recvbytetimeout(ptr,&crch);			//CRC byte 1
 | ||||
| 	if (stat != 0){ | ||||
| 		ret = 1; | ||||
| 	} | ||||
| //	printf(" char recved CRC byte 1 = %x\r\n", crch);
 | ||||
| 	if (ptr->crc_mode){ | ||||
| 		stat = uart_recvbytetimeout(ptr,&crcl); 	//CRC byte 2
 | ||||
| 		if (stat != 0){ | ||||
| 			ret = 1; | ||||
| 		} | ||||
| 	} | ||||
| //	printf(" char recved CRC byte 2 = %x\r\n", crcl);
 | ||||
| #if CRC_CHECK | ||||
| 	for (i=0; i<ptr->len; i++)			//sum check for last block
 | ||||
| 	{ | ||||
| 		cksum += ptr->uart_rcv_buf[i]; | ||||
| 	} | ||||
| 	if(cksum == 0) | ||||
| 	{  | ||||
| 	 	ret = 2; | ||||
| 		return ret; | ||||
| 	} | ||||
| 	 | ||||
| 	if (ptr->crc_mode) | ||||
| 	{ | ||||
| 		in_ptr = ptr->uart_rcv_buf; | ||||
| 		cksum = 0; | ||||
| 		 | ||||
| 		for (stat=ptr->len ; stat>0; stat--) | ||||
| 		{ | ||||
| 			cksum = cksum^(int)(*in_ptr++) << 8; | ||||
| 			for (i=8; i !=0; i--) | ||||
| 			{ | ||||
| 				if (cksum & 0x8000) | ||||
| 					cksum = cksum << 1 ^ 0x1021; | ||||
| 				else | ||||
| 					cksum = cksum << 1; | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 		cksum &= 0xffff; | ||||
| 		 | ||||
| 		if (cksum != (crch<<8 | crcl)) | ||||
| 		{ | ||||
| 			ptr->rec_err = 1; | ||||
| 			ret = 1; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		for (i=0; i<ptr->len; i++)				//sum check
 | ||||
| 		{ | ||||
| 			cksum += ptr->uart_rcv_buf[i]; | ||||
| 		} | ||||
| 		if ((cksum&0xff)!=crch) | ||||
| 		{ | ||||
| 			ptr->rec_err = 1; | ||||
| 			ret = 1; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	return ret; | ||||
| 
 | ||||
| } | ||||
| #if DUMP_DATA | ||||
| void flash_dump_data(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	int i,offset = 0; | ||||
| 	u32 data; | ||||
| 	printf("flash dump data"); | ||||
| 	for(i = 0;i< ptr->filelen;i+=4){ | ||||
| 		flash_read_word(&ptr->flash, ptr->image_address + 0x10 + offset, &data); | ||||
| 		offset += 4; | ||||
| 		printf("%x ",data); | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| #if AUTO_REBOOT | ||||
| void auto_reboot(void) | ||||
| { | ||||
| 	// Set processor clock to default before system reset
 | ||||
| 	HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); | ||||
| 	osDelay(100); | ||||
| 
 | ||||
| 	// Cortex-M3 SCB->AIRCR
 | ||||
| 	HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) |                             // VECTKEY
 | ||||
| 	                              (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP
 | ||||
| 	                              (1 << 2));                                  // SYSRESETREQ
 | ||||
| 	while(1) osDelay(1000); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int set_signature(uart_ymodem_t *ptr) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	uint32_t sig_readback0,sig_readback1; | ||||
| 	uint32_t oldimg2addr; | ||||
| 
 | ||||
| 	//old image address
 | ||||
| 	flash_read_word(&ptr->flash, 0x18, &oldimg2addr); | ||||
| 	oldimg2addr = (oldimg2addr&0xFFFF)*1024; | ||||
| 	printf(" lod image  address 0x%x\n\r",oldimg2addr); | ||||
| 	//Set signature in New Image 2 addr + 8 and + 12
 | ||||
| //	flash_write_word(&ptr->flash,ptr->image_address + 8, 0x35393138);//0x35393138
 | ||||
| //	flash_write_word(&ptr->flash,ptr->image_address + 12, 0x31313738);
 | ||||
| //	flash_read_word(&ptr->flash, ptr->image_address + 8, &sig_readback0);
 | ||||
| //	flash_read_word(&ptr->flash, ptr->image_address + 12, &sig_readback1);
 | ||||
| //	printf(" new signature %x,%x,\n\r",sig_readback0, sig_readback1);
 | ||||
| #if 1 | ||||
| 	flash_write_word(&ptr->flash,oldimg2addr + 8, 0x35393130); | ||||
| 	flash_write_word(&ptr->flash,oldimg2addr + 12, 0x31313738); | ||||
| 	flash_read_word(&ptr->flash, oldimg2addr + 8, &sig_readback0); | ||||
| 	flash_read_word(&ptr->flash, oldimg2addr + 12, &sig_readback1); | ||||
| 	printf(" old signature %x,%x\n\r",sig_readback0, sig_readback1); | ||||
| #endif | ||||
| 	printf(" set signature success!\n\r"); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void uart_ymodem_thread(void* param) | ||||
| { | ||||
| 	u8 ch; | ||||
| 	u32 stat, error_bit = 0, transfer_over = 0; | ||||
| 	u32 can_counter = 0, eot_counter = 0; | ||||
| 	u32 i, send_count = 0 , ret = 0; | ||||
| 	static int first_time = 1; | ||||
| 	uart_ymodem_t *ymodem_ptr = (uart_ymodem_t *)param; | ||||
| 	printf(" ==>uart ymodem_task\r\n"); | ||||
| 	while(1) | ||||
| 	{ | ||||
| 		//wait 2min,2*60*1000/100
 | ||||
| 		if(send_count >= (2*60*10)){ | ||||
| 			error_bit = 6; | ||||
| 			printf("no response after 2min\r\n"); | ||||
| 			goto exit; | ||||
| 		} | ||||
| 		else{ | ||||
| 			if (ymodem_ptr->crc_mode){ | ||||
| 				uart_sendbyte(ymodem_ptr,MODEM_C);	//first receiver send c
 | ||||
| 			} | ||||
| 			else{ | ||||
| 				uart_sendbyte(ymodem_ptr,MODEM_NAK); | ||||
| 			} | ||||
| 			send_count++;  | ||||
| 		} | ||||
| 		if(xSemaphoreTake(ymodem_ptr->uart_rx_sema, 0) == pdTRUE){ | ||||
| 			RtlUpSema(&ymodem_ptr->uart_rx_sema); | ||||
| 			break; | ||||
| 		} | ||||
| 		else | ||||
| 			// send every 100ms
 | ||||
| 			vTaskDelay(100); | ||||
| 	} | ||||
| start: | ||||
| 	while(xSemaphoreTake(ymodem_ptr->uart_rx_sema, portMAX_DELAY) == pdTRUE){ | ||||
| //		ymodem_ptr->tick_current = ymodem_ptr->tick_last_update = xTaskGetTickCount();
 | ||||
| 		ymodem_ptr->tick_current = xTaskGetTickCount(); | ||||
| 		while((int)(ymodem_ptr->tick_current - ymodem_ptr->tick_last_update) < 50 ){ | ||||
| 			ymodem_ptr->tick_current = xTaskGetTickCount(); | ||||
| 			vTaskDelay(5); | ||||
| 		} | ||||
| 		printf("uart_recv_index = %d current=%d last=%d\r\n",ymodem_ptr->uart_recv_index, ymodem_ptr->tick_current, ymodem_ptr->tick_last_update); | ||||
| 		/*uart data recv done and process what we have recvied*/ | ||||
| 		stat = uart_recvbytetimeout(ymodem_ptr,&ch); | ||||
| 		if (stat == 0) | ||||
| 		{ | ||||
| 			switch (ch) | ||||
| 			{ | ||||
| 				case MODEM_SOH : | ||||
| 					ymodem_ptr->len = 128; | ||||
| //					printf(" char recved was MODEM_SOH!\r\n");
 | ||||
| 					break; | ||||
| 				case MODEM_STX : | ||||
| 					ymodem_ptr->len = 1024; | ||||
| //					printf(" char recved was MODEM_STX!\r\n");
 | ||||
| 					break; | ||||
| 				case MODEM_CAN : | ||||
| 					if ((++can_counter) >= MODEM_CAN_COUNT) | ||||
| 					{ | ||||
| 						error_bit = 1; | ||||
| 						goto exit; | ||||
| 					} | ||||
| //					printf(" char recved was MODEM_CAN!\r\n");
 | ||||
| 					break; | ||||
| 				case MODEM_EOT : | ||||
| //					printf(" char recved was MODEM_EOT!\r\n");
 | ||||
| 					if ((++eot_counter) >= MODEM_EOT_COUNT) | ||||
| 					{ | ||||
| 						uart_sendbyte(ymodem_ptr,MODEM_ACK); | ||||
| 						if (ymodem_ptr->modemtype == 2)	//Ymodem protocol 
 | ||||
| 						{ | ||||
| 							uart_sendbyte(ymodem_ptr,MODEM_C);			//first send a C
 | ||||
| 							uart_sendbyte(ymodem_ptr,MODEM_ACK);			//then send ack
 | ||||
| 							uart_sendbyte(ymodem_ptr,MODEM_C);			// and then send c
 | ||||
| 							modem_cancle(ymodem_ptr);					//cancel the transits
 | ||||
| 						} | ||||
| 						transfer_over = 1; | ||||
| 						goto exit; | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						uart_sendbyte(ymodem_ptr,MODEM_ACK); | ||||
| 						uart_sendbyte(ymodem_ptr,MODEM_C); | ||||
| 						goto start; | ||||
| 					} | ||||
| 					break; | ||||
| 				default: | ||||
| 					error_bit = 1; | ||||
| 					goto exit; | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//block num check
 | ||||
| 		if(block_num_check(ymodem_ptr)){ | ||||
| 			error_bit = 2; | ||||
| 			goto exit; | ||||
| 		} | ||||
| #if CONFIG_CALC_FILE_SIZE	 | ||||
| 		// calculate file name and file size
 | ||||
| 		if(ymodem_ptr->nxt_num == 0 && first_time){ | ||||
| 			error_bit = calc_file_name_size(ymodem_ptr,&ymodem_ptr->uart_irq_buf[3]); | ||||
| //			first_time = 0;
 | ||||
| 		} | ||||
| #endif	 | ||||
| 		//copy data from uart irq buf to uart recv buf without header
 | ||||
| 		for (i=0; i<ymodem_ptr->len; i++) | ||||
| 		{ | ||||
| 			stat = uart_recvbytetimeout(ymodem_ptr,&ymodem_ptr->uart_rcv_buf[i]); | ||||
| //			printf(" data recv[%d] =%x\r\n",i,ymodem_ptr->uart_rcv_buf[i]);		
 | ||||
| 		} | ||||
| 		//write data to flash,but do not write first block data
 | ||||
| 		if(ymodem_ptr->nxt_num != 0 || !first_time){ | ||||
| 			if(data_write_to_flash(ymodem_ptr)){ | ||||
| 				error_bit = 3; | ||||
| 				goto exit; | ||||
| 			} | ||||
| 			first_time = 0; | ||||
| 		} | ||||
| 		//crc check
 | ||||
| 		ret = crc_check(ymodem_ptr); | ||||
| 		if(ret == 1){ | ||||
| 			error_bit = 4; | ||||
| 			goto exit; | ||||
| 		} | ||||
| 		else if(ret == 2 && ymodem_ptr->nxt_num == 0xff){ | ||||
| 			printf(" next num = %x\r\n",ymodem_ptr->nxt_num); | ||||
| 			transfer_over = 1; | ||||
| 			goto exit; | ||||
| 		} | ||||
| 	 | ||||
| #if 0 //avoid skip block
 | ||||
| 		uart_ymodem->cur_num = blk; | ||||
| 		if (blk != uart_ymodem->nxt_num) | ||||
| 		{ | ||||
| 			error_bit = -1; | ||||
| 		} | ||||
| #endif		 | ||||
| 		ymodem_ptr->nxt_num++; | ||||
| 		ymodem_ptr->rec_err=0; | ||||
| 		//start another round
 | ||||
| 		if(start_next_round(ymodem_ptr)){ | ||||
| 			error_bit = 5; | ||||
| 			printf(" start next round failed!\r\n"); | ||||
| 			goto exit;		 | ||||
| 		} | ||||
| } | ||||
| exit: | ||||
| 	//if anything goes wrong or transfer over,we kill ourself.
 | ||||
| 	if(error_bit || transfer_over){ | ||||
| 		if(error_bit) | ||||
| 			printf("error!!! error bit = %d\r\n",error_bit); | ||||
| 		else{ | ||||
| 			printf(" [%s, %d Bytes] transfer_over!\r\n",ymodem_ptr->filename,ymodem_ptr->filelen);	 | ||||
| 			set_signature(ymodem_ptr); | ||||
| #if DUMP_DATA | ||||
| 			flash_dump_data(ymodem_ptr); | ||||
| #endif | ||||
| #if AUTO_REBOOT | ||||
| 			auto_reboot(); | ||||
| #endif | ||||
| 		} | ||||
| 	} | ||||
| 	first_time = 1; | ||||
| 	uart_ymodem_deinit(ymodem_ptr); | ||||
| 	vTaskDelete(NULL);	 | ||||
| } | ||||
| 
 | ||||
| int uart_ymodem(void) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	uart_ymodem_t *uart_ymodem_ptr; | ||||
| 	 | ||||
| 	printf("uart ymodem update start\r\n"); | ||||
| 	uart_ymodem_ptr = (uart_ymodem_t *)RtlMalloc(sizeof(uart_ymodem_t)); | ||||
| 	if(!uart_ymodem_ptr){ | ||||
| 		printf("uart ymodem malloc fail!\r\n"); | ||||
| 		ret = -1; | ||||
| 		return ret; | ||||
| 	} | ||||
| 	uart_ymodem_init(uart_ymodem_ptr); | ||||
| 	if(ret == -1){ | ||||
| 		ret = -1; | ||||
| 		return ret; | ||||
| 	} | ||||
| 	//uart initial
 | ||||
| 	uart_init(uart_ymodem_ptr);	 | ||||
| 	if(xTaskCreate(uart_ymodem_thread, ((const char*)"uart_ymodem_thread"), UART_YMODEM_TASK_DEPTH, uart_ymodem_ptr, UART_YMODEM_TASK_PRIORITY, NULL) != pdPASS) | ||||
| 		printf("%s xTaskCreate(uart_thread) failed\r\n", __FUNCTION__); | ||||
| 	 | ||||
| 	return ret; | ||||
| } | ||||
							
								
								
									
										86
									
								
								component/common/utilities/uart_ymodem.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								component/common/utilities/uart_ymodem.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| /****************************************uart_ymodem.h**************************************************/ | ||||
| 
 | ||||
| #ifndef __YMODEM_H_ | ||||
| #define __YMODEM_H_ | ||||
| 
 | ||||
| #include "osdep_api.h" | ||||
| #include "serial_api.h" | ||||
| #include "flash_api.h" | ||||
| #include "device_lock.h" | ||||
| /***********************************************************************
 | ||||
|  *                                Macros                               * | ||||
|  ***********************************************************************/ | ||||
| // 8711AM
 | ||||
| #define UART_TX PA_7 | ||||
| #define UART_RX PA_6 | ||||
| //8711AF
 | ||||
| //#define UART_TX PA_4
 | ||||
| //#define UART_RX PA_0
 | ||||
| 
 | ||||
| #define UART_BAUDRATE 115200 | ||||
| #define UART_YMODEM_TASK_PRIORITY	5 | ||||
| #define UART_YMODEM_TASK_DEPTH	512 | ||||
| 
 | ||||
| #define CONFIG_CALC_FILE_SIZE 1 | ||||
| #define CRC_CHECK	1 | ||||
| #define AUTO_REBOOT 0 | ||||
| #define DUMP_DATA 0 | ||||
| 
 | ||||
| #define OFFSET_DATA		FLASH_SYSTEM_DATA_ADDR | ||||
| #define IMAGE_TWO			(0x80000) | ||||
| //Y-modem related
 | ||||
| #define MODEM_MAX_RETRIES   1 | ||||
| #define MODEM_CRC_RETRIES   51 | ||||
| #define MODEM_CAN_COUNT     3 | ||||
| #define MODEM_EOT_COUNT     1 | ||||
| 
 | ||||
| // ymodem protocol definition
 | ||||
| #define MODEM_SOH  0x01 | ||||
| #define MODEM_STX  0x02 | ||||
| #define MODEM_EOT  0x04 | ||||
| #define MODEM_ACK  0x06 | ||||
| #define MODEM_NAK  0x15 | ||||
| #define MODEM_CAN  0x18 | ||||
| #define MODEM_C    0x43 | ||||
| // 1 block size byte + 2 block number bytes + 1024 data body + 2 crc bytes
 | ||||
| #define RCV_BUF_SIZE ((1)+(2)+(1024)+(2)) | ||||
| /******************************** data struct **********************************/ | ||||
| typedef struct _uart_ymodem_t | ||||
| { | ||||
| 	serial_t sobj; | ||||
| 	flash_t  flash; | ||||
| 
 | ||||
| 	/* Used for UART RX */ | ||||
| 	u8 uart_rcv_buf[RCV_BUF_SIZE]; | ||||
| 	u8 uart_irq_buf[RCV_BUF_SIZE]; | ||||
| 	_Sema uart_rx_sema; | ||||
| 	u32 image_address; | ||||
| 	 | ||||
| 	u32 tick_last_update; | ||||
| 	u32 tick_current; | ||||
| 	u32 uart_recv_index; | ||||
| 	u32 uart_recv_buf_index; | ||||
| 	/* uart ymodem related*/ | ||||
| 	u32 modemtype; | ||||
|     u32 crc_mode; | ||||
|     u32 nxt_num;	//next block num
 | ||||
|     u32 cur_num;	//current block num
 | ||||
|     u32 len; | ||||
|     u32 rec_err;	//blcok data recv status
 | ||||
|     u32 filelen;	//Ymodem file length
 | ||||
|     u8 *buf;		//data buf
 | ||||
|     u8 *filename;	//file name
 | ||||
| }uart_ymodem_t; | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|     extern "C"{ | ||||
| #endif | ||||
|      | ||||
| extern int uart_ymodem(void); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										92
									
								
								component/common/utilities/udpecho.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								component/common/utilities/udpecho.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2001-2003 Swedish Institute of Computer Science. | ||||
|  * All rights reserved.  | ||||
|  *  | ||||
|  * Redistribution and use in source and binary forms, with or without modification,  | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|  *    this list of conditions and the following disclaimer in the documentation | ||||
|  *    and/or other materials provided with the distribution. | ||||
|  * 3. The name of the author may not be used to endorse or promote products | ||||
|  *    derived from this software without specific prior written permission.  | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  | ||||
|  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  | ||||
|  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  | ||||
|  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  | ||||
|  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  | ||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  | ||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  | ||||
|  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  | ||||
|  * OF SUCH DAMAGE. | ||||
|  * | ||||
|  * This file is part of the lwIP TCP/IP stack. | ||||
|  *  | ||||
|  * Author: Adam Dunkels <adam@sics.se> | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #include "lwip/opt.h" | ||||
| 
 | ||||
| #if LWIP_NETCONN | ||||
| 
 | ||||
| #include "lwip/api.h" | ||||
| #include "lwip/sys.h" | ||||
| 
 | ||||
| 
 | ||||
| #define UDPECHO_THREAD_PRIO  ( tskIDLE_PRIORITY + 3 ) | ||||
| 
 | ||||
| static struct netconn *conn; | ||||
| static struct netbuf *buf; | ||||
| static struct ip_addr *addr; | ||||
| static unsigned short port; | ||||
| /*-----------------------------------------------------------------------------------*/ | ||||
| static void udpecho_thread(void *arg) | ||||
| { | ||||
|   err_t err; | ||||
|    | ||||
|   LWIP_UNUSED_ARG(arg); | ||||
| 
 | ||||
|   conn = netconn_new(NETCONN_UDP); | ||||
|   if (conn!= NULL) | ||||
|   { | ||||
|     err = netconn_bind(conn, IP_ADDR_ANY, 7); | ||||
|     if (err == ERR_OK) | ||||
|     { | ||||
|       while (1)  | ||||
|       { | ||||
|         buf = netconn_recv(conn); | ||||
|        | ||||
|         if (buf!= NULL)  | ||||
|         { | ||||
|           addr = netbuf_fromaddr(buf); | ||||
|           port = netbuf_fromport(buf); | ||||
|           netconn_connect(conn, addr, port); | ||||
|           buf->addr = NULL; | ||||
|           netconn_send(conn,buf); | ||||
|           netbuf_delete(buf); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       printf("can not bind netconn"); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     printf("can create new UDP netconn"); | ||||
|   } | ||||
| } | ||||
| /*-----------------------------------------------------------------------------------*/ | ||||
| void udpecho_init(void) | ||||
| { | ||||
|   sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE,UDPECHO_THREAD_PRIO ); | ||||
| } | ||||
| 
 | ||||
| #endif /* LWIP_NETCONN */ | ||||
							
								
								
									
										1079
									
								
								component/common/utilities/update.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1079
									
								
								component/common/utilities/update.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										11
									
								
								component/common/utilities/update.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								component/common/utilities/update.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #ifndef UPDATE_H | ||||
| #define UPDATE_H | ||||
| 
 | ||||
| //--------------------------------------------------------------------------
 | ||||
| int update_ota_local(char *ip, int port); | ||||
| int update_ota_cloud(char *repository, char *file_path); | ||||
| void cmd_update(int argc, char **argv); | ||||
| void cmd_ota_image(bool cmd); | ||||
| 
 | ||||
| //----------------------------------------------------------------------------
 | ||||
| #endif | ||||
							
								
								
									
										1300
									
								
								component/common/utilities/webserver.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1300
									
								
								component/common/utilities/webserver.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										71
									
								
								component/common/utilities/webserver.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								component/common/utilities/webserver.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| /*
 | ||||
|     FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. | ||||
| 
 | ||||
|     *************************************************************************** | ||||
|     *                                                                         * | ||||
|     * If you are:                                                             * | ||||
|     *                                                                         * | ||||
|     *    + New to FreeRTOS,                                                   * | ||||
|     *    + Wanting to learn FreeRTOS or multitasking in general quickly       * | ||||
|     *    + Looking for basic training,                                        * | ||||
|     *    + Wanting to improve your FreeRTOS skills and productivity           * | ||||
|     *                                                                         * | ||||
|     * then take a look at the FreeRTOS eBook                                  * | ||||
|     *                                                                         * | ||||
|     *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        * | ||||
|     *                  http://www.FreeRTOS.org/Documentation                  *
 | ||||
|     *                                                                         * | ||||
|     * A pdf reference manual is also available.  Both are usually delivered   * | ||||
|     * to your inbox within 20 minutes to two hours when purchased between 8am * | ||||
|     * and 8pm GMT (although please allow up to 24 hours in case of            * | ||||
|     * exceptional circumstances).  Thank you for your support!                * | ||||
|     *                                                                         * | ||||
|     *************************************************************************** | ||||
| 
 | ||||
|     This file is part of the FreeRTOS distribution. | ||||
| 
 | ||||
|     FreeRTOS is free software; you can redistribute it and/or modify it under | ||||
|     the terms of the GNU General Public License (version 2) as published by the | ||||
|     Free Software Foundation AND MODIFIED BY the FreeRTOS exception. | ||||
|     ***NOTE*** The exception to the GPL is included to allow you to distribute | ||||
|     a combined work that includes FreeRTOS without being obliged to provide the | ||||
|     source code for proprietary components outside of the FreeRTOS kernel. | ||||
|     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT | ||||
|     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|     more details. You should have received a copy of the GNU General Public  | ||||
|     License and the FreeRTOS license exception along with FreeRTOS; if not it  | ||||
|     can be viewed here: http://www.freertos.org/a00114.html and also obtained 
 | ||||
|     by writing to Richard Barry, contact details for whom are available on the | ||||
|     FreeRTOS WEB site. | ||||
| 
 | ||||
|     1 tab == 4 spaces! | ||||
| 
 | ||||
|     http://www.FreeRTOS.org - Documentation, latest information, license and
 | ||||
|     contact details. | ||||
| 
 | ||||
|     http://www.SafeRTOS.com - A version that is certified for use in safety
 | ||||
|     critical systems. | ||||
| 
 | ||||
|     http://www.OpenRTOS.com - Commercial support, development, porting,
 | ||||
|     licensing and training services. | ||||
| */ | ||||
| 
 | ||||
| #ifndef BASIC_WEB_SERVER_H | ||||
| #define BASIC_WEB_SERVER_H | ||||
| #include <wifi/wifi_conf.h> | ||||
| /*------------------------------------------------------------------------------*/ | ||||
| /*                            MACROS                                             */ | ||||
| /*------------------------------------------------------------------------------*/ | ||||
| #define basicwebWEBSERVER_PRIORITY      ( tskIDLE_PRIORITY + 2 ) | ||||
| 
 | ||||
| #define lwipBASIC_SERVER_STACK_SIZE	256 | ||||
| 
 | ||||
| /*------------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| /* The function that implements the WEB server task. */ | ||||
| extern void	start_web_server(void); | ||||
| 
 | ||||
| #endif  /*  | ||||
|  */ | ||||
| 
 | ||||
							
								
								
									
										1376
									
								
								component/common/utilities/xml.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1376
									
								
								component/common/utilities/xml.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										43
									
								
								component/common/utilities/xml.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								component/common/utilities/xml.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| #ifndef _XML_H_ | ||||
| #define _XML_H_ | ||||
| 
 | ||||
| struct xml_node { | ||||
| 	char *name; | ||||
| 	char *text; | ||||
| 	char *prefix; | ||||
| 	char *uri; | ||||
| 	char *attr; | ||||
| 	struct xml_node *parent; | ||||
| 	struct xml_node *child; | ||||
| 	struct xml_node *prev; | ||||
| 	struct xml_node *next; | ||||
| }; | ||||
| 
 | ||||
| struct xml_node_set { | ||||
| 	int count; | ||||
| 	struct xml_node **node; | ||||
| }; | ||||
| 
 | ||||
| void xml_free(void *buf); | ||||
| int xml_doc_name(char *doc_buf, int doc_len, char **doc_prefix, char **doc_name, char **doc_uri); | ||||
| struct xml_node *xml_parse_doc(char *doc_buf, int doc_len, char *prefix, char *doc_name, char *uri); | ||||
| struct xml_node *xml_parse(char *doc_buf, int doc_len); | ||||
| struct xml_node *xml_new_element(char *prefix, char *name, char *uri); | ||||
| struct xml_node *xml_new_text(char *text); | ||||
| int xml_is_element(struct xml_node *node); | ||||
| int xml_is_text(struct xml_node *node); | ||||
| struct xml_node* xml_copy_tree(struct xml_node *root); | ||||
| void xml_delete_tree(struct xml_node *root); | ||||
| void xml_add_child(struct xml_node *node, struct xml_node *child); | ||||
| void xml_clear_child(struct xml_node *node); | ||||
| struct xml_node* xml_text_child(struct xml_node *node); | ||||
| void xml_set_text(struct xml_node *node, char *text); | ||||
| struct xml_node_set* xml_find_element(struct xml_node *root, char *name); | ||||
| struct xml_node_set* xml_find_path(struct xml_node *root, char *path); | ||||
| void xml_delete_set(struct xml_node_set *node_set); | ||||
| char *xml_dump_tree(struct xml_node *root); | ||||
| char *xml_dump_tree_ex(struct xml_node *root, char *prolog, int new_line, int space); | ||||
| void xml_set_attribute(struct xml_node *node, char *attr, char *value); | ||||
| char *xml_get_attribute(struct xml_node *node, char *attr); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue