/***************************************************************************** Function: static HTTP_IO_RESULT HTTPPostWifiConfig(void) Summary: Processes the wifi config data Description: Accepts wireless configuration data from the www site and saves them to a structure to be applied by the ZG configuration manager. The following configurations are possible: i) Mode: adhoc or infrastructure ii) Security: - None - WPA/WPA2 passphrase - WPA/WPA2 pre-calculated key - WEP 64-bit - WEP 128-bit iii) Key material If an error occurs, such as data is invalid they will be redirected to a page informing the user of such results. NOTE: This code for modified originally from HTTPPostWifiConfig as distributed by Microchip. Precondition: None Parameters: None Return Values: HTTP_IO_DONE - all parameters have been processed HTTP_IO_NEED_DATA - data needed by this function has not yet arrived ***************************************************************************/ static HTTP_IO_RESULT HTTPPostWifiConfig(void) { // Check to see if the browser is attempting to submit more data than we // can parse at once. This function needs to receive all updated // parameters and validate them all before committing them to memory so that // orphaned configuration parameters do not get written (for example, if a // static IP address is given, but the subnet mask fails parsing, we // should not use the static IP address). Everything needs to be processed // in a single transaction. If this is impossible, fail and notify the user. // As a web devloper, if you add parameters to AppConfig and run into this // problem, you could fix this by to splitting your update web page into two // seperate web pages (causing two transactional writes). Alternatively, // you could fix it by storing a static shadow copy of AppConfig someplace // in memory and using it instead of newAppConfig. Lastly, you could // increase the TCP RX FIFO size for the HTTP server. This will allow more // data to be POSTed by the web browser before hitting this limit. UINT8 ConnectionProfileID; UINT8 ConnectionState; UINT8 ssidLen; WF_CMGetConnectionState(&ConnectionState, &ConnectionProfileID); if(curHTTP.byteCount > TCPIsGetReady(sktHTTP) + TCPGetRxFIFOFree(sktHTTP)) goto ConfigFailure; // Ensure that all data is waiting to be parsed. If not, keep waiting for // all of it to arrive. if(TCPIsGetReady(sktHTTP) < curHTTP.byteCount) return HTTP_IO_NEED_DATA; // Read all browser POST data while(curHTTP.byteCount) { // Read a form field name if(HTTPReadPostName(curHTTP.data, 6) != HTTP_READ_OK) goto ConfigFailure; // Read a form field value if(HTTPReadPostValue(curHTTP.data + 6, sizeof(curHTTP.data)-6-2) != HTTP_READ_OK) goto ConfigFailure; // Parse the value that was read // Read security type if(!strcmppgm2ram((char*)curHTTP.data, "sec")) { char security_type[7]; if (strlen((char*)(curHTTP.data+6)) > 6) /* Sanity check */ goto ConfigFailure; memcpy(security_type, (void*)(curHTTP.data+6), strlen((char*)(curHTTP.data+6))); security_type[strlen((char*)(curHTTP.data+6))] = 0; /* Terminate string */ printf("\r\nSecurity Mode: "); if (!strcmppgm2ram((char*)security_type, "no")) { CFGCXT.security = WF_SECURITY_OPEN; printf("OPEN"); } else if(!strcmppgm2ram((char*)security_type, "wpa")) { CFGCXT.security = WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE; printf("WPA w/PASSPHRASE"); } else if(!strcmppgm2ram((char*)security_type, "calc")) { /* Pre-calculated key */ CFGCXT.security = WF_SECURITY_WPA_AUTO_WITH_KEY; printf("WPA w/AUTO Key"); } else if(!strcmppgm2ram((char*)security_type, "wep40")) { CFGCXT.security = WF_SECURITY_WEP_40; printf("WEP 64-bit"); } else if(!strcmppgm2ram((char*)security_type, "wep104")) { CFGCXT.security = WF_SECURITY_WEP_104; printf("WEP 128-bit"); } else { //Security type no good :-( printf("\r\nUnknown key type!"); goto ConfigFailure; } } // Read new Security Key /* else if(!strcmppgm2ram((char*)curHTTP.data, "key")) { BYTE key_size = 0, ascii_key = 0; switch ((BYTE)CFGCXT.security) { case WF_SECURITY_OPEN: //keep compiler happy, nothing to do here! break; case WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE: //wpa passphrase printf("\r\nPassphrase type of key! "); ascii_key = 1; key_size = strlen((char *)(curHTTP.data+6)); //between 8-63 characters, passphrase if ((key_size < 8 ) || (key_size > 63)) goto ConfigFailure; break; case WF_SECURITY_WPA_AUTO_WITH_KEY: //wpa pre-calculated key!!! key_size = 64; break; case WF_SECURITY_WEP_40: key_size = 10; // Assume hex size if (strlen((char *)(curHTTP.data+6)) == 5) { key_size = 5; // ASCII key support ascii_key = 1; } CFGCXT.defaultWepKey = 0; // Example uses only key idx 0 (sometimes called 1) break; case WF_SECURITY_WEP_104: key_size = 26; // Assume hex size if (strlen((char *)(curHTTP.data+6)) == 13) { key_size = 13; // ASCII key support ascii_key = 1; } CFGCXT.defaultWepKey = 0; // Example uses only key idx 0 (sometimes called 1) break; default: break; } if (strlen((char *)(curHTTP.data + 6)) != key_size) { printf("\r\nIncomplete key received! "); goto ConfigFailure; } memcpy(CFGCXT.key, (void*)(curHTTP.data+6), key_size); CFGCXT.key[key_size] = 0; // terminate string if (!ascii_key) { //if ((cfg.security == sec_wep64) || (cfg.security == sec_wep128)) key_size /= 2; if (!convertAsciiToHexInPlace((INT8 *)&CFGCXT.key[0], key_size)) { printf("\r\nFailed to convert ASCII to hex! "); goto ConfigFailure; } } } */ // Get new ssid and make sure it is valid else if(!strcmppgm2ram((char*)curHTTP.data, "ssid")) { if(strlen((char*)(curHTTP.data+6)) < 33u) { memcpy(CFGCXT.ssid, (void*)(curHTTP.data+6), strlen((char*)(curHTTP.data+6))); CFGCXT.ssid[strlen((char*)(curHTTP.data+6))] = 0; /* Terminate string */ /* save current profile SSID for displaying later */ WF_CPGetSsid(ConnectionProfileID, (UINT8*)&CFGCXT.prevSSID, &ssidLen); CFGCXT.prevSSID[ssidLen] = 0; printf("\r\nSSID: %s",CFGCXT.ssid); } else { //Invalid SSID... fail :-( printf("\r\nInvalid SSID...! "); goto ConfigFailure; } } // Get the wlan mode: adhoc or infrastructure else if(!strcmppgm2ram((char*)curHTTP.data, (ROM char*)"wlan")) { char mode[6]; if (strlen((char*)(curHTTP.data+6)) > 5) /* Sanity check */ goto ConfigFailure; memcpy(mode, (void*)(curHTTP.data+6), strlen((char*)(curHTTP.data+6))); mode[strlen((char*)(curHTTP.data+6))] = 0; /* Terminate string */ if(!strcmppgm2ram((char*)mode, (ROM char*)"infra")) { printf("\r\nSetting mode to infrastructure! "); CFGCXT.type = WF_INFRASTRUCTURE; } else if(!strcmppgm2ram((char*)mode, "adhoc")) { printf("\r\nSetting mode to adhoc! "); CFGCXT.type = WF_ADHOC; // Always setup adhoc to attempt to connect first, then start WF_CPSetAdHocBehavior(ConnectionProfileID, WF_ADHOC_CONNECT_THEN_START); } else { //Mode type no good :-( printf("\r\nConfig WLAN Mode Failure! "); goto ConfigFailure; } // save old WLAN mode WF_CPGetNetworkType(ConnectionProfileID, &CFGCXT.prevWLAN); } } /* Check if WPA hasn't been selected with adhoc, if it has we choke! */ if ((CFGCXT.type == WF_ADHOC) && ((CFGCXT.security == WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE) || (CFGCXT.security == WF_SECURITY_WPA_AUTO_WITH_KEY))) goto ConfigFailure; /* * All parsing complete! If we have got to here all data has been validated and * we can handle what is necessary to start the reconfigure process of the WiFi device */ // Copy wifi cfg data to be committed memcpy(CPElements.ssid, CFGCXT.ssid, strlen((char*)(CFGCXT.ssid))); CPElements.ssidLength = strlen((char*)(CFGCXT.ssid)); /* Going to set security type */ CPElements.securityType = CFGCXT.security; /* Going to save the key, if required */ if (CFGCXT.security != WF_SECURITY_OPEN) { BYTE key_size =0; switch ((BYTE)CFGCXT.security) { case WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE: //wpa passphrase key_size = strlen((char*)(CFGCXT.key)); //ascii so use strlen break; case WF_SECURITY_WPA_AUTO_WITH_KEY: //wpa pre-calculated key!!! key_size = 32; break; case WF_SECURITY_WEP_40: key_size = 5; break; case WF_SECURITY_WEP_104: key_size = 13; break; } memcpy(CPElements.securityKey, CFGCXT.key, key_size); CPElements.securityKey[strlen((char*)(CFGCXT.key))] = 0; } /* Going to save the network type */ CPElements.networkType = CFGCXT.type; // Set the board to reboot and display reconnecting information strcpypgm2ram((char*)curHTTP.data, "/reconnect.htm"); curHTTP.httpStatus = HTTP_REDIRECT; /* * Set state here to inform that the Wifi device has config data and it is ready * to be acted upon. */ printf("\r\nFlagging to start config change!\r\n"); WF_START_EASY_CONFIG(); return HTTP_IO_DONE; ConfigFailure: //!lastFailure = TRUE; strcpypgm2ram((char*)curHTTP.data, "/error.htm"); curHTTP.httpStatus = HTTP_REDIRECT; return HTTP_IO_DONE; }
/* POST method is used only for setting the WiFi parameters in the board */ HTTP_IO_RESULT HTTPExecutePost(void) { BYTE name[20]; WORD len; char buf[100]; // Load the file name // Make sure BYTE filename[] above is large enough for your longest name MPFSGetFilename(curHTTP.file, name, 20); if(strcmppgm2ram((char*)name, (ROM char*)"connecting.htm") != 0) return HTTP_IO_DONE; // Loop while data remains while(curHTTP.byteCount) { // Check for a complete variable len = TCPFind(sktHTTP, '&', 0, FALSE); if(len == 0xffff) {// Check if this is the last one if(TCPIsGetReady(sktHTTP) == curHTTP.byteCount) len = curHTTP.byteCount - 1; else // Wait for more data { return HTTP_IO_NEED_DATA; } } // Make sure we don't overflow if(len > HTTP_MAX_DATA_LEN-2) { curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, len+1); continue; } // Read the next variable and parse HTTPReadPostValue((BYTE*)buf,100); // Figure out which variable it is if(memcmppgm2ram(buf, (ROM void*)"host", 4) == 0) { strcpy(config_parms.MyHost,&buf[5]); } else if(memcmppgm2ram(buf, (ROM void*)"ssid", 4) == 0) { strcpy(config_parms.MySSID,&buf[5]); } else if(memcmppgm2ram(buf, (ROM void*)"select1", 7) == 0) { if (memcmppgm2ram(&buf[8],(ROM void*)"adhoc", 5) == 0) { config_parms.networkType = (BYTE)'A'; } else if (memcmppgm2ram(&buf[8],(ROM void*)"infra", 5) == 0) { config_parms.networkType = (BYTE)'I'; } } else if(memcmppgm2ram(buf, (ROM void*)"select2", 7) == 0) { if (memcmppgm2ram(&buf[8],(ROM void*)"auto", 4) == 0) { config_parms.SecurityMode = WF_SECURITY_WPA_AUTO_WITH_KEY; } else if (memcmppgm2ram(&buf[8],(ROM void*)"open", 4) == 0) { config_parms.SecurityMode = WF_SECURITY_OPEN; } } else if(memcmppgm2ram(buf, (ROM void*)"pphrase", 7) == 0) { strcpy((char *)config_parms.SecurityPhrase,&buf[8]); } else if(memcmppgm2ram(buf, (ROM void*)"chkbx", 5) == 0) { if (memcmppgm2ram(&buf[6],(ROM void*)"on", 2) == 0) { config_parms.UseKey = TRUE; } else { config_parms.UseKey = FALSE; } } else if(memcmppgm2ram(buf, (ROM void*)"pkey", 4) == 0) { strcpy((char *)config_parms.SecurityKey, &buf[5]); } else if(memcmppgm2ram(buf, (ROM void*)"ip", 2) == 0) { strcpy(config_parms.MyIPAddr,&buf[3]); } else if(memcmppgm2ram(buf, (ROM void*)"subnetmask", 10) == 0) { strcpy(config_parms.MyMask,&buf[11]); } else if(memcmppgm2ram(buf, (ROM void*)"gateway", 7) == 0) { strcpy(config_parms.MyGateway,&buf[8]); } else if(memcmppgm2ram(buf, (ROM void*)"pdns", 4) == 0) { strcpy(config_parms.PrimaryDNSServer,&buf[5]); } else if(memcmppgm2ram(buf, (ROM void*)"sdns", 4) == 0) { strcpy(config_parms.SecondaryDNSServer,&buf[5]); } else if(memcmppgm2ram(buf, (ROM void*)"submit", 6) == 0) // see which button was pressed { config_parms.flag = 1; } else if(memcmppgm2ram(buf, (ROM void*)"connect", 7) == 0) // see which button was pressed { config_parms.flag = 2; } } if (config_parms.flag == 1) { SaveWiFiStateToFlash(); CheckAndWriteCustom(); config_parms.DoConnectFlag = FALSE; config_parms.flag = 0; } else if (config_parms.flag == 2) { SaveWiFiStateToFlash(); CheckAndWriteCustom(); config_parms.DoConnectFlag = TRUE; config_parms.flag = 0; } return HTTP_IO_DONE; }