#include "../new_common.h" #include "ctype.h" #ifndef WINDOWS #include "str_pub.h" #endif #include "new_http.h" #include "../new_pins.h" #include "../new_cfg.h" #include "../ota/ota.h" #ifndef WINDOWS #include "tuya_hal_storge.h" #endif /* GET / HTTP/1.1 Host: 127.0.0.1 */ /* GET /test?a=5 HTTP/1.1 Host: 127.0.0.1 */ /* GET /test?a=Test%20with%20space HTTP/1.1 Host: 127.0.0.1 Connection: keep-alive Cache-Control: max-age=0 */ /* GET /test?a=15&b=25 HTTP/1.1 Host: 127.0.0.1 Connection: keep-alive */ #define DEFAULT_OTA_URL "http://raspberrypi:1880/firmware" const char httpHeader[] = "HTTP/1.1 200 OK\nContent-type: " ; // HTTP header const char httpMimeTypeHTML[] = "text/html\n\n" ; // HTML MIME type const char httpMimeTypeText[] = "text/plain\n\n" ; // TEXT MIME type const char htmlHeader[] = "" ; const char htmlEnd[] = "" ; const char htmlReturnToMenu[] = "Return to menu";; const char htmlReturnToCfg[] = "Return to cfg";; const char *g_build_str = "Build on " __DATE__ " " __TIME__; #if WINDOWS #define os_free free #define os_malloc malloc #endif typedef struct http_callback_tag { char *url; http_callback_fn callback; } http_callback_t; #define MAX_HTTP_CALLBACKS 32 static http_callback_t *callbacks[MAX_HTTP_CALLBACKS]; static int numCallbacks = 0; int HTTP_RegisterCallback( const char *url, http_callback_fn callback){ if (!url || !callback){ return -1; } if (numCallbacks >= MAX_HTTP_CALLBACKS){ return -4; } callbacks[numCallbacks] = (http_callback_t*)os_malloc(sizeof(http_callback_t)); if (!callbacks[numCallbacks]){ return -2; } callbacks[numCallbacks]->url = (char *)os_malloc(strlen(url)+1); if (!callbacks[numCallbacks]->url){ os_free(callbacks[numCallbacks]); return -3; } strcpy(callbacks[numCallbacks]->url, url); callbacks[numCallbacks]->callback = callback; numCallbacks++; // success return 0; } bool http_startsWith(const char *base, const char *substr) { while(*substr != 0) { if(*base != *substr) return false; if(*base == 0) return false; base++; substr++; } return true; } bool http_checkUrlBase(const char *base, const char *fileName) { while(*base != 0 && *base != '?' && *base != ' ') { if(*base != *fileName) return false; if(*base == 0) return false; base++; fileName++; } if(*fileName != 0) return false; return true; } void http_setup(char *o, const char *type){ strcpy(o,httpHeader); strcat(o,type); } const char *http_checkArg(const char *p, const char *n) { while(1) { if(*n == 0 && (*p == 0 || *p == '=')) return p; if(*p != *n) return 0; p++; n++; } return p; } void http_copyCarg(const char *atin, char *to, int maxSize) { int a, b; const unsigned char *at = (unsigned char *)atin; while(*at != 0 && *at != '&' && *at != ' ' && maxSize > 1) { #if 0 *to = *at; to++; at++; maxSize--; #else if ((*at == '%') && ((a = at[1]) && (b = at[2])) && (isxdigit(a) && isxdigit(b))) { if (a >= 'a') a -= 'a'-'A'; if (a >= 'A') a -= ('A' - 10); else a -= '0'; if (b >= 'a') b -= 'a'-'A'; if (b >= 'A') b -= ('A' - 10); else b -= '0'; *to++ = 16*a+b; at+=3; } else if (*at == '+') { *to++ = ' '; at++; } else { *to++ = *at++; } maxSize--; #endif } *to = 0; } bool http_getArg(const char *base, const char *name, char *o, int maxSize) { while(*base != '?') { if(*base == 0) return 0; base++; } base++; while(*base) { const char *at = http_checkArg(base,name); if(at) { at++; http_copyCarg(at,o,maxSize); return 1; } while(*base != '&') { if(*base == 0) { return 0; } base++; } base++; } return 0; } const char *htmlIndex = ""; /* const char *htmlPinRoles = "\ \ \ \ \ \ "; */ const char *htmlPinRoleNames[] = { " ", "Rel", "Rel_n", "Btn", "Btn_n", "LED", "LED_n", "PWM", "Wifi LED", "Wifi LED_n", "e", "e", }; void setupAllWB2SPinsAsButtons() { PIN_SetPinRoleForPinIndex(6,IOR_Button); PIN_SetPinChannelForPinIndex(6,1); PIN_SetPinRoleForPinIndex(7,IOR_Button); PIN_SetPinChannelForPinIndex(7,1); PIN_SetPinRoleForPinIndex(8,IOR_Button); PIN_SetPinChannelForPinIndex(8,1); PIN_SetPinRoleForPinIndex(23,IOR_Button); PIN_SetPinChannelForPinIndex(23,1); PIN_SetPinRoleForPinIndex(24,IOR_Button); PIN_SetPinChannelForPinIndex(24,1); PIN_SetPinRoleForPinIndex(26,IOR_Button); PIN_SetPinChannelForPinIndex(26,1); PIN_SetPinRoleForPinIndex(27,IOR_Button); PIN_SetPinChannelForPinIndex(27,1); } typedef struct template_s { void (*setter)(); const char *name; } template_t; template_t g_templates [] = { { Setup_Device_Empty, "Empty"}, { Setup_Device_TuyaWL_SW01_16A, "WL SW01 16A"}, { Setup_Device_TuyaSmartLife4CH10A, "Smart Life 4CH 10A"}, { Setup_Device_IntelligentLife_NF101A, "Intelligent Life NF101A"}, { Setup_Device_TuyaLEDDimmerSingleChannel, "Tuya LED Dimmer Single Channel PWM WB3S"}, { Setup_Device_CalexLEDDimmerFiveChannel, "Calex RGBWW LED Dimmer Five Channel PWM BK7231S"}, { Setup_Device_CalexPowerStrip_900018_1v1_0UK, "Calex UK power strip 900018.1 v1.0 UK"} }; int g_total_templates = sizeof(g_templates)/sizeof(g_templates[0]); const char *g_header = "

