📄 upnpdescgen.c
字号:
{ {"NewTotalBytesReceived", 2, 5}, {0, 0, 0}};static const struct argument GetTotalPacketsSentArgs[] ={ {"NewTotalPacketsSent", 2, 6}, {0, 0, 0}};static const struct argument GetTotalPacketsReceivedArgs[] ={ {"NewTotalPacketsReceived", 2, 7}, {0, 0, 0}};static const struct action WANCfgActions[] ={ {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */ {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */ {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */ {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */ {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */ {0, 0}};/* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */static const struct stateVar WANCfgVars[] ={ {"WANAccessType", 0, 0, 1}, /* Allowed Values : DSL / POTS / Cable / Ethernet * Default value : empty string */ {"Layer1UpstreamMaxBitRate", 3, 0}, {"Layer1DownstreamMaxBitRate", 3, 0}, {"PhysicalLinkStatus", 0|0x80, 0, 6}, /* allowed values : * Up / Down / Initializing (optional) / Unavailable (optionnal) * no Default value * Evented */ {"TotalBytesSent", 3, 0}, /* Optional */ {"TotalBytesReceived", 3, 0}, /* Optional */ {"TotalPacketsSent", 3, 0}, /* Optional */ {"TotalPacketsReceived", 3, 0},/* Optional */ /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */ {0, 0, 0}};static const struct serviceDesc scpdWANCfg ={ WANCfgActions, WANCfgVars };/* strcat_str() * concatenate the string and use realloc to increase the * memory buffer if needed. */static char *strcat_str(char * str, int * len, int * tmplen, const char * s2){ int s2len; s2len = (int)strlen(s2); if(*tmplen <= (*len + s2len)) { if(s2len < 256) *tmplen += 256; else *tmplen += s2len; str = (char *)realloc(str, *tmplen); } /*strcpy(str + *len, s2); */ memcpy(str + *len, s2, s2len + 1); *len += s2len; return str;}/* strcat_char() : * concatenate a character and use realloc to increase the * size of the memory buffer if needed */static char *strcat_char(char * str, int * len, int * tmplen, char c){ if(*tmplen <= (*len + 1)) { *tmplen += 256; str = (char *)realloc(str, *tmplen); } str[*len] = c; (*len)++; return str;}/* iterative subroutine using a small stack * This way, the progam stack usage is kept low */static char *genXML(char * str, int * len, int * tmplen, const struct XMLElt * p){ unsigned short i, j, k; int top; const char * eltname, *s; char c; struct { unsigned short i; unsigned short j; const char * eltname; } pile[16]; /* stack */ top = -1; i = 0; /* current node */ j = 1; /* i + number of nodes*/ for(;;) { eltname = p[i].eltname; if(!eltname) return str; if(eltname[0] == '/') { /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */ str = strcat_char(str, len, tmplen, '<'); str = strcat_str(str, len, tmplen, eltname+1); str = strcat_char(str, len, tmplen, '>'); str = strcat_str(str, len, tmplen, p[i].data); str = strcat_char(str, len, tmplen, '<'); str = strcat_str(str, len, tmplen, eltname); str = strcat_char(str, len, tmplen, '>'); for(;;) { if(top < 0) return str; i = ++(pile[top].i); j = pile[top].j; /*printf(" pile[%d]\t%d %d\n", top, i, j); */ if(i==j) { /*printf("</%s>\n", pile[top].eltname); */ str = strcat_char(str, len, tmplen, '<'); str = strcat_char(str, len, tmplen, '/'); s = pile[top].eltname; for(c = *s; c > ' '; c = *(++s)) str = strcat_char(str, len, tmplen, c); str = strcat_char(str, len, tmplen, '>'); top--; } else break; } } else { /*printf("<%s>\n", eltname); */ str = strcat_char(str, len, tmplen, '<'); str = strcat_str(str, len, tmplen, eltname); str = strcat_char(str, len, tmplen, '>'); k = i; /*i = p[k].index; */ /*j = i + p[k].nchild; */ i = (unsigned)p[k].data & 0xffff; j = i + ((unsigned)p[k].data >> 16); top++; /*printf(" +pile[%d]\t%d %d\n", top, i, j); */ pile[top].i = i; pile[top].j = j; pile[top].eltname = eltname; } }}/* genRootDesc() : * - Generate the root description of the UPnP device. * - the len argument is used to return the length of * the returned string. * - tmp_uuid argument is used to build the uuid string */char *genRootDesc(int * len){ char * str; int tmplen; tmplen = 2048; str = (char *)malloc(tmplen); if(str == NULL) return NULL; * len = strlen(xmlver); /*strcpy(str, xmlver); */ memcpy(str, xmlver, *len + 1); str = genXML(str, len, &tmplen, rootDesc); str[*len] = '\0'; return str;}/* genServiceDesc() : * Generate service description with allowed methods and * related variables. */static char *genServiceDesc(int * len, const struct serviceDesc * s){ int i, j; const struct action * acts; const struct stateVar * vars; const struct argument * args; char * str; int tmplen; tmplen = 2048; str = (char *)malloc(tmplen); if(str == NULL) return NULL; /*strcpy(str, xmlver); */ *len = strlen(xmlver); memcpy(str, xmlver, *len + 1); acts = s->actionList; vars = s->serviceStateTable; str = strcat_char(str, len, &tmplen, '<'); str = strcat_str(str, len, &tmplen, root_service); str = strcat_char(str, len, &tmplen, '>'); str = strcat_str(str, len, &tmplen, "<specVersion><major>1</major><minor>0</minor></specVersion>"); i = 0; str = strcat_str(str, len, &tmplen, "<actionList>"); while(acts[i].name) { str = strcat_str(str, len, &tmplen, "<action><name>"); str = strcat_str(str, len, &tmplen, acts[i].name); str = strcat_str(str, len, &tmplen, "</name>"); /* argument List */ args = acts[i].args; if(args) { str = strcat_str(str, len, &tmplen, "<argumentList>"); j = 0; while(args[j].name) { str = strcat_str(str, len, &tmplen, "<argument><name>"); str = strcat_str(str, len, &tmplen, args[j].name); str = strcat_str(str, len, &tmplen, "</name><direction>"); str = strcat_str(str, len, &tmplen, args[j].dir==1?"in":"out"); str = strcat_str(str, len, &tmplen, "</direction><relatedStateVariable>"); str = strcat_str(str, len, &tmplen, vars[args[j].relatedVar].name); str = strcat_str(str, len, &tmplen, "</relatedStateVariable></argument>"); j++; } str = strcat_str(str, len, &tmplen,"</argumentList>"); } str = strcat_str(str, len, &tmplen, "</action>"); /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */ i++; } str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>"); i = 0; while(vars[i].name) { str = strcat_str(str, len, &tmplen, "<stateVariable sendEvents=\""); /* for the moment allways send no. Wait for SUBSCRIBE implementation * before setting it to yes */ /*str = strcat_str(str, len, &tmplen, (vars[i].itype & 0x80)?"yes":"no"); */ str = strcat_str(str, len, &tmplen, "no"); str = strcat_str(str, len, &tmplen, "\"><name>"); str = strcat_str(str, len, &tmplen, vars[i].name); str = strcat_str(str, len, &tmplen, "</name><dataType>"); str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]); str = strcat_str(str, len, &tmplen, "</dataType>"); if(vars[i].iallowedlist) { str = strcat_str(str, len, &tmplen, "<allowedValueList>"); for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++) { str = strcat_str(str, len, &tmplen, "<allowedValue>"); str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]); str = strcat_str(str, len, &tmplen, "</allowedValue>"); } str = strcat_str(str, len, &tmplen, "</allowedValueList>"); } /*if(vars[i].defaultValue) */ if(vars[i].idefault) { str = strcat_str(str, len, &tmplen, "<defaultValue>"); /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */ str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]); str = strcat_str(str, len, &tmplen, "</defaultValue>"); } str = strcat_str(str, len, &tmplen, "</stateVariable>"); /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */ i++; } str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>"); str[*len] = '\0'; return str;}/* genWANIPCn() : * Generate the WANIPConnection xml description */char *genWANIPCn(int * len){ return genServiceDesc(len, &scpdWANIPCn);}/* genWANCfg() : * Generate the WANInterfaceConfig xml description. */char *genWANCfg(int * len){ return genServiceDesc(len, &scpdWANCfg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -