mirror of
https://github.com/cwyark/ameba-sdk-gcc-make.git
synced 2026-07-08 14:05:39 +00:00
first commit and add gitignore, README.md
This commit is contained in:
commit
760756ba2c
1861 changed files with 709236 additions and 0 deletions
596
component/common/utilities/cJSON.c
Executable file
596
component/common/utilities/cJSON.c
Executable file
|
|
@ -0,0 +1,596 @@
|
|||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned parse_hex4(const char *str)
|
||||
{
|
||||
unsigned h=0;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
uc2=parse_hex4(ptr+3);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+4:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){if(newitem->string) cJSON_free(newitem->string);newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void cJSON_Minify(char *json)
|
||||
{
|
||||
char *into=json;
|
||||
while (*json)
|
||||
{
|
||||
if (*json==' ') json++;
|
||||
else if (*json=='\t') json++; // Whitespace characters.
|
||||
else if (*json=='\r') json++;
|
||||
else if (*json=='\n') json++;
|
||||
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
|
||||
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
|
||||
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
|
||||
else *into++=*json++; // All other characters.
|
||||
}
|
||||
*into=0; // and null-terminate.
|
||||
}
|
||||
145
component/common/utilities/cJSON.h
Executable file
145
component/common/utilities/cJSON.h
Executable 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
|
||||
277
component/common/utilities/ssl_client.c
Executable file
277
component/common/utilities/ssl_client.c
Executable file
|
|
@ -0,0 +1,277 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "polarssl/config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "polarssl/net.h"
|
||||
#include "polarssl/ssl.h"
|
||||
#include "polarssl/error.h"
|
||||
#include "polarssl/memory.h"
|
||||
|
||||
#define SERVER_PORT 443
|
||||
#define SERVER_HOST "192.168.13.15"
|
||||
#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
|
||||
#define DEBUG_LEVEL 0
|
||||
#define SSL_USE_SRP 0
|
||||
#define STACKSIZE 1150
|
||||
|
||||
static int is_task = 0;
|
||||
char server_host[16];
|
||||
#if SSL_USE_SRP
|
||||
char srp_username[16];
|
||||
char srp_password[16];
|
||||
#endif
|
||||
|
||||
static void my_debug(void *ctx, int level, const char *str)
|
||||
{
|
||||
if(level <= DEBUG_LEVEL) {
|
||||
printf("\n\r%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int arc4random(void)
|
||||
{
|
||||
unsigned int res = xTaskGetTickCount();
|
||||
static unsigned int seed = 0xDEADB00B;
|
||||
|
||||
seed = ((seed & 0x007F00FF) << 7) ^
|
||||
((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
|
||||
(res << 13) ^ (res >> 9); // using the clock too!
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
static void get_random_bytes(void *buf, size_t len)
|
||||
{
|
||||
unsigned int ranbuf;
|
||||
unsigned int *lp;
|
||||
int i, count;
|
||||
count = len / sizeof(unsigned int);
|
||||
lp = (unsigned int *) buf;
|
||||
|
||||
for(i = 0; i < count; i ++) {
|
||||
lp[i] = arc4random();
|
||||
len -= sizeof(unsigned int);
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
ranbuf = arc4random();
|
||||
memcpy(&lp[i], &ranbuf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
|
||||
{
|
||||
get_random_bytes(output, output_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t min_heap_size = 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;
|
||||
|
||||
memory_set_own(my_malloc, my_free);
|
||||
/*
|
||||
* 0. Initialize the session data
|
||||
*/
|
||||
memset(&ssl, 0, sizeof(ssl_context));
|
||||
|
||||
/*
|
||||
* 1. Start the connection
|
||||
*/
|
||||
printf("\n\r . Connecting to tcp/%s/%d...", server_host, SERVER_PORT);
|
||||
|
||||
if((ret = net_connect(&server_fd, server_host, SERVER_PORT)) != 0) {
|
||||
printf(" failed\n\r ! net_connect returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
/*
|
||||
* 2. Setup stuff
|
||||
*/
|
||||
printf("\n\r . Setting up the SSL/TLS structure..." );
|
||||
|
||||
if((ret = ssl_init(&ssl)) != 0) {
|
||||
printf(" failed\n\r ! ssl_init returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
|
||||
ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
|
||||
ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
|
||||
ssl_set_rng(&ssl, my_random, NULL);
|
||||
#ifdef POLARSSL_DEBUG_C
|
||||
debug_set_threshold(DEBUG_LEVEL);
|
||||
#endif
|
||||
ssl_set_dbg(&ssl, my_debug, NULL);
|
||||
ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd);
|
||||
#if SSL_USE_SRP
|
||||
if(strlen(srp_username))
|
||||
ssl_set_srp(&ssl, srp_username, strlen(srp_username), srp_password, strlen(srp_password));
|
||||
#endif
|
||||
/*
|
||||
* 3. Handshake
|
||||
*/
|
||||
printf("\n\r . Performing the SSL/TLS handshake...");
|
||||
|
||||
while((ret = ssl_handshake(&ssl)) != 0) {
|
||||
if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
|
||||
printf(" failed\n\r ! ssl_handshake returned -0x%x\n", -ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" ok\n");
|
||||
printf("\n\r . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl));
|
||||
|
||||
/*
|
||||
* 4. Write the GET request
|
||||
*/
|
||||
printf("\n\r > Write to server:");
|
||||
|
||||
len = sprintf((char *) buf, GET_REQUEST);
|
||||
|
||||
while((ret = ssl_write(&ssl, buf, len)) <= 0) {
|
||||
if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
|
||||
printf(" failed\n\r ! ssl_write returned %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
len = ret;
|
||||
printf(" %d bytes written\n\r\n\r%s\n", len, (char *) buf);
|
||||
|
||||
/*
|
||||
* 5. Read the HTTP response
|
||||
*/
|
||||
printf("\n\r < Read from server:");
|
||||
|
||||
do {
|
||||
len = sizeof(buf) - 1;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = ssl_read(&ssl, buf, len);
|
||||
|
||||
if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE)
|
||||
continue;
|
||||
|
||||
if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||
break;
|
||||
|
||||
if(ret < 0) {
|
||||
printf(" failed\n\r ! ssl_read returned %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == 0) {
|
||||
printf("\n\rEOF\n");
|
||||
break;
|
||||
}
|
||||
|
||||
len = ret;
|
||||
printf(" %d bytes read\n\r\n\r%s\n", len, (char *) buf);
|
||||
}
|
||||
while(1);
|
||||
|
||||
ssl_close_notify(&ssl);
|
||||
|
||||
exit:
|
||||
|
||||
#ifdef POLARSSL_ERROR_C
|
||||
if(ret != 0) {
|
||||
char error_buf[100];
|
||||
polarssl_strerror(ret, error_buf, 100);
|
||||
printf("\n\rLast error was: %d - %s\n", ret, error_buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
net_close(server_fd);
|
||||
ssl_free(&ssl);
|
||||
|
||||
if(is_task) {
|
||||
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
||||
printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
||||
#endif
|
||||
|
||||
if(min_heap_size > 0)
|
||||
printf("\n\rMin available heap size = %d bytes during %s\n\r", min_heap_size, __FUNCTION__);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
if(param != NULL)
|
||||
*((int *) param) = ret;
|
||||
}
|
||||
|
||||
void start_ssl_client(void)
|
||||
{
|
||||
is_task = 1;
|
||||
//strcpy(server_host, SERVER_HOST);
|
||||
|
||||
if(xTaskCreate(ssl_client, "ssl_client", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
|
||||
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
|
||||
}
|
||||
|
||||
void do_ssl_connect(void)
|
||||
{
|
||||
int ret;
|
||||
static int success = 0;
|
||||
static int fail = 0;
|
||||
|
||||
is_task = 0;
|
||||
strcpy(server_host, SERVER_HOST);
|
||||
ssl_client(&ret);
|
||||
|
||||
if(ret != 0)
|
||||
printf("\n\r%s fail (success %d times, fail %d times)\n\r", __FUNCTION__, success, ++ fail);
|
||||
else
|
||||
printf("\n\r%s success (success %d times, fail %d times)\n\r", __FUNCTION__, ++ success, fail);
|
||||
}
|
||||
|
||||
void cmd_ssl_client(int argc, char **argv)
|
||||
{
|
||||
if(argc == 2) {
|
||||
strcpy(server_host, argv[1]);
|
||||
#if SSL_USE_SRP
|
||||
strcpy(srp_username, "");
|
||||
strcpy(srp_password, "");
|
||||
#endif
|
||||
}
|
||||
#if SSL_USE_SRP
|
||||
else if(argc == 4) {
|
||||
strcpy(server_host, argv[1]);
|
||||
strcpy(srp_username, argv[2]);
|
||||
strcpy(srp_password, argv[3]);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
#if SSL_USE_SRP
|
||||
printf("\n\rUsage: %s SSL_SERVER_HOST [SRP_USER_NAME SRP_PASSWORD]", argv[0]);
|
||||
#else
|
||||
printf("\n\rUsage: %s SSL_SERVER_HOST", argv[0]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
start_ssl_client();
|
||||
}
|
||||
121
component/common/utilities/tcpecho.c
Executable file
121
component/common/utilities/tcpecho.c
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_NETCONN
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/api.h"
|
||||
|
||||
#define TCPECHO_THREAD_PRIO ( tskIDLE_PRIORITY + 3 )
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void tcpecho_thread(void *arg)
|
||||
{
|
||||
struct netconn *conn, *newconn;
|
||||
err_t err;
|
||||
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
|
||||
/* Create a new connection identifier. */
|
||||
conn = netconn_new(NETCONN_TCP);
|
||||
|
||||
if (conn!=NULL)
|
||||
{
|
||||
/* Bind connection to well known port number 7. */
|
||||
err = netconn_bind(conn, NULL, 7);
|
||||
|
||||
if (err == ERR_OK)
|
||||
{
|
||||
/* Tell connection to go into listening mode. */
|
||||
netconn_listen(conn);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Grab new connection. */
|
||||
newconn = netconn_accept(conn);
|
||||
|
||||
/* Process the new connection. */
|
||||
if (newconn)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
void *data;
|
||||
u16_t len;
|
||||
|
||||
while ((buf = netconn_recv(newconn)) != NULL)
|
||||
{
|
||||
do
|
||||
{
|
||||
netbuf_data(buf, &data, &len);
|
||||
netconn_write(newconn, data, len, NETCONN_COPY);
|
||||
|
||||
}
|
||||
while (netbuf_next(buf) >= 0);
|
||||
|
||||
netbuf_delete(buf);
|
||||
}
|
||||
|
||||
/* Close connection and discard connection identifier. */
|
||||
netconn_close(newconn);
|
||||
netconn_delete(newconn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" can not bind TCP netconn");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("can not create TCP netconn");
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void tcpecho_init(void)
|
||||
{
|
||||
sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void cmd_tcpecho(int argc, char **argv)
|
||||
{
|
||||
printf("\n\rInit TCP ECHO Server ...");
|
||||
tcpecho_init();
|
||||
printf("\n\r\nPlease use echotool to connect to this echo server. ex. echotool 192.168.0.1 /p tcp /r 7 /n 0");
|
||||
}
|
||||
#endif /* LWIP_NETCONN */
|
||||
536
component/common/utilities/tcptest.c
Executable file
536
component/common/utilities/tcptest.c
Executable file
|
|
@ -0,0 +1,536 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/raw.h>
|
||||
#include <lwip/icmp.h>
|
||||
#include <lwip/inet_chksum.h>
|
||||
#include <platform/platform_stdlib.h>
|
||||
|
||||
#define TCP_PACKET_COUNT 10000
|
||||
#define BSD_STACK_SIZE 256
|
||||
|
||||
#define HOST_IP "192.168.1.101"
|
||||
#define REMOTE_IP ((u32_t)0xc0a80165UL) /*192.168.1.101*/
|
||||
#define LOCAL_IP ((u32_t)0xc0a80164UL) /*192.168.1.100*/
|
||||
|
||||
unsigned int g_srv_buf_size = 1500;
|
||||
unsigned int g_cli_buf_size = 1500;
|
||||
xTaskHandle g_server_task = NULL;
|
||||
xTaskHandle g_client_task = NULL;
|
||||
|
||||
xTaskHandle udpcllient_task = NULL;
|
||||
xTaskHandle udpserver_task = NULL;
|
||||
|
||||
unsigned char g_start_server = 0;
|
||||
unsigned char g_start_client = 0;
|
||||
unsigned char g_terminate = 0;
|
||||
|
||||
unsigned char udp_start_server = 0;
|
||||
unsigned char udp_start_client= 0;
|
||||
char g_server_ip[16];
|
||||
unsigned long g_ulPacketCount = TCP_PACKET_COUNT;
|
||||
|
||||
int BsdTcpClient(const char *host_ip, unsigned short usPort)
|
||||
{
|
||||
int iCounter;
|
||||
short sTestBufLen;
|
||||
struct sockaddr_in sAddr;
|
||||
int iAddrSize;
|
||||
int iSockFD;
|
||||
int iStatus;
|
||||
long lLoopCount = 0;
|
||||
char *cBsdBuf = NULL;
|
||||
|
||||
if(g_cli_buf_size > 4300)
|
||||
g_cli_buf_size = 4300;
|
||||
else if (g_cli_buf_size == 0)
|
||||
g_cli_buf_size = 1500;
|
||||
|
||||
cBsdBuf = pvPortMalloc(g_cli_buf_size);
|
||||
if(NULL == cBsdBuf){
|
||||
printf("\n\rTCP: Allocate client buffer failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// filling the buffer
|
||||
for (iCounter = 0; iCounter < g_cli_buf_size; iCounter++) {
|
||||
cBsdBuf[iCounter] = (char)(iCounter % 10);
|
||||
}
|
||||
sTestBufLen = g_cli_buf_size;
|
||||
|
||||
//filling the TCP server socket address
|
||||
FD_ZERO(&sAddr);
|
||||
sAddr.sin_family = AF_INET;
|
||||
sAddr.sin_port = htons(usPort);
|
||||
sAddr.sin_addr.s_addr = inet_addr(host_ip);
|
||||
|
||||
iAddrSize = sizeof(struct sockaddr_in);
|
||||
|
||||
// creating a TCP socket
|
||||
iSockFD = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if( iSockFD < 0 ) {
|
||||
printf("\n\rTCP ERROR: create tcp client socket fd error!");
|
||||
goto Exit1;
|
||||
}
|
||||
|
||||
printf("\n\rTCP: ServerIP=%s port=%d.", host_ip, usPort);
|
||||
printf("\n\rTCP: Create socket %d.", iSockFD);
|
||||
// connecting to TCP server
|
||||
iStatus = connect(iSockFD, (struct sockaddr *)&sAddr, iAddrSize);
|
||||
if (iStatus < 0) {
|
||||
printf("\n\rTCP ERROR: tcp client connect server error! ");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
printf("\n\rTCP: Connect server successfully.");
|
||||
// sending multiple packets to the TCP server
|
||||
while (lLoopCount < g_ulPacketCount && !g_terminate) {
|
||||
// sending packet
|
||||
iStatus = send(iSockFD, cBsdBuf, sTestBufLen, 0 );
|
||||
if( iStatus <= 0 ) {
|
||||
printf("\r\nTCP ERROR: tcp client send data error! iStatus:%d", iStatus);
|
||||
goto Exit;
|
||||
}
|
||||
lLoopCount++;
|
||||
//printf("BsdTcpClient:: send data count:%ld iStatus:%d \n\r", lLoopCount, iStatus);
|
||||
}
|
||||
|
||||
printf("\n\rTCP: Sent %u packets successfully.",g_ulPacketCount);
|
||||
|
||||
Exit:
|
||||
//closing the socket after sending 1000 packets
|
||||
close(iSockFD);
|
||||
|
||||
Exit1:
|
||||
//free buffer
|
||||
vPortFree(cBsdBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BsdTcpServer(unsigned short usPort)
|
||||
{
|
||||
struct sockaddr_in sAddr;
|
||||
struct sockaddr_in sLocalAddr;
|
||||
int iCounter;
|
||||
int iAddrSize;
|
||||
int iSockFD;
|
||||
int iStatus;
|
||||
int iNewSockFD;
|
||||
long lLoopCount = 0;
|
||||
//long lNonBlocking = 1;
|
||||
int iTestBufLen;
|
||||
int n;
|
||||
char *cBsdBuf = NULL;
|
||||
|
||||
if(g_srv_buf_size > 5000)
|
||||
g_srv_buf_size = 5000;
|
||||
else if (g_srv_buf_size == 0)
|
||||
g_srv_buf_size = 1500;
|
||||
|
||||
cBsdBuf = pvPortMalloc(g_srv_buf_size);
|
||||
if(NULL == cBsdBuf){
|
||||
printf("\n\rTCP: Allocate server buffer failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// filling the buffer
|
||||
for (iCounter = 0; iCounter < g_srv_buf_size; iCounter++) {
|
||||
cBsdBuf[iCounter] = (char)(iCounter % 10);
|
||||
}
|
||||
iTestBufLen = g_srv_buf_size;
|
||||
|
||||
// creating a TCP socket
|
||||
iSockFD = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if( iSockFD < 0 ) {
|
||||
goto Exit2;
|
||||
}
|
||||
|
||||
printf("\n\rTCP: Create server socket %d\n\r", iSockFD);
|
||||
n = 1;
|
||||
setsockopt( iSockFD, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &n, sizeof( n ) );
|
||||
|
||||
//filling the TCP server socket address
|
||||
memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
|
||||
sLocalAddr.sin_family = AF_INET;
|
||||
sLocalAddr.sin_len = sizeof(sLocalAddr);
|
||||
sLocalAddr.sin_port = htons(usPort);
|
||||
sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
iAddrSize = sizeof(sLocalAddr);
|
||||
|
||||
// binding the TCP socket to the TCP server address
|
||||
iStatus = bind(iSockFD, (struct sockaddr *)&sLocalAddr, iAddrSize);
|
||||
if( iStatus < 0 ) {
|
||||
printf("\n\rTCP ERROR: bind tcp server socket fd error! ");
|
||||
goto Exit1;
|
||||
}
|
||||
printf("\n\rTCP: Bind successfully.");
|
||||
|
||||
// putting the socket for listening to the incoming TCP connection
|
||||
iStatus = listen(iSockFD, 20);
|
||||
if( iStatus != 0 ) {
|
||||
printf("\n\rTCP ERROR: listen tcp server socket fd error! ");
|
||||
goto Exit1;
|
||||
}
|
||||
printf("\n\rTCP: Listen port %d", usPort);
|
||||
|
||||
// setting socket option to make the socket as non blocking
|
||||
//iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_NONBLOCKING,
|
||||
// &lNonBlocking, sizeof(lNonBlocking));
|
||||
//if( iStatus < 0 ) {
|
||||
// return -1;
|
||||
//}
|
||||
Restart:
|
||||
iNewSockFD = -1;
|
||||
lLoopCount = 0;
|
||||
|
||||
// waiting for an incoming TCP connection
|
||||
while( iNewSockFD < 0 ) {
|
||||
// accepts a connection form a TCP client, if there is any
|
||||
// otherwise returns SL_EAGAIN
|
||||
int addrlen=sizeof(sAddr);
|
||||
iNewSockFD = accept(iSockFD, ( struct sockaddr *)&sAddr,
|
||||
(socklen_t*)&addrlen);
|
||||
if( iNewSockFD < 0 ) {
|
||||
printf("\n\rTCP ERROR: Accept tcp client socket fd error! ");
|
||||
goto Exit1;
|
||||
}
|
||||
printf("\n\rTCP: Accept socket %d successfully.", iNewSockFD);
|
||||
}
|
||||
|
||||
// waits packets from the connected TCP client
|
||||
while (!g_terminate) {
|
||||
iStatus = recv(iNewSockFD, cBsdBuf, iTestBufLen, 0); //MSG_DONTWAIT MSG_WAITALL
|
||||
if( iStatus < 0 ) {
|
||||
printf("\n\rTCP ERROR: server recv data error iStatus:%d ", iStatus);
|
||||
goto Exit;
|
||||
} else if (iStatus == 0) {
|
||||
printf("\n\rTCP: Recieved %u packets successfully.", lLoopCount);
|
||||
close(iNewSockFD);
|
||||
goto Restart;
|
||||
}
|
||||
lLoopCount++;
|
||||
}
|
||||
|
||||
Exit:
|
||||
// close the connected socket after receiving from connected TCP client
|
||||
close(iNewSockFD);
|
||||
|
||||
Exit1:
|
||||
// close the listening socket
|
||||
close(iSockFD);
|
||||
|
||||
Exit2:
|
||||
//free buffer
|
||||
vPortFree(cBsdBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void TcpServerHandler(void *param)
|
||||
{
|
||||
unsigned short port = 5001;
|
||||
vTaskDelay(1000);
|
||||
printf("\n\rTCP: Start tcp Server!");
|
||||
if(g_start_server)
|
||||
BsdTcpServer(port);
|
||||
|
||||
#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_server_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void TcpClientHandler(void *param)
|
||||
{
|
||||
unsigned short port = 5001;
|
||||
vTaskDelay(1000);
|
||||
printf("\n\rTCP: Start tcp client!");
|
||||
if(g_start_client)
|
||||
BsdTcpClient(g_server_ip, port);
|
||||
|
||||
#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_client_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
/***************************udp related*********************************/
|
||||
int udpclient()
|
||||
{
|
||||
int cli_sockfd;
|
||||
socklen_t addrlen;
|
||||
struct sockaddr_in cli_addr;
|
||||
int loop= 0;
|
||||
char *buffer ;
|
||||
// int delay = 2;
|
||||
|
||||
|
||||
if(!g_ulPacketCount)
|
||||
g_ulPacketCount = 100;
|
||||
|
||||
if(!g_cli_buf_size)
|
||||
g_cli_buf_size = 1500;
|
||||
|
||||
buffer = (char*)pvPortMalloc(g_cli_buf_size);
|
||||
|
||||
if(NULL == buffer){
|
||||
printf("\n\rudpclient: Allocate buffer failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*create socket*/
|
||||
memset(buffer, 0, g_cli_buf_size);
|
||||
cli_sockfd=socket(AF_INET,SOCK_DGRAM,0);
|
||||
if (cli_sockfd<0) {
|
||||
printf("create socket failed\r\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fill sockaddr_in*/
|
||||
addrlen=sizeof(struct sockaddr_in);
|
||||
memset(&cli_addr, 0, addrlen);
|
||||
|
||||
cli_addr.sin_family=AF_INET;
|
||||
cli_addr.sin_addr.s_addr=inet_addr(g_server_ip);
|
||||
cli_addr.sin_port=htons(5001);
|
||||
|
||||
/* send data to server*/
|
||||
while(loop < g_ulPacketCount && !g_terminate) {
|
||||
if(sendto(cli_sockfd, buffer, g_cli_buf_size, 0,(struct sockaddr*)&cli_addr, addrlen) < 0) {
|
||||
// Dynamic delay to prevent send fail due to limited skb, this will degrade throughtput
|
||||
// if(delay < 100)
|
||||
// delay += 2;
|
||||
}
|
||||
|
||||
// vTaskDelay(delay);
|
||||
loop++;
|
||||
}
|
||||
close(cli_sockfd);
|
||||
//free buffer
|
||||
vPortFree(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udpserver()
|
||||
{
|
||||
int ser_sockfd;
|
||||
socklen_t addrlen;
|
||||
struct sockaddr_in ser_addr, peer_addr;
|
||||
uint32_t start_time, end_time;
|
||||
unsigned char *buffer;
|
||||
int total_size = 0, report_interval = 1;
|
||||
|
||||
if (g_srv_buf_size == 0)
|
||||
g_srv_buf_size = 1500;
|
||||
|
||||
buffer = pvPortMalloc(g_srv_buf_size);
|
||||
|
||||
if(NULL == buffer){
|
||||
printf("\n\rudpclient: Allocate buffer failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*create socket*/
|
||||
ser_sockfd=socket(AF_INET,SOCK_DGRAM,0);
|
||||
if (ser_sockfd<0) {
|
||||
printf("\n\rudp server success");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*fill the socket in*/
|
||||
addrlen=sizeof(ser_addr);
|
||||
memset(&ser_addr, 0,addrlen);
|
||||
ser_addr.sin_family=AF_INET;
|
||||
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
ser_addr.sin_port=htons(5001);
|
||||
|
||||
/*bind*/
|
||||
if (bind(ser_sockfd,(struct sockaddr *)&ser_addr,addrlen)<0) {
|
||||
printf("bind failed\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
start_time = xTaskGetTickCount();
|
||||
total_size = 0;
|
||||
|
||||
while(1) {
|
||||
int read_size = 0;
|
||||
addrlen = sizeof(peer_addr);
|
||||
read_size=recvfrom(ser_sockfd,buffer,g_srv_buf_size,0,(struct sockaddr *) &peer_addr,&addrlen);
|
||||
if(read_size < 0){
|
||||
printf("%s recv error\r\n", __FUNCTION__);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
end_time = xTaskGetTickCount();
|
||||
total_size += read_size;
|
||||
if((end_time - start_time) >= (configTICK_RATE_HZ * report_interval)) {
|
||||
printf("\nUDP recv %d bytes in %d ticks, %d Kbits/sec\n",
|
||||
total_size, end_time - start_time, total_size * 8 / 1024 / ((end_time - start_time) / configTICK_RATE_HZ));
|
||||
start_time = end_time;
|
||||
total_size = 0;
|
||||
}
|
||||
|
||||
/*ack data to client*/
|
||||
// Not send ack to prevent send fail due to limited skb, but it will have warning at iperf client
|
||||
// sendto(ser_sockfd,buffer,read_size,0,(struct sockaddr*)&peer_addr,sizeof(peer_addr));
|
||||
}
|
||||
|
||||
Exit:
|
||||
close(ser_sockfd);
|
||||
//free buffer
|
||||
vPortFree(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Udpclienthandler(void *param)
|
||||
{
|
||||
/*here gives the udp demo code*/
|
||||
vTaskDelay(1000);
|
||||
printf("\n\rUdp client test");
|
||||
|
||||
udpclient();
|
||||
#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!");
|
||||
udpcllient_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void Udpserverhandler(void *param)
|
||||
{
|
||||
/*here gives the udp demo code*/
|
||||
vTaskDelay(1000);
|
||||
printf("\n\rUdp server test");
|
||||
|
||||
udpserver();
|
||||
#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!");
|
||||
udpserver_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/***************************end of udp*********************************/
|
||||
void cmd_tcp(int argc, char **argv)
|
||||
{
|
||||
g_terminate = g_start_server = g_start_client = 0;
|
||||
g_ulPacketCount = 10000;
|
||||
memset(g_server_ip, 0, 16);
|
||||
|
||||
if(argc < 2)
|
||||
goto Exit;
|
||||
|
||||
if(strcmp(argv[1], "-s") == 0 ||strcmp(argv[1], "s") == 0) {
|
||||
if(g_server_task){
|
||||
printf("\n\rTCP: Tcp Server is already running.");
|
||||
return;
|
||||
}else{
|
||||
g_start_server = 1;
|
||||
if(argc == 3)
|
||||
g_srv_buf_size = atoi(argv[2]);
|
||||
}
|
||||
}else if(strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "c") == 0) {
|
||||
if(g_client_task){
|
||||
printf("\n\rTCP: Tcp client is already running. Please enter \"tcp stop\" to stop it.");
|
||||
return;
|
||||
}else{
|
||||
if(argc < 4)
|
||||
goto Exit;
|
||||
g_start_client = 1;
|
||||
strncpy(g_server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2]));
|
||||
g_cli_buf_size = atoi(argv[3]);
|
||||
if(argc == 5)
|
||||
g_ulPacketCount = atoi(argv[4]);
|
||||
}
|
||||
|
||||
}else if(strcmp(argv[1], "stop") == 0){
|
||||
g_terminate = 1;
|
||||
}else
|
||||
goto Exit;
|
||||
|
||||
if(g_start_server && (NULL == g_server_task)){
|
||||
if(xTaskCreate(TcpServerHandler, "tcp_server", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_server_task) != pdPASS)
|
||||
printf("\n\rTCP ERROR: Create tcp server task failed.");
|
||||
}
|
||||
if(g_start_client && (NULL == g_client_task)){
|
||||
if(xTaskCreate(TcpClientHandler, "tcp_client", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_client_task) != pdPASS)
|
||||
printf("\n\rTCP ERROR: Create tcp client task failed.");
|
||||
}
|
||||
|
||||
return;
|
||||
Exit:
|
||||
printf("\n\rTCP: Tcp test command format error!");
|
||||
printf("\n\rPlease Enter: \"tcp -s\" to start tcp server or \"tcp <-c *.*.*.*> <buf len> [count]]\" to start tcp client\n\r");
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_udp(int argc, char **argv)
|
||||
{
|
||||
g_terminate = udp_start_server = udp_start_client = 0;
|
||||
g_ulPacketCount = 10000;
|
||||
if(argc == 2){
|
||||
if(strcmp(argv[1], "-s") == 0 ||strcmp(argv[1], "s") == 0){
|
||||
if(udpserver_task){
|
||||
printf("\r\nUDP: UDP Server is already running.");
|
||||
return;
|
||||
}else{
|
||||
udp_start_server = 1;
|
||||
}
|
||||
}else if(strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "c") == 0){
|
||||
if(udpcllient_task){
|
||||
printf("\r\nUDP: UDP Server is already running.");
|
||||
return;
|
||||
}else{
|
||||
udp_start_client= 1;
|
||||
}
|
||||
}else if(strcmp(argv[1], "stop") == 0){
|
||||
g_terminate = 1;
|
||||
}else
|
||||
goto Exit;
|
||||
}else if(strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "c") == 0) {
|
||||
if(udpcllient_task){
|
||||
printf("\n\nUDP: UDP client is already running. Please enter \"udp stop\" to stop it.");
|
||||
return;
|
||||
}else{
|
||||
if(argc < 4)
|
||||
goto Exit;
|
||||
udp_start_client = 1;
|
||||
strncpy(g_server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2]));
|
||||
g_cli_buf_size = atoi(argv[3]);
|
||||
if(argc == 5)
|
||||
g_ulPacketCount = atoi(argv[4]);
|
||||
}
|
||||
|
||||
}else
|
||||
goto Exit;
|
||||
|
||||
if(udp_start_server && (NULL == udpserver_task)){
|
||||
if(xTaskCreate(Udpserverhandler, "udp_server", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &udpserver_task) != pdPASS)
|
||||
printf("\r\nUDP ERROR: Create udp server task failed.");
|
||||
}
|
||||
|
||||
if(udp_start_client && (NULL == udpcllient_task)){
|
||||
if(xTaskCreate(Udpclienthandler, "udp_client", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &udpcllient_task) != pdPASS)
|
||||
printf("\r\nUDP ERROR: Create udp client task failed.");
|
||||
}
|
||||
|
||||
return;
|
||||
Exit:
|
||||
printf("\r\nUDP: udp test command format error!");
|
||||
printf("\r\nPlease Enter: \"udp -s\" to start udp server or \"udp -c to start udp client\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
362
component/common/utilities/uart_socket.c
Executable file
362
component/common/utilities/uart_socket.c
Executable file
|
|
@ -0,0 +1,362 @@
|
|||
#include "lwip/api.h"
|
||||
#include "PinNames.h"
|
||||
#include "sockets.h"
|
||||
#include "uart_socket.h"
|
||||
|
||||
#define UART_SOCKET_USE_DMA_TX 1
|
||||
/***********************************************************************
|
||||
* Macros *
|
||||
***********************************************************************/
|
||||
#define uart_printf printf
|
||||
#define uart_print_data(x, d, l) \
|
||||
do{\
|
||||
int i;\
|
||||
uart_printf("\n%s: Len=%d\n", (x), (l));\
|
||||
for(i = 0; i < (l); i++)\
|
||||
uart_printf("%02x ", (d)[i]);\
|
||||
uart_printf("\n");\
|
||||
}while(0);
|
||||
|
||||
/************************************************************************
|
||||
* extern funtions *
|
||||
************************************************************************/
|
||||
extern void lwip_selectevindicate(int fd);
|
||||
extern void lwip_setsockrcvevent(int fd, int rcvevent);
|
||||
extern int lwip_allocsocketsd();
|
||||
|
||||
/*************************************************************************
|
||||
* uart releated fuantions *
|
||||
*************************************************************************/
|
||||
static void uart_irq(uint32_t id, SerialIrq event)
|
||||
{
|
||||
uart_socket_t *u = (uart_socket_t *)id;
|
||||
|
||||
if(event == RxIrq) {
|
||||
if( u->rx_start == 0 ){
|
||||
RtlUpSemaFromISR(&u->action_sema); //up action semaphore
|
||||
u->rx_start = 1; // set this flag in uart_irq to indicate data recved
|
||||
}
|
||||
u->recv_buf[u->prxwrite++] = serial_getc(&u->sobj);
|
||||
if(u->prxwrite > (UART_RECV_BUFFER_LEN -1)){ //restart from head if reach tail
|
||||
u->prxwrite = 0;
|
||||
u->rxoverlap = 1; //set overlap indicated that overlaped
|
||||
}
|
||||
if(u->rxoverlap && (u->prxwrite + 1) > u->prxread ){
|
||||
u->prxread = u->prxwrite; //if pwrite overhead pread ,pread is always flow rwrite
|
||||
}
|
||||
u->last_update = xTaskGetTickCountFromISR(); // update tick everytime recved data
|
||||
}
|
||||
|
||||
if(event == TxIrq){
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_send_stream_done(uint32_t id)
|
||||
{
|
||||
uart_socket_t *u = (uart_socket_t *)id;
|
||||
|
||||
u->tx_start = 0;
|
||||
memset(u->send_buf,0, UART_SEND_BUFFER_LEN); //zero set uart_send_buf
|
||||
RtlUpSemaFromISR(&u->tx_sema);
|
||||
RtlUpSemaFromISR(&u->dma_tx_sema);
|
||||
}
|
||||
|
||||
static int uart_send_stream(uart_socket_t *u, char* pbuf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(!len || (!pbuf) || !u){
|
||||
uart_printf("input error,size should not be null\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if UART_SOCKET_USE_DMA_TX
|
||||
while(RtlDownSema(&u->dma_tx_sema) == pdTRUE){
|
||||
ret = serial_send_stream_dma(&u->sobj, pbuf, len);
|
||||
if(ret != HAL_OK){
|
||||
RtlUpSema(&u->dma_tx_sema);
|
||||
return -1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (len){
|
||||
serial_putc(&u->sobj, *pbuf);
|
||||
len--;
|
||||
pbuf++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 uart_wait_rx_complete(uart_socket_t *u)
|
||||
{
|
||||
s32 tick_current = xTaskGetTickCount();
|
||||
|
||||
while((tick_current -u->last_update) < UART_MAX_DELAY_TIME ){
|
||||
vTaskDelay(5);
|
||||
tick_current = xTaskGetTickCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uart_action_handler(void* param)
|
||||
{
|
||||
uart_socket_t *u = (uart_socket_t*)param;
|
||||
if(!u)
|
||||
goto Exit;
|
||||
|
||||
while(RtlDownSema(&u->action_sema) == pdTRUE) {
|
||||
if(u->fd == -1)
|
||||
goto Exit;
|
||||
if(u->rx_start){
|
||||
/* Blocked here to wait uart rx data completed */
|
||||
uart_wait_rx_complete(u);
|
||||
|
||||
/* As we did not register netconn callback function.,so call lwip_selectevindicate unblocking select */
|
||||
lwip_setsockrcvevent(u->fd, 1);
|
||||
lwip_selectevindicate(u->fd); //unblocking select()
|
||||
u->rx_start = 0;
|
||||
}
|
||||
if(u->tx_start){
|
||||
uart_print_data("TX:", u->send_buf, u->tx_bytes);
|
||||
//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 {
|
||||
#if (UART_SOCKET_USE_DMA_TX == 0)
|
||||
u->tx_start = 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 512
|
||||
#define UART_ACTION_PRIORITY 1
|
||||
if(xTaskCreate(uart_action_handler, ((const char*)"uart_action"), UART_ACTION_STACKSIZE, u, UART_ACTION_PRIORITY, NULL) != pdPASS){
|
||||
uart_printf("%s xTaskCreate(uart_action) failed", __FUNCTION__);
|
||||
goto Exit1;
|
||||
}
|
||||
}
|
||||
return u;
|
||||
Exit1:
|
||||
/* Free uart related semaphore */
|
||||
RtlFreeSema(&u->action_sema);
|
||||
RtlFreeSema(&u->tx_sema);
|
||||
RtlFreeSema(&u->dma_tx_sema);
|
||||
Exit2:
|
||||
RtlMfree((u8*)u, sizeof(uart_socket_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uart_close(uart_socket_t *u)
|
||||
{
|
||||
if(!u){
|
||||
uart_printf("uart_close(): u is NULL!\r\n");
|
||||
return -1;
|
||||
}
|
||||
/* Close uart socket */
|
||||
if(lwip_close(u->fd) == -1){
|
||||
uart_printf("%s(): close uart failed!", __func__);
|
||||
}
|
||||
/* Delete uart_action task */
|
||||
u->fd = -1;
|
||||
RtlUpSema(&u->action_sema);
|
||||
RtlMsleepOS(20);
|
||||
|
||||
/* Free uart related semaphore */
|
||||
RtlFreeSema(&u->action_sema);
|
||||
RtlFreeSema(&u->tx_sema);
|
||||
RtlFreeSema(&u->dma_tx_sema);
|
||||
|
||||
/* Free serial */
|
||||
serial_free(&u->sobj);
|
||||
|
||||
RtlMfree((u8 *)u, sizeof(uart_socket_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uart_read(uart_socket_t *u, void *read_buf, size_t size)
|
||||
{
|
||||
/*the same as socket*/
|
||||
int read_bytes = 0;
|
||||
int pread_local,pwrite_local;
|
||||
char *ptr = (char *)read_buf;
|
||||
|
||||
uart_printf("==>uart_read()\n");
|
||||
if(!size || !read_buf || !u){
|
||||
uart_printf("uart_read(): input error,size should not be null\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pread_local = u->prxread;
|
||||
pwrite_local = u->prxwrite;
|
||||
/*calculate how much data not read */
|
||||
if(!u->rxoverlap){
|
||||
read_bytes = pwrite_local - pread_local;
|
||||
} else {
|
||||
read_bytes = (UART_RECV_BUFFER_LEN - pread_local) + pwrite_local;
|
||||
}
|
||||
/*decide how much data shoule copy to application*/
|
||||
if(size < read_bytes)
|
||||
read_bytes = size;
|
||||
|
||||
if(!u->rxoverlap){
|
||||
memcpy(ptr, (u->recv_buf+ pread_local), read_bytes );
|
||||
} else {
|
||||
uart_printf("uart recv buf is write through!!\n");
|
||||
if((pread_local + read_bytes) > UART_RECV_BUFFER_LEN){
|
||||
memcpy(ptr,(u->recv_buf+ pread_local), (UART_RECV_BUFFER_LEN-pread_local));
|
||||
memcpy(ptr+(UART_RECV_BUFFER_LEN-pread_local), u->recv_buf, read_bytes-(UART_RECV_BUFFER_LEN- pread_local));
|
||||
} else
|
||||
memcpy(ptr,(u->recv_buf+ pread_local), read_bytes);
|
||||
}
|
||||
lwip_setsockrcvevent(u->fd, 0);
|
||||
|
||||
if((pread_local + read_bytes) >= UART_RECV_BUFFER_LEN){ //update pread
|
||||
u->prxread = (pread_local + read_bytes) - UART_RECV_BUFFER_LEN;
|
||||
u->rxoverlap = 0; //clean overlap flags
|
||||
} else
|
||||
u->prxread = pread_local + read_bytes;
|
||||
|
||||
return read_bytes;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int uart_write(uart_socket_t *u, void *pbuf, size_t size)
|
||||
{
|
||||
if(!size || !pbuf || !u){
|
||||
uart_printf("input error,please check!");
|
||||
return -1;
|
||||
}
|
||||
if(RtlDownSema(&u->tx_sema)){
|
||||
//uart_printf("[%d]:uart_write %d!\n", xTaskGetTickCount(), size);
|
||||
memcpy(u->send_buf, pbuf, size);
|
||||
u->tx_bytes = size;
|
||||
u->tx_start = 1; //set uart tx start
|
||||
RtlUpSema(&u->action_sema); // let uart_handle_run through
|
||||
} else {
|
||||
uart_printf("uart write buf error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void uart_socket_example(void *param)
|
||||
{
|
||||
char tx_data[] = {0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
uart_set_str uartset;
|
||||
struct timeval tv;
|
||||
fd_set readfds;
|
||||
int read_len = 0, count = 0;
|
||||
int ret = 0;
|
||||
char rxbuf[512];
|
||||
int uart_fd;
|
||||
uart_socket_t *uart_socket = NULL;
|
||||
|
||||
uartset.BaudRate = 9600;
|
||||
uartset.number = 8;
|
||||
uartset.StopBits = 0;
|
||||
uartset.FlowControl = 0;
|
||||
uartset.parity = 0;
|
||||
strcpy(uartset.UartName, "uart0");
|
||||
|
||||
uart_socket = uart_open(&uartset);
|
||||
if(uart_socket == NULL){
|
||||
uart_printf("Init uart socket failed!\n");
|
||||
goto Exit;
|
||||
}
|
||||
uart_fd = uart_socket->fd;
|
||||
uart_printf("\nOpen uart socket: %d\n", uart_fd);
|
||||
while(1)
|
||||
{
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(uart_fd, &readfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 20000;
|
||||
if(count++ == 50){
|
||||
uart_write(uart_socket, tx_data, sizeof(tx_data));
|
||||
//uart_print_data("TX:", tx_data, sizeof(tx_data));
|
||||
count = 0;
|
||||
}
|
||||
ret = select(uart_fd + 1, &readfds, NULL, NULL, &tv);
|
||||
//uart_printf("[%d] select ret = %x count=%d\n", xTaskGetTickCount(), ret, count);
|
||||
if(ret > 0)
|
||||
{
|
||||
if(FD_ISSET(uart_fd, &readfds))
|
||||
{
|
||||
read_len = uart_read(uart_socket, rxbuf, sizeof(rxbuf));
|
||||
if(read_len > 0)
|
||||
{
|
||||
uart_print_data("RX:", rxbuf, read_len);
|
||||
if(rtl_strncmp(rxbuf, "close", 5) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
//else for other sockets
|
||||
}
|
||||
}
|
||||
uart_printf("Exit uart socket example!\n");
|
||||
uart_close(uart_socket);
|
||||
Exit:
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void uart_socket()
|
||||
{
|
||||
#define UART_SOCKET_STACK_SIZE 512
|
||||
#define UART_SOCKET_PRIORITY 1
|
||||
if(xTaskCreate(uart_socket_example, "uart_socket", UART_SOCKET_STACK_SIZE, NULL, UART_SOCKET_PRIORITY, NULL) != pdPASS)
|
||||
uart_printf("%s xTaskCreate failed", __FUNCTION__);
|
||||
}
|
||||
|
||||
50
component/common/utilities/uart_socket.h
Executable file
50
component/common/utilities/uart_socket.h
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef __UART_SOCKET_H_
|
||||
#define __UART_SOCKET_H_
|
||||
|
||||
#include "osdep_api.h"
|
||||
#include "serial_api.h"
|
||||
#include "serial_ex_api.h"
|
||||
|
||||
#define UART_SEND_BUFFER_LEN 256
|
||||
#define UART_RECV_BUFFER_LEN 1024
|
||||
#define UART_MAX_DELAY_TIME 20
|
||||
|
||||
typedef struct _uart_set_str
|
||||
{
|
||||
char UartName[8]; // the name of uart
|
||||
int BaudRate; //The baud rate
|
||||
char number; //The number of data bits
|
||||
char parity; //The parity(default NONE)
|
||||
char StopBits; //The number of stop bits
|
||||
char FlowControl; //support flow control is 1
|
||||
}uart_set_str;
|
||||
|
||||
typedef struct _uart_socket_t
|
||||
{
|
||||
serial_t sobj;
|
||||
int fd;
|
||||
|
||||
/* Used for UART RX */
|
||||
u32 rx_start;
|
||||
//u32 rx_bytes;
|
||||
u32 prxread;
|
||||
u32 prxwrite;
|
||||
u32 rxoverlap;
|
||||
u32 last_update; //tick count when rx byte
|
||||
u8 recv_buf[UART_RECV_BUFFER_LEN];
|
||||
|
||||
u32 tx_start;
|
||||
u32 tx_bytes;
|
||||
u8 send_buf[UART_SEND_BUFFER_LEN];
|
||||
_Sema tx_sema;
|
||||
_Sema dma_tx_sema;
|
||||
|
||||
_Sema action_sema;
|
||||
}uart_socket_t;
|
||||
|
||||
uart_socket_t* uart_open(uart_set_str *puartpara);
|
||||
int uart_close(uart_socket_t *u);
|
||||
int uart_read(uart_socket_t *u, void *read_buf, size_t size);
|
||||
int uart_write(uart_socket_t *u, void *pbuf, size_t size);
|
||||
|
||||
#endif //__UART_SOCKET_H_
|
||||
92
component/common/utilities/udpecho.c
Executable file
92
component/common/utilities/udpecho.c
Executable file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_NETCONN
|
||||
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
|
||||
#define UDPECHO_THREAD_PRIO ( tskIDLE_PRIORITY + 3 )
|
||||
|
||||
static struct netconn *conn;
|
||||
static struct netbuf *buf;
|
||||
static struct ip_addr *addr;
|
||||
static unsigned short port;
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void udpecho_thread(void *arg)
|
||||
{
|
||||
err_t err;
|
||||
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
|
||||
conn = netconn_new(NETCONN_UDP);
|
||||
if (conn!= NULL)
|
||||
{
|
||||
err = netconn_bind(conn, IP_ADDR_ANY, 7);
|
||||
if (err == ERR_OK)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
buf = netconn_recv(conn);
|
||||
|
||||
if (buf!= NULL)
|
||||
{
|
||||
addr = netbuf_fromaddr(buf);
|
||||
port = netbuf_fromport(buf);
|
||||
netconn_connect(conn, addr, port);
|
||||
buf->addr = NULL;
|
||||
netconn_send(conn,buf);
|
||||
netbuf_delete(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("can not bind netconn");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("can create new UDP netconn");
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void udpecho_init(void)
|
||||
{
|
||||
sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE,UDPECHO_THREAD_PRIO );
|
||||
}
|
||||
|
||||
#endif /* LWIP_NETCONN */
|
||||
1001
component/common/utilities/update.c
Executable file
1001
component/common/utilities/update.c
Executable file
File diff suppressed because it is too large
Load diff
10
component/common/utilities/update.h
Executable file
10
component/common/utilities/update.h
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#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);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#endif
|
||||
977
component/common/utilities/webserver.c
Executable file
977
component/common/utilities/webserver.c
Executable file
|
|
@ -0,0 +1,977 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Implements a simplistic WEB server. Every time a connection is made and
|
||||
data is received a dynamic page that shows the current TCP/IP statistics
|
||||
is generated and returned. The connection is then closed.
|
||||
|
||||
This file was adapted from a FreeRTOS lwIP slip demo supplied by a third
|
||||
party.
|
||||
*/
|
||||
|
||||
/* ------------------------ System includes ------------------------------- */
|
||||
|
||||
|
||||
/* ------------------------ FreeRTOS includes ----------------------------- */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* ------------------------ lwIP includes --------------------------------- */
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "netif/loopif.h"
|
||||
|
||||
/* ------------------------ Project includes ------------------------------ */
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
|
||||
#include "webserver.h"
|
||||
#include "wlan_intf.h"
|
||||
|
||||
|
||||
#define CONFIG_READ_FLASH 1
|
||||
|
||||
|
||||
#ifdef CONFIG_READ_FLASH
|
||||
|
||||
#ifndef CONFIG_PLATFORM_8195A
|
||||
|
||||
#include <flash/stm32_flash.h>
|
||||
#if defined(STM32F2XX)
|
||||
#include <stm32f2xx_flash.h>
|
||||
#elif defined(STM32F4XX)
|
||||
#include <stm32f4xx_flash.h>
|
||||
#elif defined(STM32f1xx)
|
||||
#include <stm32f10x_flash.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "flash_api.h"
|
||||
#define DATA_SECTOR (0x000FE000)
|
||||
#define BACKUP_SECTOR (0x00008000)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/* ------------------------ Defines --------------------------------------- */
|
||||
/* The size of the buffer in which the dynamic WEB page is created. */
|
||||
#define webMAX_PAGE_SIZE ( 2800 ) /*FSL: buffer containing array*/
|
||||
#define LOCAL_BUF_SIZE 800
|
||||
#define AP_SETTING_ADDR 0x000FE000;
|
||||
/* Standard GET response. */
|
||||
#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
|
||||
|
||||
/* The port on which we listen. */
|
||||
#define webHTTP_PORT ( 80 )
|
||||
|
||||
/* Delay on close error. */
|
||||
#define webSHORT_DELAY ( 10 )
|
||||
|
||||
|
||||
/* Format of the dynamic page that is returned on each connection. */
|
||||
#define webHTML_HEAD_START \
|
||||
"<html>\
|
||||
<head>\
|
||||
"
|
||||
/*
|
||||
<meta http-equiv=\"Content-Type\" content=\"text/html;charset=gb2312>\
|
||||
<meta http-equiv=\"Cache-Control\" CONTENT=\"no-cache\">\
|
||||
<meta http-equiv=\"Expires\" CONTENT=\"0\">\
|
||||
*/
|
||||
|
||||
#define webHTML_BODY_START \
|
||||
"</head>\
|
||||
<BODY onLoad=\"onChangeSecType()\">\
|
||||
\r\n\r\n<form name=\"form\" method=\"post\" onsubmit=\"return onSubmitForm()\">\
|
||||
<table width=\"500\">\
|
||||
<tr>\
|
||||
<td colspan=\"2\" style=\"background-color:#FFA500;text-align:center;\">\
|
||||
<h2>Realtek SoftAP Configuration</h2>\
|
||||
</td>\
|
||||
</tr>"
|
||||
|
||||
#define webHTML_END \
|
||||
"<tr>\
|
||||
<td colspan=\"2\" style=\"background-color:#FFD700;text-align:center;height:40px\">\
|
||||
<input type=\"submit\" value=\"Submit\"><br></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td colspan=\"2\" style=\"background-color:#FFA500;text-align:center;\">\
|
||||
Copyright ?realtek.com</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
\r\n</form>" \
|
||||
"</BODY>\r\n" \
|
||||
"</html>"
|
||||
|
||||
#define webWaitHTML_START \
|
||||
"<html location.href='wait.html'>\
|
||||
<head>\
|
||||
"
|
||||
#define webWaitHTML_END \
|
||||
"</head>\
|
||||
<BODY>\
|
||||
<p>\
|
||||
<h2>SoftAP is now restarting!</h2>\
|
||||
<h2>Please wait a moment and reconnect!</h2>\
|
||||
</p>"\
|
||||
"</BODY>\r\n" \
|
||||
"</html>"
|
||||
|
||||
#define onChangeSecType \
|
||||
"<script>\
|
||||
function onChangeSecType()\
|
||||
{\
|
||||
x=document.getElementById(\"sec\");\
|
||||
y=document.getElementById(\"pwd_row\");\
|
||||
if(x.value == \"open\"){\
|
||||
y.style.display=\"none\";\
|
||||
}else{\
|
||||
y.style.display=\"block\";\
|
||||
}\
|
||||
}\
|
||||
</script>"
|
||||
|
||||
#define onSubmitForm \
|
||||
"<script>\
|
||||
function onSubmitForm()\
|
||||
{\
|
||||
x=document.getElementById(\"Ssid\");\
|
||||
y=document.getElementById(\"pwd_row\");\
|
||||
z=document.getElementById(\"pwd\");\
|
||||
if(x.value.length>32)\
|
||||
{\
|
||||
alert(\"SoftAP SSID is too long!(1-32)\");\
|
||||
return false;\
|
||||
}\
|
||||
if(!(/^[A-Za-z0-9]+$/.test(x.value)))\
|
||||
{\
|
||||
alert(\"SoftAP SSID can only be [A-Za-z0-9]\");\
|
||||
return false;\
|
||||
}\
|
||||
if(y.style.display == \"block\")\
|
||||
{\
|
||||
if((z.value.length < 8)||(z.value.length>32))\
|
||||
{\
|
||||
alert(\"Password length is between 8 to 32\");\
|
||||
return false;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
</script>"
|
||||
|
||||
/*
|
||||
alert(\"Please enter your password!\");\
|
||||
return false;\
|
||||
}\
|
||||
if(z.value.length < 8)\
|
||||
{\
|
||||
alert(\"Your password is too short!(8-32)\");\
|
||||
return false;\
|
||||
}\
|
||||
if(z.value.length>32)\
|
||||
{\
|
||||
alert(\"Your password is too long!(8-32)\");\
|
||||
*/
|
||||
|
||||
#define MAX_SOFTAP_SSID_LEN 32
|
||||
#define MAX_PASSWORD_LEN 32
|
||||
#define MAX_CHANNEL_NUM 13
|
||||
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark
|
||||
static volatile unsigned portBASE_TYPE uxHighWaterMark_web = 0;
|
||||
#endif
|
||||
|
||||
/* ------------------------ Prototypes ------------------------------------ */
|
||||
static void vProcessConnection( struct netconn *pxNetCon );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* GLOBALS */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
rtw_wifi_setting_t wifi_setting = {RTW_MODE_NONE, {0}, 0, RTW_SECURITY_OPEN, {0}};
|
||||
|
||||
#ifndef WLAN0_NAME
|
||||
#define WLAN0_NAME "wlan0"
|
||||
#endif
|
||||
|
||||
#ifndef WLAN1_NAME
|
||||
#define WLAN1_NAME "wlan1"
|
||||
#endif
|
||||
|
||||
static void LoadWifiSetting()
|
||||
{
|
||||
const char *ifname = WLAN0_NAME;
|
||||
|
||||
if(rltk_wlan_running(WLAN1_IDX))
|
||||
{//STA_AP_MODE
|
||||
ifname = WLAN1_NAME;
|
||||
}
|
||||
|
||||
wifi_get_setting(ifname, &wifi_setting);
|
||||
|
||||
//printf("\r\nLoadWifiSetting(): wifi_setting.ssid=%s\n", wifi_setting.ssid);
|
||||
//printf("\r\nLoadWifiSetting(): wifi_setting.channel=%d\n", wifi_setting.channel);
|
||||
//printf("\r\nLoadWifiSetting(): wifi_setting.security_type=%d\n", wifi_setting.security_type);
|
||||
//printf("\r\nLoadWifiSetting(): wifi_setting.password=%s\n", wifi_setting.password);
|
||||
}
|
||||
|
||||
#if CONFIG_READ_FLASH
|
||||
#ifndef CONFIG_PLATFORM_8195A
|
||||
void LoadWifiConfig()
|
||||
{
|
||||
rtw_wifi_config_t local_config;
|
||||
uint32_t address;
|
||||
#ifdef STM32F10X_XL
|
||||
address = 0x08080000; //bank2 domain
|
||||
#else
|
||||
uint16_t sector_nb = FLASH_Sector_11;
|
||||
address = flash_SectorAddress(sector_nb);
|
||||
#endif
|
||||
printf("\r\nLoadWifiConfig(): Read from FLASH!\n");
|
||||
flash_Read(address, (char *)&local_config, sizeof(local_config));
|
||||
|
||||
printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode);
|
||||
printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid);
|
||||
printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel);
|
||||
printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type);
|
||||
printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password);
|
||||
|
||||
if(local_config.boot_mode == 0x77665502)
|
||||
{
|
||||
wifi_setting.mode = RTW_MODE_AP;
|
||||
if(local_config.ssid_len > 32)
|
||||
local_config.ssid_len = 32;
|
||||
memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len);
|
||||
wifi_setting.ssid[local_config.ssid_len] = '\0';
|
||||
wifi_setting.channel = local_config.channel;
|
||||
wifi_setting.security_type = local_config.security_type;
|
||||
if(local_config.password_len > 32)
|
||||
local_config.password_len = 32;
|
||||
memcpy(wifi_setting.password, local_config.password, local_config.password_len);
|
||||
wifi_setting.password[local_config.password_len] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadWifiSetting();
|
||||
}
|
||||
}
|
||||
|
||||
int StoreApInfo()
|
||||
{
|
||||
rtw_wifi_config_t wifi_config;
|
||||
uint32_t address;
|
||||
#ifdef STM32F10X_XL
|
||||
address = 0x08080000; //bank2 domain
|
||||
#else
|
||||
uint16_t sector_nb = FLASH_Sector_11;
|
||||
address = flash_SectorAddress(sector_nb);
|
||||
#endif
|
||||
wifi_config.boot_mode = 0x77665502;
|
||||
memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
||||
wifi_config.ssid_len = strlen((char*)wifi_setting.ssid);
|
||||
wifi_config.security_type = wifi_setting.security_type;
|
||||
memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password));
|
||||
wifi_config.password_len= strlen((char*)wifi_setting.password);
|
||||
wifi_config.channel = wifi_setting.channel;
|
||||
|
||||
printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ...");
|
||||
#ifdef STM32F10X_XL
|
||||
FLASH_ErasePage(address);
|
||||
#else
|
||||
flash_EraseSector(sector_nb);
|
||||
#endif
|
||||
flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
void LoadWifiConfig()
|
||||
{
|
||||
|
||||
|
||||
flash_t flash;
|
||||
|
||||
rtw_wifi_config_t local_config;
|
||||
uint32_t address;
|
||||
|
||||
address = DATA_SECTOR;
|
||||
|
||||
|
||||
//memset(&local_config,0,sizeof(rtw_wifi_config_t));
|
||||
printf("\r\nLoadWifiConfig(): Read from FLASH!\n");
|
||||
// flash_Read(address, &local_config, sizeof(local_config));
|
||||
|
||||
flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),(uint8_t *)(&local_config));
|
||||
|
||||
|
||||
printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode);
|
||||
printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid);
|
||||
printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel);
|
||||
printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type);
|
||||
printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password);
|
||||
|
||||
if(local_config.boot_mode == 0x77665502)
|
||||
{
|
||||
wifi_setting.mode = RTW_MODE_AP;
|
||||
if(local_config.ssid_len > 32)
|
||||
local_config.ssid_len = 32;
|
||||
memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len);
|
||||
wifi_setting.ssid[local_config.ssid_len] = '\0';
|
||||
wifi_setting.channel = local_config.channel;
|
||||
if(local_config.security_type == 1)
|
||||
wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
||||
else
|
||||
wifi_setting.security_type = RTW_SECURITY_OPEN;
|
||||
if(local_config.password_len > 32)
|
||||
local_config.password_len = 32;
|
||||
memcpy(wifi_setting.password, local_config.password, local_config.password_len);
|
||||
wifi_setting.password[local_config.password_len] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadWifiSetting();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int StoreApInfo()
|
||||
{
|
||||
|
||||
flash_t flash;
|
||||
|
||||
rtw_wifi_config_t wifi_config;
|
||||
uint32_t address;
|
||||
uint32_t data,i = 0;
|
||||
|
||||
|
||||
address = DATA_SECTOR;
|
||||
|
||||
wifi_config.boot_mode = 0x77665502;
|
||||
memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
||||
wifi_config.ssid_len = strlen((char*)wifi_setting.ssid);
|
||||
wifi_config.security_type = wifi_setting.security_type;
|
||||
if(wifi_setting.security_type !=0)
|
||||
wifi_config.security_type = 1;
|
||||
else
|
||||
wifi_config.security_type = 0;
|
||||
memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password));
|
||||
wifi_config.password_len= strlen((char*)wifi_setting.password);
|
||||
wifi_config.channel = wifi_setting.channel;
|
||||
printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ...");
|
||||
//printf("\n\r &wifi_config = 0x%x",&wifi_config);
|
||||
|
||||
flash_read_word(&flash,address,&data);
|
||||
|
||||
|
||||
if(data == ~0x0)
|
||||
|
||||
flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);
|
||||
|
||||
else{
|
||||
//flash_EraseSector(sector_nb);
|
||||
|
||||
|
||||
flash_erase_sector(&flash,BACKUP_SECTOR);
|
||||
for(i = 0; i < 0x1000; i+= 4){
|
||||
flash_read_word(&flash, DATA_SECTOR + i, &data);
|
||||
if(i < sizeof(rtw_wifi_config_t))
|
||||
{
|
||||
memcpy(&data,(char *)(&wifi_config) + i,4);
|
||||
//printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i));
|
||||
//printf("\n\r Data = %d",data);
|
||||
}
|
||||
flash_write_word(&flash, BACKUP_SECTOR + i,data);
|
||||
}
|
||||
flash_read_word(&flash,BACKUP_SECTOR + 68,&data);
|
||||
//printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data);
|
||||
//erase system data
|
||||
flash_erase_sector(&flash, DATA_SECTOR);
|
||||
//write data back to system data
|
||||
for(i = 0; i < 0x1000; i+= 4){
|
||||
flash_read_word(&flash, BACKUP_SECTOR + i, &data);
|
||||
flash_write_word(&flash, DATA_SECTOR + i,data);
|
||||
}
|
||||
//erase backup sector
|
||||
flash_erase_sector(&flash, BACKUP_SECTOR);
|
||||
}
|
||||
|
||||
//flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t));
|
||||
//flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);
|
||||
//flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
|
||||
//flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
|
||||
//printf("\n\r Base + 0x000FF000 +4 wifi config = %s",data[4]);
|
||||
//printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static void RestartSoftAP()
|
||||
{
|
||||
//printf("\r\nRestartAP: ssid=%s", wifi_setting.ssid);
|
||||
//printf("\r\nRestartAP: ssid_len=%d", strlen((char*)wifi_setting.ssid));
|
||||
//printf("\r\nRestartAP: security_type=%d", wifi_setting.security_type);
|
||||
//printf("\r\nRestartAP: password=%s", wifi_setting.password);
|
||||
//printf("\r\nRestartAP: password_len=%d", strlen((char*)wifi_setting.password));
|
||||
//printf("\r\nRestartAP: channel=%d\n", wifi_setting.channel);
|
||||
wifi_restart_ap(wifi_setting.ssid,
|
||||
wifi_setting.security_type,
|
||||
wifi_setting.password,
|
||||
strlen((char*)wifi_setting.ssid),
|
||||
strlen((char*)wifi_setting.password),
|
||||
wifi_setting.channel);
|
||||
}
|
||||
|
||||
|
||||
u32 web_atoi(char* s)
|
||||
{
|
||||
int num=0,flag=0;
|
||||
int i;
|
||||
|
||||
for(i=0;i<=strlen(s);i++)
|
||||
{
|
||||
if(s[i] >= '0' && s[i] <= '9')
|
||||
num = num * 10 + s[i] -'0';
|
||||
else if(s[0] == '-' && i==0)
|
||||
flag =1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(flag == 1)
|
||||
num = num * -1;
|
||||
|
||||
return(num);
|
||||
}
|
||||
|
||||
static void CreateSsidTableItem(char *pbuf, u8_t *ssid, u8_t ssid_len)
|
||||
{
|
||||
char local_ssid[MAX_SOFTAP_SSID_LEN+1];
|
||||
|
||||
if(ssid_len > MAX_SOFTAP_SSID_LEN)
|
||||
ssid_len = MAX_SOFTAP_SSID_LEN;
|
||||
memcpy(local_ssid, ssid, ssid_len);
|
||||
local_ssid[ssid_len] = '\0';
|
||||
sprintf(pbuf, "<tr>"
|
||||
"<td style=\"background-color:#FFD700;width:100px;\">"
|
||||
"<b>SoftAP SSID:</b><br>"
|
||||
"</td>"
|
||||
"<td style=\"background-color:#eeeeee;height:30px;width:400px;\">"
|
||||
"<input type=\"text\" name=\"Ssid\" id=\"Ssid\" value=\"%s\"><br>"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
local_ssid);
|
||||
//printf("\r\nstrlen(SsidTableItem)=%d\n", strlen(pbuf));
|
||||
}
|
||||
|
||||
static void CreateSecTypeTableItem(char *pbuf, u32_t sectype)
|
||||
{
|
||||
u8_t flag[2] = {0, 0};
|
||||
|
||||
if(sectype == RTW_SECURITY_OPEN)
|
||||
flag[0] = 1;
|
||||
else if(sectype == RTW_SECURITY_WPA2_AES_PSK)
|
||||
flag[1] = 1;
|
||||
else
|
||||
return;
|
||||
|
||||
sprintf(pbuf, "<tr>"
|
||||
"<td style=\"background-color:#FFD700;width:100px;\">"
|
||||
"<b>Security Type:</b><br>"
|
||||
"</td>"
|
||||
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
||||
"<select name=\"Security Type\" id=\"sec\" onChange=onChangeSecType()>"
|
||||
"<option value=\"open\" %s>OPEN</option>"
|
||||
"<option value=\"wpa2-aes\" %s>WPA2-AES</option>"
|
||||
"</select>"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
flag[0]?"selected":"",
|
||||
flag[1]?"selected":"");
|
||||
//printf("\r\nstrlen(SecTypeTableItem)=%d\n", strlen(pbuf));
|
||||
}
|
||||
|
||||
static void CreatePasswdTableItem(char *pbuf, u8_t *password, u8_t passwd_len)
|
||||
{
|
||||
char local_passwd[MAX_PASSWORD_LEN+1];
|
||||
|
||||
if(passwd_len > MAX_PASSWORD_LEN)
|
||||
passwd_len = MAX_PASSWORD_LEN;
|
||||
if(passwd_len > 0)
|
||||
{
|
||||
memcpy(local_passwd, password, passwd_len);
|
||||
local_passwd[passwd_len] = '\0';
|
||||
}
|
||||
sprintf(pbuf, "<tr id=\"pwd_row\">"
|
||||
"<td style=\"background-color:#FFD700;width:100px;\">"
|
||||
"<b>Password:</b><br>"
|
||||
"</td>"
|
||||
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
||||
"<input type=\"text\" name=\"Password\" id=\"pwd\" value=\"%s\" ><br>"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
passwd_len?local_passwd:"");
|
||||
//printf("\r\nstrlen(passwordTableItem)=%d\n", strlen(pbuf));
|
||||
}
|
||||
|
||||
static void CreateChannelTableItem(char *pbuf, u8_t channel)
|
||||
{
|
||||
u8_t flag[MAX_CHANNEL_NUM+1] = {0};
|
||||
|
||||
if(channel > MAX_CHANNEL_NUM){
|
||||
printf("Channel(%d) is out of range!\n", channel);
|
||||
channel = 1;
|
||||
}
|
||||
flag[channel] = 1;
|
||||
|
||||
sprintf(pbuf, "<tr>"
|
||||
"<td style=\"background-color:#FFD700;width:100px;\">"
|
||||
"<b>Channel:</b><br>"
|
||||
"</td>"
|
||||
"<td style=\"background-color:#eeeeee;height:30px;\">"
|
||||
"<select name=\"Channel\">"
|
||||
"<option value=\"1\" %s>1</option>"
|
||||
"<option value=\"2\" %s>2</option>"
|
||||
"<option value=\"3\" %s>3</option>"
|
||||
"<option value=\"4\" %s>4</option>"
|
||||
"<option value=\"5\" %s>5</option>"
|
||||
"<option value=\"6\" %s>6</option>"
|
||||
"<option value=\"7\" %s>7</option>"
|
||||
"<option value=\"8\" %s>8</option>"
|
||||
"<option value=\"9\" %s>9</option>"
|
||||
"<option value=\"10\" %s>10</option>"
|
||||
"<option value=\"11\" %s>11</option>"
|
||||
"</select>"
|
||||
"</td>"
|
||||
"</tr>",
|
||||
flag[1]?"selected":"",
|
||||
flag[2]?"selected":"",
|
||||
flag[3]?"selected":"",
|
||||
flag[4]?"selected":"",
|
||||
flag[5]?"selected":"",
|
||||
flag[6]?"selected":"",
|
||||
flag[7]?"selected":"",
|
||||
flag[8]?"selected":"",
|
||||
flag[9]?"selected":"",
|
||||
flag[10]?"selected":"",
|
||||
flag[11]?"selected":"");
|
||||
//printf("\r\nstrlen(ChannelTableItem)=%d\n", strlen(pbuf));
|
||||
}
|
||||
|
||||
static void GenerateIndexHtmlPage(portCHAR* cDynamicPage, portCHAR *LocalBuf)
|
||||
{
|
||||
/* Generate the page index.html...
|
||||
... First the page header. */
|
||||
strcpy( cDynamicPage, webHTML_HEAD_START );
|
||||
|
||||
/* Add script */
|
||||
strcat( cDynamicPage, onChangeSecType );
|
||||
strcat( cDynamicPage, onSubmitForm);
|
||||
|
||||
/* Add Body start */
|
||||
strcat( cDynamicPage, webHTML_BODY_START );
|
||||
|
||||
/* Add SSID */
|
||||
CreateSsidTableItem(LocalBuf, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
|
||||
strcat( cDynamicPage, LocalBuf );
|
||||
|
||||
/* Add SECURITY TYPE */
|
||||
CreateSecTypeTableItem(LocalBuf, wifi_setting.security_type);
|
||||
strcat( cDynamicPage, LocalBuf );
|
||||
|
||||
/* Add PASSWORD */
|
||||
CreatePasswdTableItem(LocalBuf, wifi_setting.password, strlen((char*)wifi_setting.password));
|
||||
strcat( cDynamicPage, LocalBuf );
|
||||
|
||||
/* Add CHANNEL */
|
||||
CreateChannelTableItem(LocalBuf, wifi_setting.channel);
|
||||
strcat( cDynamicPage, LocalBuf );
|
||||
|
||||
/* ... Finally the page footer. */
|
||||
strcat( cDynamicPage, webHTML_END );
|
||||
//printf("\r\nGenerateIndexHtmlPage(): %s\n", cDynamicPage);
|
||||
printf("\r\nGenerateIndexHtmlPage Len: %d\n", strlen( cDynamicPage ));
|
||||
}
|
||||
|
||||
static void GenerateWaitHtmlPage(portCHAR* cDynamicPage)
|
||||
{
|
||||
/* Generate the dynamic page...
|
||||
... First the page header. */
|
||||
strcpy( cDynamicPage, webWaitHTML_START );
|
||||
|
||||
/* ... Finally the page footer. */
|
||||
strcat( cDynamicPage, webWaitHTML_END);
|
||||
|
||||
//printf("\r\nGenerateWaitHtmlPage(): %s\n", cDynamicPage);
|
||||
//printf("\r\nGenerateWaitHtmlPage Len: %d\n", strlen( cDynamicPage ));
|
||||
}
|
||||
|
||||
static u8_t ProcessPostMessage(struct netbuf *pxRxBuffer, portCHAR *LocalBuf)
|
||||
{
|
||||
struct pbuf *p;
|
||||
portCHAR *pcRxString, *ptr;
|
||||
unsigned portSHORT usLength;
|
||||
u8_t bChanged = 0;
|
||||
rtw_security_t secType;
|
||||
u8_t channel;
|
||||
u8_t len = 0;
|
||||
|
||||
pcRxString = LocalBuf;
|
||||
p = pxRxBuffer->p;
|
||||
usLength = p->tot_len;
|
||||
//printf("\r\n !!!!!!!!!POST!p->tot_len =%d p->len=%d\n", p->tot_len, p->len);
|
||||
while(p)
|
||||
{
|
||||
memcpy(pcRxString, p->payload, p->len);
|
||||
pcRxString += p->len;
|
||||
p = p->next;
|
||||
}
|
||||
pcRxString = LocalBuf;
|
||||
pcRxString[usLength] = '\0';
|
||||
//printf("\r\n usLength=%d pcRxString = %s\n", usLength, pcRxString);
|
||||
|
||||
ptr = (char*)strstr(pcRxString, "Ssid=");
|
||||
if(ptr)
|
||||
{
|
||||
pcRxString = (char*)strstr(ptr, "&");
|
||||
*pcRxString++ = '\0';
|
||||
ptr += 5;
|
||||
if(strcmp((char*)wifi_setting.ssid, ptr))
|
||||
{
|
||||
bChanged = 1;
|
||||
len = strlen(ptr);
|
||||
if(len > MAX_SOFTAP_SSID_LEN){
|
||||
len = MAX_SOFTAP_SSID_LEN;
|
||||
ptr[len] = '\0';
|
||||
}
|
||||
strcpy((char*)wifi_setting.ssid, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("\r\n wifi_config.ssid = %s\n", wifi_setting.ssid);
|
||||
ptr = (char*)strstr(pcRxString, "Security+Type=");
|
||||
if(ptr)
|
||||
{
|
||||
pcRxString = (char*)strstr(ptr, "&");
|
||||
*pcRxString++ = '\0';
|
||||
ptr += 14;
|
||||
if(!strcmp(ptr, "open"))
|
||||
secType = RTW_SECURITY_OPEN;
|
||||
else if(!strcmp(ptr, "wpa2-aes"))
|
||||
secType = RTW_SECURITY_WPA2_AES_PSK;
|
||||
else
|
||||
secType = RTW_SECURITY_OPEN;
|
||||
if(wifi_setting.security_type != secType)
|
||||
{
|
||||
bChanged = 1;
|
||||
wifi_setting.security_type = secType;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("\r\n wifi_config.security_type = %d\n", wifi_setting.security_type);
|
||||
if(wifi_setting.security_type > RTW_SECURITY_OPEN)
|
||||
{
|
||||
ptr = (char*)strstr(pcRxString, "Password=");
|
||||
if(ptr)
|
||||
{
|
||||
pcRxString = (char*)strstr(ptr, "&");
|
||||
*pcRxString++ = '\0';
|
||||
ptr += 9;
|
||||
if(strcmp((char*)wifi_setting.password, ptr))
|
||||
{
|
||||
bChanged = 1;
|
||||
len = strlen(ptr);
|
||||
if(len > MAX_PASSWORD_LEN){
|
||||
len = MAX_PASSWORD_LEN;
|
||||
ptr[len] = '\0';
|
||||
}
|
||||
strcpy((char*)wifi_setting.password, ptr);
|
||||
}
|
||||
}
|
||||
//printf("\r\n wifi_config.password = %s\n", wifi_setting.password);
|
||||
}
|
||||
ptr = (char*)strstr(pcRxString, "Channel=");
|
||||
if(ptr)
|
||||
{
|
||||
ptr += 8;
|
||||
channel = web_atoi(ptr);
|
||||
if((channel>MAX_CHANNEL_NUM)||(channel < 1))
|
||||
channel = 1;
|
||||
if(wifi_setting.channel !=channel)
|
||||
{
|
||||
bChanged = 1;
|
||||
wifi_setting.channel = channel;
|
||||
}
|
||||
}
|
||||
//printf("\r\n wifi_config.channel = %d\n", wifi_setting.channel);
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
struct netconn *pxHTTPListener = NULL;
|
||||
static void vProcessConnection( struct netconn *pxNetCon )
|
||||
{
|
||||
static portCHAR cDynamicPage[webMAX_PAGE_SIZE];
|
||||
struct netbuf *pxRxBuffer, *pxRxBuffer1 = NULL;
|
||||
portCHAR *pcRxString;
|
||||
unsigned portSHORT usLength;
|
||||
static portCHAR LocalBuf[LOCAL_BUF_SIZE];
|
||||
u8_t bChanged = 0;
|
||||
int ret_recv = ERR_OK;
|
||||
int ret_accept = ERR_OK;
|
||||
char *ptr = NULL;
|
||||
|
||||
/* Load WiFi Setting*/
|
||||
LoadWifiSetting();
|
||||
|
||||
/* We expect to immediately get data. */
|
||||
// Evan mopdified for adapt two version lwip api diff
|
||||
port_netconn_recv( pxNetCon , pxRxBuffer, ret_recv);
|
||||
|
||||
if( pxRxBuffer != NULL && ret_recv == ERR_OK)
|
||||
{
|
||||
/* Where is the data? */
|
||||
netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength );
|
||||
|
||||
//printf("\r\nusLength=%d pcRxString = \n%s\n", usLength, pcRxString);
|
||||
/* Is this a GET? We don't handle anything else. */
|
||||
if( !strncmp( pcRxString, "GET", 3 ) )
|
||||
{
|
||||
//printf("\r\nusLength=%d pcRxString=%s \n", usLength, pcRxString);
|
||||
//pcRxString = cDynamicPage;
|
||||
|
||||
/* Write out the HTTP OK header. */
|
||||
netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );
|
||||
|
||||
/* Generate index.html page. */
|
||||
GenerateIndexHtmlPage(cDynamicPage, LocalBuf);
|
||||
|
||||
/* Write out the dynamically generated page. */
|
||||
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
||||
}
|
||||
else if(!strncmp( pcRxString, "POST", 4 ) )
|
||||
{
|
||||
/* Write out the HTTP OK header. */
|
||||
netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY );
|
||||
|
||||
bChanged = ProcessPostMessage(pxRxBuffer, LocalBuf);
|
||||
if(bChanged == 0){
|
||||
port_netconn_recv( pxNetCon , pxRxBuffer1, ret_recv);
|
||||
if(pxRxBuffer != NULL && ret_recv == ERR_OK){
|
||||
bChanged = ProcessPostMessage(pxRxBuffer1, LocalBuf);
|
||||
netbuf_delete( pxRxBuffer1 );
|
||||
}
|
||||
}
|
||||
if(bChanged)
|
||||
{
|
||||
GenerateWaitHtmlPage(cDynamicPage);
|
||||
|
||||
/* Write out the generated page. */
|
||||
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
||||
|
||||
#if CONFIG_READ_FLASH
|
||||
StoreApInfo();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Generate index.html page. */
|
||||
GenerateIndexHtmlPage(cDynamicPage, LocalBuf);
|
||||
|
||||
/* Write out the generated page. */
|
||||
netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY );
|
||||
}
|
||||
}
|
||||
netbuf_delete( pxRxBuffer );
|
||||
}
|
||||
netconn_close( pxNetCon );
|
||||
|
||||
if(bChanged)
|
||||
{
|
||||
struct netconn *pxNewConnection;
|
||||
vTaskDelay(200/portTICK_RATE_MS);
|
||||
//printf("\r\n%d:before restart ap\n", xTaskGetTickCount());
|
||||
RestartSoftAP();
|
||||
//printf("\r\n%d:after restart ap\n", xTaskGetTickCount());
|
||||
pxHTTPListener->recv_timeout = 1;
|
||||
// Evan mopdified for adapt two version lwip api diff
|
||||
port_netconn_accept( pxHTTPListener , pxNewConnection, ret_accept);
|
||||
if( pxNewConnection != NULL && ret_accept == ERR_OK)
|
||||
{
|
||||
//printf("\r\n%d: got a conn\n", xTaskGetTickCount());
|
||||
netconn_close( pxNewConnection );
|
||||
while( netconn_delete( pxNewConnection ) != ERR_OK )
|
||||
{
|
||||
vTaskDelay( webSHORT_DELAY );
|
||||
}
|
||||
}
|
||||
//printf("\r\n%d:end\n", xTaskGetTickCount());
|
||||
pxHTTPListener->recv_timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
xTaskHandle webs_task = NULL;
|
||||
xSemaphoreHandle webs_sema = NULL;
|
||||
u8_t webs_terminate = 0;
|
||||
void vBasicWEBServer( void *pvParameters )
|
||||
{
|
||||
struct netconn *pxNewConnection;
|
||||
//struct ip_addr xIpAddr, xNetMast, xGateway;
|
||||
extern err_t ethernetif_init( struct netif *netif );
|
||||
int ret = ERR_OK;
|
||||
/* Parameters are not used - suppress compiler error. */
|
||||
( void )pvParameters;
|
||||
|
||||
/* Create a new tcp connection handle */
|
||||
pxHTTPListener = netconn_new( NETCONN_TCP );
|
||||
ip_set_option(pxHTTPListener->pcb.ip, SOF_REUSEADDR);
|
||||
netconn_bind( pxHTTPListener, NULL, webHTTP_PORT );
|
||||
netconn_listen( pxHTTPListener );
|
||||
|
||||
#if CONFIG_READ_FLASH
|
||||
/* Load wifi_config */
|
||||
LoadWifiConfig();
|
||||
RestartSoftAP();
|
||||
#endif
|
||||
//printf("\r\n-0\n");
|
||||
|
||||
/* Loop forever */
|
||||
for( ;; )
|
||||
{
|
||||
if(webs_terminate)
|
||||
break;
|
||||
|
||||
//printf("\r\n%d:-1\n", xTaskGetTickCount());
|
||||
/* Wait for connection. */
|
||||
// Evan mopdified for adapt two version lwip api diff
|
||||
port_netconn_accept( pxHTTPListener , pxNewConnection, ret);
|
||||
//printf("\r\n%d:-2\n", xTaskGetTickCount());
|
||||
|
||||
if( pxNewConnection != NULL && ret == ERR_OK)
|
||||
{
|
||||
/* Service connection. */
|
||||
vProcessConnection( pxNewConnection );
|
||||
while( netconn_delete( pxNewConnection ) != ERR_OK )
|
||||
{
|
||||
vTaskDelay( webSHORT_DELAY );
|
||||
}
|
||||
}
|
||||
//printf("\r\n%d:-3\n", xTaskGetTickCount());
|
||||
}
|
||||
//printf("\r\n-4\n");
|
||||
if(pxHTTPListener)
|
||||
{
|
||||
netconn_close(pxHTTPListener);
|
||||
netconn_delete(pxHTTPListener);
|
||||
pxHTTPListener = NULL;
|
||||
}
|
||||
|
||||
//printf("\r\nExit Web Server Thread!\n");
|
||||
xSemaphoreGive(webs_sema);
|
||||
}
|
||||
|
||||
#define STACKSIZE 512
|
||||
void start_web_server()
|
||||
{
|
||||
printf("\r\nWEB:Enter start web server!\n");
|
||||
webs_terminate = 0;
|
||||
if(webs_task == NULL)
|
||||
{
|
||||
if(xTaskCreate(vBasicWEBServer, (const char *)"web_server", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, &webs_task) != pdPASS)
|
||||
printf("\n\rWEB: Create webserver task failed!\n");
|
||||
}
|
||||
if(webs_sema == NULL)
|
||||
{
|
||||
webs_sema = xSemaphoreCreateCounting(0xffffffff, 0); //Set max count 0xffffffff
|
||||
}
|
||||
//printf("\r\nWEB:Exit start web server!\n");
|
||||
}
|
||||
|
||||
void stop_web_server()
|
||||
{
|
||||
//printf("\r\nWEB:Enter stop web server!\n");
|
||||
webs_terminate = 1;
|
||||
if(pxHTTPListener)
|
||||
netconn_abort(pxHTTPListener);
|
||||
if(webs_sema)
|
||||
{
|
||||
if(xSemaphoreTake(webs_sema, 15 * configTICK_RATE_HZ) != pdTRUE)
|
||||
{
|
||||
if(pxHTTPListener)
|
||||
{
|
||||
netconn_close(pxHTTPListener);
|
||||
netconn_delete(pxHTTPListener);
|
||||
pxHTTPListener = NULL;
|
||||
}
|
||||
printf("\r\nWEB: Take webs sema(%p) failed!!!!!!!!!!!\n", webs_sema);
|
||||
}
|
||||
vSemaphoreDelete(webs_sema);
|
||||
webs_sema = NULL;
|
||||
}
|
||||
if(webs_task)
|
||||
{
|
||||
vTaskDelete(webs_task);
|
||||
webs_task = NULL;
|
||||
}
|
||||
printf("\r\nWEB:Exit stop web server!\n");
|
||||
}
|
||||
71
component/common/utilities/webserver.h
Executable file
71
component/common/utilities/webserver.h
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* If you are: *
|
||||
* *
|
||||
* + New to FreeRTOS, *
|
||||
* + Wanting to learn FreeRTOS or multitasking in general quickly *
|
||||
* + Looking for basic training, *
|
||||
* + Wanting to improve your FreeRTOS skills and productivity *
|
||||
* *
|
||||
* then take a look at the FreeRTOS eBook *
|
||||
* *
|
||||
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* A pdf reference manual is also available. Both are usually delivered *
|
||||
* to your inbox within 20 minutes to two hours when purchased between 8am *
|
||||
* and 8pm GMT (although please allow up to 24 hours in case of *
|
||||
* exceptional circumstances). Thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
***NOTE*** The exception to the GPL is included to allow you to distribute
|
||||
a combined work that includes FreeRTOS without being obliged to provide the
|
||||
source code for proprietary components outside of the FreeRTOS kernel.
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
#ifndef BASIC_WEB_SERVER_H
|
||||
#define BASIC_WEB_SERVER_H
|
||||
#include <wifi/wifi_conf.h>
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* MACROS */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
#define basicwebWEBSERVER_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
|
||||
#define lwipBASIC_SERVER_STACK_SIZE 256
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/* The function that implements the WEB server task. */
|
||||
extern void start_web_server(void);
|
||||
|
||||
#endif /*
|
||||
*/
|
||||
|
||||
1376
component/common/utilities/xml.c
Executable file
1376
component/common/utilities/xml.c
Executable file
File diff suppressed because it is too large
Load diff
43
component/common/utilities/xml.h
Executable file
43
component/common/utilities/xml.h
Executable 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