OpenBK7231

[Read more][Support project]

"; void HTTP_AddBuildFooter(char *outbuf, int outBufSize) { strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,g_build_str,outBufSize); } int HTTP_ProcessPacket(const char *recvbuf, char *outbuf, int outBufSize, http_send_fn sendpart, int socket) { int i, j; char tmpA[128]; char tmpB[64]; char tmpC[64]; //int bChanged = 0; const char *urlStr; *outbuf = '\0'; urlStr = recvbuf + 5; if(http_startsWith(recvbuf,"GET")) { printf("HTTP request\n"); } else { printf("Other request\n"); } http_getArg(urlStr,"a",tmpA,sizeof(tmpA)); http_getArg(urlStr,"b",tmpB,sizeof(tmpB)); http_getArg(urlStr,"c",tmpC,sizeof(tmpC)); for (i = 0; i < numCallbacks; i++){ char *url = callbacks[i]->url; if (http_checkUrlBase(urlStr, &url[1])){ return callbacks[i]->callback(recvbuf, outbuf, outBufSize); } } if(http_checkUrlBase(urlStr,"about")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"About us page.",outBufSize); strcat_safe(outbuf,htmlReturnToMenu,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_mqtt")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"

Use this to connect to your MQTT

",outBufSize); strcat_safe(outbuf,"
\
\
\
\

