mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-07-31 12:41:06 +00:00
first commit
This commit is contained in:
parent
2ee525362e
commit
d108756e9b
792 changed files with 336059 additions and 0 deletions
596
RTL00_SDKV35a/component/common/utilities/cJSON.c
Normal file
596
RTL00_SDKV35a/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
RTL00_SDKV35a/component/common/utilities/cJSON.h
Normal file
145
RTL00_SDKV35a/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
RTL00_SDKV35a/component/common/utilities/http_client.c
Normal file
137
RTL00_SDKV35a/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
RTL00_SDKV35a/component/common/utilities/http_client.h
Normal file
10
RTL00_SDKV35a/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
|
248
RTL00_SDKV35a/component/common/utilities/ssl_client.c
Normal file
248
RTL00_SDKV35a/component/common/utilities/ssl_client.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "polarssl/config.h"
|
||||
#include "platform_opts.h"
|
||||
|
||||
#if CONFIG_SSL_CLIENT
|
||||
|
||||
#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(" . Connecting to tcp/%s/%d...\n", server_host, SERVER_PORT);
|
||||
|
||||
if((ret = net_connect(&server_fd, server_host, SERVER_PORT)) != 0) {
|
||||
printf(" failed\n ! net_connect returned %d\n", ret);
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
/*
|
||||
* 2. Setup stuff
|
||||
*/
|
||||
printf(" . Setting up the SSL/TLS structure...\n" );
|
||||
|
||||
if((ret = ssl_init(&ssl)) != 0) {
|
||||
printf(" failed\n ! ssl_init returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
#ifdef SSL_CLIENT_EXT
|
||||
if((ret = ssl_client_ext_init()) != 0) {
|
||||
printf(" failed\n ! 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 ! ssl_client_ext_setup returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
/*
|
||||
* 3. Handshake
|
||||
*/
|
||||
printf(" . Performing the SSL/TLS handshake...\n");
|
||||
|
||||
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 ! ssl_handshake returned -0x%x\n", -ret);
|
||||
goto exit;
|
||||
}
|
||||
retry_count++;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
printf(" . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl));
|
||||
|
||||
/*
|
||||
* 4. Write the GET request
|
||||
*/
|
||||
printf(" > Write to server:\n");
|
||||
|
||||
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 ! ssl_write returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
len = ret;
|
||||
printf(" %d bytes written\n%s\n", len, (char *) buf);
|
||||
|
||||
/*
|
||||
* 5. Read the HTTP response
|
||||
*/
|
||||
printf(" < 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 ! ssl_read returned %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == 0) {
|
||||
printf("EOF\n");
|
||||
break;
|
||||
}
|
||||
|
||||
len = ret;
|
||||
printf(" %d bytes read\n%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("\nLast 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("\nMin available stack size of %s = %d * %d bytes\n", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
||||
#endif
|
||||
|
||||
if(min_heap_size > 0)
|
||||
printf("\nMin available heap size = %d bytes during %s\n", 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("%s xTaskCreate failed\n", __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("%s fail (success %d times, fail %d times)\n", __FUNCTION__, success, ++ fail);
|
||||
else
|
||||
printf("%s success (success %d times, fail %d times)\n", __FUNCTION__, ++ success, fail);
|
||||
}
|
||||
|
||||
void cmd_ssl_client(int argc, char **argv)
|
||||
{
|
||||
if(argc == 2) {
|
||||
strcpy(server_host, argv[1]);
|
||||
}
|
||||
else {
|
||||
printf("Usage: %s SSL_SERVER_HOST\n", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
start_ssl_client();
|
||||
}
|
||||
|
||||
#endif // #if CONFIG_SSL_CLIENT
|
184
RTL00_SDKV35a/component/common/utilities/ssl_client_ext.c
Normal file
184
RTL00_SDKV35a/component/common/utilities/ssl_client_ext.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
#include <polarssl/ssl.h>
|
||||
#include <polarssl/memory.h>
|
||||
#include "platform_opts.h"
|
||||
|
||||
#if CONFIG_SSL_CLIENT
|
||||
//#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;
|
||||
}
|
||||
|
||||
#endif //#if CONFIG_SSL_CLIENT
|
938
RTL00_SDKV35a/component/common/utilities/tcptest.c
Normal file
938
RTL00_SDKV35a/component/common/utilities/tcptest.c
Normal file
|
@ -0,0 +1,938 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
|
||||
#if CONFIG_BSD_TCP
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
#if LWIP_SOCKET
|
||||
#include <lwip/raw.h>
|
||||
#include <lwip/icmp.h>
|
||||
#include <lwip/inet_chksum.h>
|
||||
#include <platform/platform_stdlib.h>
|
||||
|
||||
#include "wifi_util.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;
|
||||
}
|
||||
|
||||
#endif // CONFIG_BSD_TCP
|
||||
|
||||
#endif // LWIP_SOCKET
|
||||
|
372
RTL00_SDKV35a/component/common/utilities/uart_socket.c
Normal file
372
RTL00_SDKV35a/component/common/utilities/uart_socket.c
Normal file
|
@ -0,0 +1,372 @@
|
|||
#include "lwip/api.h"
|
||||
#include "PinNames.h"
|
||||
#include "sockets.h"
|
||||
#include "uart_socket.h"
|
||||
#include "autoconf.h"
|
||||
|
||||
#if CONFIG_UART_SOCKET
|
||||
|
||||
#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__);
|
||||
}
|
||||
|
||||
#endif // #if CONFIG_UART_SOCKET
|
52
RTL00_SDKV35a/component/common/utilities/uart_socket.h
Normal file
52
RTL00_SDKV35a/component/common/utilities/uart_socket.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef __UART_SOCKET_H_
|
||||
#define __UART_SOCKET_H_
|
||||
|
||||
#include "osdep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
|
||||
#if CONFIG_UART_SOCKET
|
||||
#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 // #if CONFIG_UART_SOCKET
|
||||
#endif //__UART_SOCKET_H_
|
656
RTL00_SDKV35a/component/common/utilities/uart_ymodem.c
Normal file
656
RTL00_SDKV35a/component/common/utilities/uart_ymodem.c
Normal file
|
@ -0,0 +1,656 @@
|
|||
/****************************************uart _ymodem.c**************************************************/
|
||||
|
||||
#include "osdep_service.h"
|
||||
#include "uart_ymodem.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if CONFIG_UART_SOCKET
|
||||
/*****************************************************************************************
|
||||
* 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;
|
||||
}
|
||||
#endif // #if CONFIG_UART_SOCKET
|
89
RTL00_SDKV35a/component/common/utilities/uart_ymodem.h
Normal file
89
RTL00_SDKV35a/component/common/utilities/uart_ymodem.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/****************************************uart_ymodem.h**************************************************/
|
||||
|
||||
#ifndef __YMODEM_H_
|
||||
#define __YMODEM_H_
|
||||
|
||||
#if CONFIG_UART_SOCKET
|
||||
|
||||
#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
|
||||
#endif //#if CONFIG_UART_SOCKET
|
1083
RTL00_SDKV35a/component/common/utilities/update.c
Normal file
1083
RTL00_SDKV35a/component/common/utilities/update.c
Normal file
File diff suppressed because it is too large
Load diff
11
RTL00_SDKV35a/component/common/utilities/update.h
Normal file
11
RTL00_SDKV35a/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
|
1304
RTL00_SDKV35a/component/common/utilities/webserver.c
Normal file
1304
RTL00_SDKV35a/component/common/utilities/webserver.c
Normal file
File diff suppressed because it is too large
Load diff
72
RTL00_SDKV35a/component/common/utilities/webserver.h
Normal file
72
RTL00_SDKV35a/component/common/utilities/webserver.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
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
RTL00_SDKV35a/component/common/utilities/xml.c
Normal file
1376
RTL00_SDKV35a/component/common/utilities/xml.c
Normal file
File diff suppressed because it is too large
Load diff
43
RTL00_SDKV35a/component/common/utilities/xml.h
Normal file
43
RTL00_SDKV35a/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