\
\
\
\
\
\
\ \
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_mqtt_set")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); if(http_getArg(recvbuf,"host",tmpA,sizeof(tmpA))) { CFG_SetMQTTHost(tmpA); } if(http_getArg(recvbuf,"port",tmpA,sizeof(tmpA))) { CFG_SetMQTTPort(atoi(tmpA)); } if(http_getArg(recvbuf,"user",tmpA,sizeof(tmpA))) { CFG_SetMQTTUserName(tmpA); } if(http_getArg(recvbuf,"password",tmpA,sizeof(tmpA))) { CFG_SetMQTTPass(tmpA); } if(http_getArg(recvbuf,"client",tmpA,sizeof(tmpA))) { CFG_SetMQTTBrokerName(tmpA); } strcat_safe(outbuf,"MQTT mode set!",outBufSize); CFG_SaveMQTT(); strcat_safe(outbuf,"Please wait for module to connect... if there is problem, restart it...",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"Return to MQTT settings",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_wifi_set")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); if(http_getArg(recvbuf,"open",tmpA,sizeof(tmpA))) { CFG_SetWiFiSSID(""); CFG_SetWiFiPass(""); strcat_safe(outbuf,"WiFi mode set: open access point.",outBufSize); } else { if(http_getArg(recvbuf,"ssid",tmpA,sizeof(tmpA))) { CFG_SetWiFiSSID(tmpA); } if(http_getArg(recvbuf,"pass",tmpA,sizeof(tmpA))) { CFG_SetWiFiPass(tmpA); } strcat_safe(outbuf,"WiFi mode set: connect to WLAN.",outBufSize); } CFG_SaveWiFi(); strcat_safe(outbuf,"Please wait for module to reset...",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"Return to WiFi settings",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_wifi")) { // for a test, show password as well... const char *cur_ssid, *cur_pass; http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); /*bChanged = 0; if(http_getArg(recvbuf,"ssid",tmpA,sizeof(tmpA))) { CFG_SetWiFiSSID(tmpA); strcat_safe(outbuf,"

WiFi SSID set!

",outBufSize); bChanged = 1; } if(http_getArg(recvbuf,"pass",tmpA,sizeof(tmpA))) { CFG_SetWiFiPass(tmpA); strcat_safe(outbuf,"

WiFi Password set!

",outBufSize); bChanged = 1; } if(bChanged) { strcat_safe(outbuf,"

Device will reconnect after restarting

",outBufSize); }*/ strcat_safe(outbuf,"

Use this to disconnect from your WiFi

",outBufSize); strcat_safe(outbuf,"
\ \ \
",outBufSize); strcat_safe(outbuf,"

Use this to connect to your WiFi

",outBufSize); strcat_safe(outbuf,"
\
\
\
\

\ \
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"flash_read_tool")) { int len = 16; int ofs = 1970176; int res; int rem; int now; int nowOfs; http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"

Flash Read Tool

",outBufSize); if(http_getArg(recvbuf,"offset",tmpA,sizeof(tmpA))&&http_getArg(recvbuf,"len",tmpB,sizeof(tmpB))) { u8 buffer[128]; len = atoi(tmpB); ofs = atoi(tmpA); sprintf(tmpA,"Memory at %i with len %i reads: ",ofs,len); strcat_safe(outbuf,tmpA,outBufSize); strcat_safe(outbuf,"
",outBufSize); ///res = tuya_hal_flash_read (ofs, buffer,len); //sprintf(tmpA,"Result %i",res); // strcat(outbuf,tmpA); /// strcat(outbuf,"
"); nowOfs = ofs; rem = len; while(1) { if(rem > sizeof(buffer)) { now = sizeof(buffer); } else { now = rem; } res = tuya_hal_flash_read (nowOfs, buffer,now); for(i = 0; i < now; i++) { sprintf(tmpA,"%02X ",buffer[i]); strcat_safe(outbuf,tmpA,outBufSize); } rem -= now; nowOfs += now; if(rem <= 0) { break; } } strcat_safe(outbuf,"
",outBufSize); } strcat_safe(outbuf,"
\
\
",ofs); strcat_safe(outbuf,tmpA,outBufSize); strcat_safe(outbuf,"
\ ",len); strcat_safe(outbuf,tmpA,outBufSize); strcat_safe(outbuf,"

\ \
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_quick")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"

Quick Config

",outBufSize); if(http_getArg(urlStr,"dev",tmpA,sizeof(tmpA))) { j = atoi(tmpA); sprintf(tmpA,"

Set dev %i!

",j); strcat(outbuf,tmpA); g_templates[j].setter(); } strcat_safe(outbuf,"
",outBufSize); sprintf(tmpA, ""); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_ha")) { int relayFlags = 0; int pwmFlags = 0; int relayCount = 0; int pwmCount = 0; const char *baseName; baseName = CFG_GetShortDeviceName(); http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"

Home Assistant Cfg

",outBufSize); strcat_safe(outbuf,"

Paste this to configuration yaml

",outBufSize); strcat_safe(outbuf,"",outBufSize); strcat_safe(outbuf,htmlReturnToCfg,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg")) { http_setup(outbuf, httpMimeTypeHTML); strcat_safe(outbuf,htmlHeader,outBufSize); strcat_safe(outbuf,g_header,outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,"
",outBufSize); strcat_safe(outbuf,htmlReturnToMenu,outBufSize); HTTP_AddBuildFooter(outbuf,outBufSize); strcat_safe(outbuf,htmlEnd,outBufSize); //} else if(http_checkUrlBase(urlStr,"setWB2SInputs")) { // http_setup(outbuf, httpMimeTypeHTML); // strcat_safe(outbuf,htmlHeader,outBufSize); // setupAllWB2SPinsAsButtons(); // http_setup(outbuf, httpMimeTypeHTML); // strcat_safe(outbuf,"Set all inputs for dbg .",outBufSize); // strcat_safe(outbuf,htmlReturnToMenu,outBufSize); // HTTP_AddBuildFooter(outbuf,outBufSize); // strcat_safe(outbuf,htmlEnd,outBufSize); //} else if(http_checkUrlBase(urlStr,"setAllInputs")) { // http_setup(outbuf, httpMimeTypeHTML); // strcat_safe(outbuf,htmlHeader,outBufSize); // // it breaks UART pins as well, omg! // for(i = 0; i < GPIO_MAX; i++) { // PIN_SetPinRoleForPinIndex(i,IOR_Button); // PIN_SetPinChannelForPinIndex(i,1); // } // http_setup(outbuf, httpMimeTypeHTML); // strcat_safe(outbuf,"Set all inputs for dbg .",outBufSize); // strcat_safe(outbuf,htmlReturnToMenu,outBufSize); // HTTP_AddBuildFooter(outbuf,outBufSize); // strcat_safe(outbuf,htmlEnd,outBufSize); } else if(http_checkUrlBase(urlStr,"cfg_pins")) { int iChanged = 0; int iChangedRequested = 0; http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); strcat_safe(outbuf,g_header,outBufSize); for(i = 0; i < GPIO_MAX; i++) { sprintf(tmpA, "%i",i); if(http_getArg(recvbuf,tmpA,tmpB,sizeof(tmpB))) { int role; int pr; iChangedRequested++; role = atoi(tmpB); pr = PIN_GetPinRoleForPinIndex(i); if(pr != role) { PIN_SetPinRoleForPinIndex(i,role); iChanged++; } } sprintf(tmpA, "r%i",i); if(http_getArg(recvbuf,tmpA,tmpB,sizeof(tmpB))) { int rel; int prevRel; iChangedRequested++; rel = atoi(tmpB); prevRel = PIN_GetPinChannelForPinIndex(i); if(prevRel != rel) { PIN_SetPinChannelForPinIndex(i,rel); iChanged++; } } } if (sendpart){ sendpart(socket, outbuf, strlen(outbuf)); outbuf[0] = 0; } if(iChangedRequested>0) { PIN_SaveToFlash(); sprintf(tmpA, "Pins update - %i reqs, %i changed!

",iChangedRequested,iChanged); strcat(outbuf,tmpA); } // strcat(outbuf,""); strcat(outbuf,"
"); for( i = 0; i < GPIO_MAX; i++) { int si, ch; si = PIN_GetPinRoleForPinIndex(i); ch = PIN_GetPinChannelForPinIndex(i); sprintf(tmpA, "P%i ",i); strcat(outbuf,tmpA); sprintf(tmpA, ""); if(ch == 0) { tmpB[0] = 0; } else { sprintf(tmpB,"%i",ch); } sprintf(tmpA, "",i,tmpB); strcat(outbuf,tmpA); strcat(outbuf,"
"); if (sendpart){ sendpart(socket, outbuf, strlen(outbuf)); outbuf[0] = 0; } } strcat(outbuf,"
"); strcat(outbuf,htmlReturnToCfg); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } else if(http_checkUrlBase(urlStr,"index")) { int relayFlags; int pwmFlags; relayFlags = 0; pwmFlags = 0; http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); strcat(outbuf,""); strcat_safe(outbuf,g_header,outBufSize); if(http_getArg(urlStr,"tgl",tmpA,sizeof(tmpA))) { j = atoi(tmpA); sprintf(tmpA,"

Toggled %i!

",j); strcat(outbuf,tmpA); CHANNEL_Toggle(j); } if(http_getArg(urlStr,"on",tmpA,sizeof(tmpA))) { j = atoi(tmpA); sprintf(tmpA,"

Enabled %i!

",j); strcat(outbuf,tmpA); CHANNEL_Set(j,255,1); } if(http_getArg(urlStr,"off",tmpA,sizeof(tmpA))) { j = atoi(tmpA); sprintf(tmpA,"

Disabled %i!

",j); strcat(outbuf,tmpA); CHANNEL_Set(j,0,1); } if(http_getArg(urlStr,"pwm",tmpA,sizeof(tmpA))) { int newPWMValue = atoi(tmpA); http_getArg(urlStr,"pwmIndex",tmpA,sizeof(tmpA)); j = atoi(tmpA); sprintf(tmpA,"

Changed pwm %i to %i!

",j,newPWMValue); strcat(outbuf,tmpA); CHANNEL_Set(j,newPWMValue,1); } for(i = 0; i < GPIO_MAX; i++) { int role = PIN_GetPinRoleForPinIndex(i); int ch = PIN_GetPinChannelForPinIndex(i); if(role == IOR_Relay || role == IOR_Relay_n || role == IOR_LED || role == IOR_LED_n) { BIT_SET(relayFlags,ch); } if(role == IOR_PWM) { BIT_SET(pwmFlags,ch); } } for(i = 0; i < CHANNEL_MAX; i++) { if(BIT_CHECK(relayFlags,i)) { const char *c; if(CHANNEL_Check(i)) { c = "r"; } else { c = "g"; } strcat(outbuf,"
"); sprintf(tmpA,"",i); strcat(outbuf,tmpA); sprintf(tmpA,"
",c,i); strcat(outbuf,tmpA); } if(BIT_CHECK(pwmFlags,i)) { int pwmValue; pwmValue = CHANNEL_Get(i); sprintf(tmpA,"
",i); strcat(outbuf,tmpA); sprintf(tmpA,"",i,pwmValue); strcat(outbuf,tmpA); sprintf(tmpA,"",i); strcat(outbuf,tmpA); sprintf(tmpA,"
",i); strcat(outbuf,tmpA); strcat(outbuf,""); } } // strcat(outbuf,""); strcat(outbuf,"
"); strcat(outbuf,"
"); strcat(outbuf,htmlReturnToMenu); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } else if(http_checkUrlBase(urlStr,"ota_exec")) { http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); if(http_getArg(urlStr,"host",tmpA,sizeof(tmpA))) { sprintf(tmpB,"

OTA requested for %s!

",tmpA); strcat(outbuf,tmpB); #if WINDOWS #else otarequest(tmpA); #endif } strcat(outbuf,htmlReturnToMenu); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } else if(http_checkUrlBase(urlStr,"ota")) { http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); strcat_safe(outbuf,"
\
\
\ \
",outBufSize); strcat(outbuf,htmlReturnToMenu); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } else { http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); strcat_safe(outbuf,g_header,outBufSize); strcat(outbuf,"Not found."); strcat(outbuf,htmlReturnToMenu); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } i = strlen(outbuf); if(i >= outBufSize-1) { // Rewrite all to allow user to know that something went wrong http_setup(outbuf, httpMimeTypeHTML); strcat(outbuf,htmlHeader); strcat_safe(outbuf,g_header,outBufSize); sprintf(tmpA, "Buffer overflow occured while trying to process your request.
"); strcat(outbuf,tmpA); strcat(outbuf,htmlReturnToMenu); HTTP_AddBuildFooter(outbuf,outBufSize); strcat(outbuf,htmlEnd); } i = strlen(outbuf); return i; }