static void HTTPHeaderParseCookie(void) { WORD lenA, lenB; // Verify there's enough space lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE); if(lenB >= curHTTP.data + HTTP_MAX_DATA_LEN - curHTTP.ptrData - 2) {// If not, overflow curHTTP.httpStatus = HTTP_OVERFLOW; smHTTP = SM_HTTP_SERVE_HEADERS; return; } // While a CRLF is not immediate, grab a cookie value while(lenB != 0) { // Look for a ';' and use the shorter of that or a CRLF lenA = TCPFind(sktHTTP, ';', 0, FALSE); // Read to the terminator curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.ptrData, mMIN(lenA, lenB)); // Insert an & to anticipate another cookie *(curHTTP.ptrData++) = '&'; // If semicolon, trash it and whitespace if(lenA < lenB) { TCPGet(sktHTTP, NULL); while(TCPFind(sktHTTP, ' ', 0, FALSE) == 0) TCPGet(sktHTTP, NULL); } // Find the new distance to the CRLF lenB = TCPFindROMArray(sktHTTP, HTTP_CRLF, HTTP_CRLF_LEN, 0, FALSE); } return; }
/********************************************************************* * Function: void TelnetTask(void) * * PreCondition: Stack is initialized() * * Input: None * * Output: None * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ void TelnetTask(void) { BYTE i; BYTE vTelnetSession; WORD w, w2; TCP_SOCKET MySocket; enum { SM_HOME = 0, SM_PRINT_LOGIN, SM_GET_LOGIN, SM_GET_PASSWORD, SM_GET_PASSWORD_BAD_LOGIN, SM_AUTHENTICATED, SM_REFRESH_VALUES } TelnetState; static TCP_SOCKET hTelnetSockets[MAX_TELNET_CONNECTIONS]; static BYTE vTelnetStates[MAX_TELNET_CONNECTIONS]; static BOOL bInitialized = FALSE; // Perform one time initialization on power up if(!bInitialized) { for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++) { hTelnetSockets[vTelnetSession] = INVALID_SOCKET; vTelnetStates[vTelnetSession] = SM_HOME; } bInitialized = TRUE; } // Loop through each telnet session and process state changes and TX/RX data for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++) { // Load up static state information for this session MySocket = hTelnetSockets[vTelnetSession]; TelnetState = vTelnetStates[vTelnetSession]; // Reset our state if the remote client disconnected from us if(MySocket != INVALID_SOCKET) { if(TCPWasReset(MySocket)) TelnetState = SM_PRINT_LOGIN; } // Handle session state switch(TelnetState) { case SM_HOME: // Connect a socket to the remote TCP server MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET); // Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available // If this ever happens, you need to go add one to TCPIPConfig.h if(MySocket == INVALID_SOCKET) break; TelnetState++; break; case SM_PRINT_LOGIN: // Make certain the socket can be written to if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle)) break; // Place the application protocol data into the transmit buffer. TCPPutROMString(MySocket, strTitle); // Send the packet TCPFlush(MySocket); TelnetState++; case SM_GET_LOGIN: // Make sure we can put the password prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the username -- case insensitive w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_USERNAME, sizeof(TELNET_USERNAME)-1, 0, TRUE); if((w2 != 0u) || !((sizeof(TELNET_USERNAME)-1 == w) || (sizeof(TELNET_USERNAME) == w))) { // Did not find the username, but let's pretend we did so we don't leak the user name validity TelnetState = SM_GET_PASSWORD_BAD_LOGIN; } else { TelnetState = SM_GET_PASSWORD; } // Username verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the password prompt TCPPutROMString(MySocket, strPassword); TCPFlush(MySocket); break; case SM_GET_PASSWORD: case SM_GET_PASSWORD_BAD_LOGIN: // Make sure we can put the authenticated prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the password -- case sensitive w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_PASSWORD, sizeof(TELNET_PASSWORD)-1, 0, FALSE); if((w2 != 3u) || !((sizeof(TELNET_PASSWORD)-1 == w-3) || (sizeof(TELNET_PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN)) { // Did not find the password TelnetState = SM_PRINT_LOGIN; TCPPutROMString(MySocket, strAccessDenied); TCPDisconnect(MySocket); break; } // Password verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the authenticated prompt TCPPutROMString(MySocket, strAuthenticated); TelnetState = SM_AUTHENTICATED; // No break case SM_AUTHENTICATED: if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4) break; TCPPutROMString(MySocket, strDisplay); TelnetState++; // All future characters will be bold TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m"); case SM_REFRESH_VALUES: if(TCPIsPutReady(MySocket) >= 78u) { //[10;1] //"SNTP Time: (disabled)\r\n" //"Analog: 1023\r\n" //"Buttons: 3 2 1 0\r\n" //"LEDs: 7 6 5 4 3 2 1 0\r\n" // Write current UTC seconds from SNTP module, if it is enable // and has changed. Note that conversion from a DWORD to an // ASCII string can take a lot of CPU power, so we only print // this if the value has changed. #if defined(STACK_USE_SNTP_CLIENT) { static DWORD dwTime; BYTE vTime[11]; if(dwTime != SNTPGetUTCSeconds()) { // Position cursor at Line 10, Col 15 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;15f"); dwTime = SNTPGetUTCSeconds(); ultoa(dwTime, vTime); TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 10-strlen((char*)vTime)); TCPPutString(MySocket, vTime); } } #endif // Position cursor at Line 11, Col 21 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;21f"); // Put analog value with space padding on right side for 4 characters TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 4-strlen((char*)AN0String)); TCPPutString(MySocket, AN0String); // Put Buttons TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;18f"); TCPPut(MySocket, BUTTON3_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON2_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON1_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON0_IO ? '1':'0'); // Put LEDs TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;10f"); TCPPut(MySocket, LED1_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED0_IO ? '1':'0'); // Put cursor at beginning of next line TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[14;1f"); // Send the data out immediately TCPFlush(MySocket); } if(TCPIsGetReady(MySocket)) { TCPGet(MySocket, &i); switch(i) { case '\r': case 'q': case 'Q': if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye)) TCPPutROMString(MySocket, strGoodBye); TCPDisconnect(MySocket); TelnetState = SM_PRINT_LOGIN; break; } } break; } // Save session state back into the static array hTelnetSockets[vTelnetSession] = MySocket; vTelnetStates[vTelnetSession] = TelnetState; } }
/********************************************************************* * Function: void TelnetTask(void) * * PreCondition: Stack is initialized() * * Input: None * * Output: None * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ void TelnetTask(void) { BYTE i; WORD w, w2; static TCP_SOCKET MySocket = INVALID_SOCKET; static enum _TelnetState { SM_HOME = 0, SM_PRINT_LOGIN, SM_GET_LOGIN, SM_GET_PASSWORD, SM_GET_PASSWORD_BAD_LOGIN, SM_AUTHENTICATED, SM_REFRESH_VALUES, } TelnetState = SM_HOME; // Reset our state if the remote client disconnected from us if(MySocket != INVALID_SOCKET) { if(TCPWasReset(MySocket)) TelnetState = SM_PRINT_LOGIN; } switch(TelnetState) { case SM_HOME: // Connect a socket to the remote TCP server MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET); // Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available // If this ever happens, you need to go add one to TCPIPConfig.h if(MySocket == INVALID_SOCKET) break; TelnetState++; break; case SM_PRINT_LOGIN: // Make certain the socket can be written to if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle)) break; // Place the application protocol data into the transmit buffer. TCPPutROMString(MySocket, strTitle); // Send the packet TCPFlush(MySocket); TelnetState++; case SM_GET_LOGIN: // Make sure we can put the password prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the username -- case insensitive w2 = TCPFindROMArray(MySocket, (ROM BYTE*)USERNAME, sizeof(USERNAME)-1, 0, TRUE); if((w2 != 0) || !((sizeof(USERNAME)-1 == w) || (sizeof(USERNAME) == w))) { // Did not find the username, but let's pretend we did so we don't leak the user name validity TelnetState = SM_GET_PASSWORD_BAD_LOGIN; } else { TelnetState = SM_GET_PASSWORD; } // Username verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the password prompt TCPPutROMString(MySocket, strPassword); TCPFlush(MySocket); break; case SM_GET_PASSWORD: case SM_GET_PASSWORD_BAD_LOGIN: // Make sure we can put the authenticated prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the password -- case sensitive w2 = TCPFindROMArray(MySocket, (ROM BYTE*)PASSWORD, sizeof(PASSWORD)-1, 0, FALSE); if((w2 != 3) || !((sizeof(PASSWORD)-1 == w-3) || (sizeof(PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN)) { // Did not find the password TelnetState = SM_PRINT_LOGIN; TCPPutROMString(MySocket, strAccessDenied); TCPDisconnect(MySocket); break; } // Password verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the authenticated prompt TCPPutROMString(MySocket, strAuthenticated); TelnetState = SM_AUTHENTICATED; // No break case SM_AUTHENTICATED: if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4) break; TCPPutROMString(MySocket, strDisplay); TelnetState++; // All future characters will be bold TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m"); case SM_REFRESH_VALUES: if(TCPIsPutReady(MySocket) >= 60u) { //[10;1] //"Analog: 1023\r\n" //"Buttons: 3 2 1 0\r\n" //"LEDs: 7 6 5 4 3 2 1 0\r\n" // Position cursor at Line 10, Col 21 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;21f"); // Put analog value with space padding on right side for 4 characters TCPPutROMArray(MySocket, (ROM BYTE*)" ", 4-strlen((char*)AN0String)); TCPPutString(MySocket, AN0String); // Put Buttons TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;18f"); TCPPut(MySocket, BUTTON3_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON2_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON1_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, BUTTON0_IO ? '1':'0'); // Put LEDs TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;10f"); TCPPut(MySocket, LED7_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED6_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED5_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED4_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED3_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED2_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED1_IO ? '1':'0'); TCPPut(MySocket, ' '); TCPPut(MySocket, LED0_IO ? '1':'0'); // Put cursor at beginning of next line TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;1f"); // Send the data out immediately TCPFlush(MySocket); } if(TCPIsGetReady(MySocket)) { TCPGet(MySocket, &i); switch(i) { case '\r': case 'q': case 'Q': if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye)) TCPPutROMString(MySocket, strGoodBye); TCPDisconnect(MySocket); TelnetState = SM_PRINT_LOGIN; break; } } break; } }
/***************************************************************************** Function: HTTP_IO_RESULT HTTPExecutePost(void) This function processes every POST request from the pages. ***************************************************************************/ HTTP_IO_RESULT HTTPExecutePost(void) { // Resolve which function to use and pass along BYTE filename[20]; int len; // Load the file name // Make sure BYTE filename[] above is large enough for your longest name MPFSGetFilename(curHTTP.file, filename, sizeof(filename)); while(curHTTP.byteCount) { // Check for a complete variable len = TCPFind(sktHTTP, '&', 0, FALSE); if(len == 0xffff) { // Check if is the last post, otherwise continue in the loop if( TCPIsGetReady(sktHTTP) == curHTTP.byteCount) len = curHTTP.byteCount - 1; else { return HTTP_IO_NEED_DATA; // No last post, we need more data } } if(len > HTTP_MAX_DATA_LEN - 2) { // Make sure we don't overflow curHTTP.byteCount -= TCPGetArray(sktHTTP, (BYTE*)String_post, len+1); continue; } len = TCPGetArray(sktHTTP,curHTTP.data, len+1); curHTTP.byteCount -= len; curHTTP.data[len] = '\0'; HTTPURLDecode(curHTTP.data); // NETWORK TYPE SELECTION: ADHOC/INFRASTRUCTURE/SOFTAP(WIFI G only) if(memcmppgm2ram(curHTTP.data,(ROM void*)"NETTYPE", 7) == 0) { memcpy(String_post,(void*)&curHTTP.data[8], len-8); WFSetParam(NETWORK_TYPE, String_post); } // DHCP CLIENT ENABLING/DISABLING else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DHCPCL", 6) == 0) { memcpy(String_post,(void*)&curHTTP.data[7], len-7); if (String_post [0] == 'd') WFSetParam(DHCP_ENABLE , DISABLED); else WFSetParam(DHCP_ENABLE , ENABLED); } // IP ADDRESS OF THE DEVICE else if(memcmppgm2ram(curHTTP.data,(ROM void*)"IPADDR", 6) == 0) { memcpy(String_post,(void*)&curHTTP.data[7], len-7); WFSetParam(MY_IP_ADDR, String_post); } // SUBNET MASK else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SUBNET", 6) == 0) { memcpy(String_post,(void*)&curHTTP.data[7], len-7); WFSetParam(SUBNET_MASK, String_post); } // DEFAULT GATEWAY else if(memcmppgm2ram(curHTTP.data,(ROM void*)"GATEWAY", 7) == 0) { memcpy(String_post,(void*)&curHTTP.data[8], len-8); WFSetParam(MY_GATEWAY, String_post); } // DNS SERVER #1 else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DNS1", 4) == 0) { memcpy(String_post,(void*)&curHTTP.data[5], len-5); WFSetParam(PRIMARY_DNS, String_post); } // DNS SERVER #2 else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DNS2", 4) == 0) { memcpy(String_post,(void*)&curHTTP.data[5], len-5); WFSetParam(SECONDARY_DNS, String_post); } // SSID else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SSID", 4) == 0) { memcpy(String_post,(void*)&curHTTP.data[5], len-5); WFSetParam(SSID_NAME, String_post); } // SECURITY TYPE else if(memcmppgm2ram(curHTTP.data,(ROM void*)"SECTYPE", 7) == 0) { memcpy(String_post,(void*)&curHTTP.data[8], len-8); if (String_post[2] == 'E') { security = 0; WFSetSecurity(WF_SECURITY_OPEN, "", 0, 0); ParamSet = TRUE; } else if (String_post[2] == 'A') { if (String_post[3] == '2') security = 5; else security = 3; } else if (String_post[2] == 'P') { if (String_post[3] == '4') security = 1; else security = 2; } } // ---------- SECURITY KEY AND PASSWORD ---------- // WEP40 KEY else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP40KEY4", 9) == 0) { if (security == 1) { if (len > 10) { int j = 0, j1 = 0; WORD_VAL dummy; for ( j=0; j<40; j=j+2) { memcpy(String_post,(void*)&curHTTP.data[10+j], 2); dummy.v[1] = String_post[0]; dummy.v[0] = String_post[1]; PassKey[j1] = hexatob(dummy); j1++; } PassKey[j1]= '\0'; security = 1; } } } // WEP40 KEY INDEX else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP40KEYID", 10) == 0) { memcpy(String_post,(void*)&curHTTP.data[11], len-11); int k_index; k_index = atoi(String_post); k_index--; if (security == 1) { WFSetSecurity(WF_SECURITY_WEP_40, PassKey, 20, k_index); ParamSet = TRUE; } } // WEP104 KEY INDEX else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP104KEY", 9) == 0) { if (security == 2) { int j = 0, j1 = 0; WORD_VAL dummy; for ( j=0; j<32; j=j+2) { memcpy(String_post,(void*)&curHTTP.data[10+j], 2); dummy.v[1] = String_post[0]; dummy.v[0] = String_post[1]; PassKey[j1] = hexatob(dummy); j1++; } PassKey[j1]= '\0'; WFSetSecurity(WF_SECURITY_WEP_104, PassKey, 16, 0); ParamSet = TRUE; } } // WPA WITH PASSPHRASE else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPAPASS", 7) == 0) { if (security == 3) { if (len > 10) { memcpy(String_post,(void*)&curHTTP.data[8], len-8); WFSetSecurity(WF_SECURITY_WPA_WITH_PASS_PHRASE, String_post, len-9, 0); ParamSet = TRUE; } } } // WPA WITH PASSKEY else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPAKEY", 6) == 0) { if (security == 3) { if (len > 10) { int j = 0, j1 = 0; WORD_VAL dummy; for ( j=0; j<64; j=j+2) { memcpy(String_post,(void*)&curHTTP.data[7+j], 2); dummy.v[1] = String_post[0]; dummy.v[0] = String_post[1]; PassKey[j1] = hexatob(dummy); j1++; } PassKey[j1]= '\0'; WFSetSecurity(WF_SECURITY_WPA_WITH_KEY, PassKey, 32, 0); ParamSet = TRUE; } } } // WPA2 WITH PASSPHRASE else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPA2PASS", 8) == 0) { if (len > 10) { memcpy(String_post,(void*)&curHTTP.data[9], len-9); WFSetSecurity(WF_SECURITY_WPA2_WITH_PASS_PHRASE, String_post, len-9, 0); ParamSet = TRUE; } } // WPA2 WITH PASSKEY else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WPA2KEY", 7) == 0) { if (len > 10) { int j = 0, j1 = 0; WORD_VAL dummy; for ( j=0; j<64; j=j+2) { memcpy(String_post,(void*)&curHTTP.data[8+j], 2); dummy.v[1] = String_post[0]; dummy.v[0] = String_post[1]; PassKey[j1] = hexatob(dummy); j1++; } PassKey[j1]= '\0'; WFSetSecurity(WF_SECURITY_WPA2_WITH_KEY, PassKey, 32, 0); ParamSet = TRUE; } } /* EMAIL */ else if (memcmppgm2ram(curHTTP.data,(ROM void*)"TXEMAIL", 7) == 0) { memcpy(MY_EMAIL,(void*)&curHTTP.data[8], len-8); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"USEREMAIL", 9) == 0) { memcpy(MY_EMAIL_USER,(void*)&curHTTP.data[10], len-10); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"PASSEMAIL", 9) == 0) { memcpy(MY_EMAIL_PASS,(void*)&curHTTP.data[10], len-10); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"SERVER", 6) == 0) { memcpy(MY_SMTP,(void*)&curHTTP.data[7], len-7); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"PORT", 4) == 0) { memcpy(MY_SMTP_PORT,(void*)&curHTTP.data[5], len-5); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"SUBJ", 4) == 0) { memcpy(EMAIL_SUBJECT,(void*)&curHTTP.data[5], len-5); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"TEXT", 4) == 0) { memcpy(EMAIL_BODY,(void*)&curHTTP.data[5], len-5); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"RXEMAIL", 7) == 0) { memcpy(EMAIL_DEST,(void*)&curHTTP.data[8], len-8); } /* ALARM */ else if (memcmppgm2ram(curHTTP.data,(ROM void*)"GMT", 3) == 0) { memcpy(GMT,(void*)&curHTTP.data[4], len-4); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"START", 5) == 0) { memcpy(start_string,(void*)&curHTTP.data[6], len-6); } else if (memcmppgm2ram(curHTTP.data,(ROM void*)"STOP", 4) == 0) { memcpy(stop_string,(void*)&curHTTP.data[5], len-5); } } 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; }
/********************************************************************* * Function: static void HTTPProcess(void) * * PreCondition: HTTPInit() called and curHTTP loaded * * Input: None * * Output: None * * Side Effects: None * * Overview: Serves the current HTTP connection in curHTTP * * Note: None ********************************************************************/ static void HTTPProcess(void) { WORD lenA, lenB; BYTE c, i; BOOL isDone; BYTE *ext; BYTE buffer[HTTP_MAX_HEADER_LEN+1]; do { isDone = TRUE; // If a socket is disconnected at any time // forget about it and return to idle state. if(TCPWasReset(sktHTTP)) { smHTTP = SM_HTTP_IDLE; // Make sure any opened files are closed if(curHTTP.file != MPFS_INVALID_HANDLE) { MPFSClose(curHTTP.file); curHTTP.file = MPFS_INVALID_HANDLE; } if(curHTTP.offsets != MPFS_INVALID_HANDLE) { MPFSClose(curHTTP.offsets); curHTTP.offsets = MPFS_INVALID_HANDLE; } // Adjust the TCP FIFOs for optimal reception of // the next HTTP request from the browser TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_GIVE_REST_TO_RX | TCP_ADJUST_PRESERVE_RX); } switch(smHTTP) { case SM_HTTP_IDLE: // Check how much data is waiting lenA = TCPIsGetReady(sktHTTP); // If a connection has been made, then process the request if(lenA) {// Clear out state info and move to next state curHTTP.ptrData = curHTTP.data; smHTTP = SM_HTTP_PARSE_REQUEST; curHTTP.isAuthorized = 0xff; curHTTP.hasArgs = FALSE; curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND; curHTTP.callbackPos = 0xffffffff; curHTTP.byteCount = 0; } // In all cases, we break // For new connections, this waits for the buffer to fill break; case SM_HTTP_PARSE_REQUEST: // Verify the entire first line is in the FIFO if(TCPFind(sktHTTP, '\n', 0, FALSE) == 0xffff) {// First line isn't here yet if(TCPGetRxFIFOFree(sktHTTP) == 0) {// If the FIFO is full, we overflowed curHTTP.httpStatus = HTTP_OVERFLOW; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; } if(TickGet() > curHTTP.callbackID) {// A timeout has occurred TCPDisconnect(sktHTTP); smHTTP = SM_HTTP_DISCONNECT; isDone = FALSE; } break; } // Reset the watchdog timer curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND; // Determine the request method lenA = TCPFind(sktHTTP, ' ', 0, FALSE); if(lenA > 5) lenA = 5; TCPGetArray(sktHTTP, curHTTP.data, lenA+1); if ( memcmppgm2ram(curHTTP.data, (ROM void*)"GET", 3) == 0) curHTTP.httpStatus = HTTP_GET; #if defined(HTTP_USE_POST) else if ( memcmppgm2ram(curHTTP.data, (ROM void*)"POST", 4) == 0) curHTTP.httpStatus = HTTP_POST; #endif else {// Unrecognized method, so return not implemented curHTTP.httpStatus = HTTP_NOT_IMPLEMENTED; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } // Find end of filename lenA = TCPFind(sktHTTP, ' ', 0, FALSE); lenB = TCPFindEx(sktHTTP, '?', 0, lenA, FALSE); lenA = mMIN(lenA, lenB); // If the file name is too long, then reject the request if(lenA > HTTP_MAX_DATA_LEN - HTTP_DEFAULT_LEN - 1) { curHTTP.httpStatus = HTTP_OVERFLOW; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } // Read in the filename and decode lenB = TCPGetArray(sktHTTP, curHTTP.data, lenA); curHTTP.data[lenB] = '\0'; HTTPURLDecode(curHTTP.data); // Check if this is an MPFS Upload #if defined(HTTP_MPFS_UPLOAD) if(memcmppgm2ram(&curHTTP.data[1], HTTP_MPFS_UPLOAD, strlenpgm(HTTP_MPFS_UPLOAD)) == 0) {// Read remainder of line, and bypass all file opening, etc. #if defined(HTTP_USE_AUTHENTICATION) curHTTP.isAuthorized = HTTPAuthenticate(NULL, NULL, &curHTTP.data[1]); #endif if(curHTTP.httpStatus == HTTP_GET) curHTTP.httpStatus = HTTP_MPFS_FORM; else curHTTP.httpStatus = HTTP_MPFS_UP; smHTTP = SM_HTTP_PARSE_HEADERS; isDone = FALSE; break; } #endif // If the last character is a not a directory delimiter, then try to open the file // String starts at 2nd character, because the first is always a '/' if(curHTTP.data[lenB-1] != '/') curHTTP.file = MPFSOpen(&curHTTP.data[1]); // If the open fails, then add our default name and try again if(curHTTP.file == MPFS_INVALID_HANDLE) { // Add the directory delimiter if needed if(curHTTP.data[lenB-1] != '/') curHTTP.data[lenB++] = '/'; // Add our default file name // If this is a loopback, then it's an SSL connection if(TCPIsLoopback(sktHTTP)) { strcpypgm2ram((void*)&curHTTP.data[lenB], HTTPS_DEFAULT_FILE); lenB += strlenpgm(HTTPS_DEFAULT_FILE); } else { strcpypgm2ram((void*)&curHTTP.data[lenB], HTTP_DEFAULT_FILE); lenB += strlenpgm(HTTP_DEFAULT_FILE); } // Try to open again curHTTP.file = MPFSOpen(&curHTTP.data[1]); } // Find the extension in the filename for(ext = curHTTP.data + lenB-1; ext != curHTTP.data; ext--) if(*ext == '.') break; // Compare to known extensions to determine Content-Type ext++; for(curHTTP.fileType = HTTP_TXT; curHTTP.fileType < HTTP_UNKNOWN; curHTTP.fileType++) if(!stricmppgm2ram(ext, (ROM void*)httpFileExtensions[curHTTP.fileType])) break; // Perform first round authentication (pass file name only) #if defined(HTTP_USE_AUTHENTICATION) curHTTP.isAuthorized = HTTPAuthenticate(NULL, NULL, &curHTTP.data[1]); #endif // If the file was found, see if it has an index if(curHTTP.file != MPFS_INVALID_HANDLE && (MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_HASINDEX) ) { curHTTP.data[lenB-1] = '#'; curHTTP.offsets = MPFSOpen(&curHTTP.data[1]); } // Read GET args, up to buffer size - 1 lenA = TCPFind(sktHTTP, ' ', 0, FALSE); if(lenA != 0) { curHTTP.hasArgs = TRUE; // Trash the '?' TCPGet(sktHTTP, &c); // Verify there's enough space lenA--; if(lenA >= HTTP_MAX_DATA_LEN - 2) { curHTTP.httpStatus = HTTP_OVERFLOW; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } // Read in the arguments and '&'-terminate in anticipation of cookies curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.data, lenA); *(curHTTP.ptrData++) = '&'; } // Clear the rest of the line lenA = TCPFind(sktHTTP, '\n', 0, FALSE); TCPGetArray(sktHTTP, NULL, lenA + 1); // Move to parsing the headers smHTTP = SM_HTTP_PARSE_HEADERS; // No break, continue to parsing headers case SM_HTTP_PARSE_HEADERS: // Loop over all the headers while(1) { // Make sure entire line is in the FIFO lenA = TCPFind(sktHTTP, '\n', 0, FALSE); if(lenA == 0xffff) {// If not, make sure we can receive more data if(TCPGetRxFIFOFree(sktHTTP) == 0) {// Overflow curHTTP.httpStatus = HTTP_OVERFLOW; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; } if(TickGet() > curHTTP.callbackID) {// A timeout has occured TCPDisconnect(sktHTTP); smHTTP = SM_HTTP_DISCONNECT; isDone = FALSE; } break; } // Reset the watchdog timer curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND; // If a CRLF is immediate, then headers are done if(lenA == 1) {// Remove the CRLF and move to next state TCPGetArray(sktHTTP, NULL, 2); smHTTP = SM_HTTP_AUTHENTICATE; isDone = FALSE; break; } // Find the header name, and use isDone as a flag to indicate a match lenB = TCPFindEx(sktHTTP, ':', 0, lenA, FALSE) + 2; isDone = FALSE; // If name is too long or this line isn't a header, ignore it if(lenB > sizeof(buffer)) { TCPGetArray(sktHTTP, NULL, lenA+1); continue; } // Read in the header name TCPGetArray(sktHTTP, buffer, lenB); buffer[lenB-1] = '\0'; lenA -= lenB; // Compare header read to ones we're interested in for(i = 0; i < HTTP_NUM_HEADERS; i++) { if(strcmppgm2ram((char*)buffer, (ROM char *)HTTPRequestHeaders[i]) == 0) {// Parse the header and stop the loop HTTPHeaderParseLookup(i); isDone = TRUE; break; } } // Clear the rest of the line, and call the loop again if(isDone) {// We already know how much to remove unless a header was found lenA = TCPFind(sktHTTP, '\n', 0, FALSE); } TCPGetArray(sktHTTP, NULL, lenA+1); } break; case SM_HTTP_AUTHENTICATE: #if defined(HTTP_USE_AUTHENTICATION) // Check current authorization state if(curHTTP.isAuthorized < 0x80) {// 401 error curHTTP.httpStatus = HTTP_UNAUTHORIZED; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; #if defined(HTTP_NO_AUTH_WITHOUT_SSL) if(!TCPIsLoopback(sktHTTP)) curHTTP.httpStatus = HTTP_SSL_REQUIRED; #endif break; } #endif // Parse the args string *curHTTP.ptrData = '\0'; curHTTP.ptrData = HTTPURLDecode(curHTTP.data); // If this is an MPFS upload form request, bypass to headers #if defined(HTTP_MPFS_UPLOAD) if(curHTTP.httpStatus == HTTP_MPFS_FORM) { smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } #endif // Move on to GET args, unless there are none smHTTP = SM_HTTP_PROCESS_GET; if(!curHTTP.hasArgs) smHTTP = SM_HTTP_PROCESS_POST; isDone = FALSE; curHTTP.hasArgs = FALSE; break; case SM_HTTP_PROCESS_GET: // Run the application callback HTTPExecuteGet() if(HTTPExecuteGet() == HTTP_IO_WAITING) {// If waiting for asynchronous process, return to main app break; } // Move on to POST data smHTTP = SM_HTTP_PROCESS_POST; case SM_HTTP_PROCESS_POST: #if defined(HTTP_USE_POST) // See if we have any new data if(TCPIsGetReady(sktHTTP) == curHTTP.callbackPos) { if(TickGet() > curHTTP.callbackID) {// If a timeout has occured, disconnect TCPDisconnect(sktHTTP); smHTTP = SM_HTTP_DISCONNECT; isDone = FALSE; break; } } if(curHTTP.httpStatus == HTTP_POST #if defined(HTTP_MPFS_UPLOAD) || (curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR) #endif ) { // Run the application callback HTTPExecutePost() #if defined(HTTP_MPFS_UPLOAD) if(curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR) { c = HTTPMPFSUpload(); if(c == HTTP_IO_DONE) { smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } } else #endif c = HTTPExecutePost(); // If waiting for asynchronous process, return to main app if(c == HTTP_IO_WAITING) {// return to main app and make sure we don't get stuck by the watchdog curHTTP.callbackPos = TCPIsGetReady(sktHTTP) - 1; break; } else if(c == HTTP_IO_NEED_DATA) {// If waiting for more data curHTTP.callbackPos = TCPIsGetReady(sktHTTP); curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND; // If more is expected and space is available, return to main app if(curHTTP.byteCount > 0 && TCPGetRxFIFOFree(sktHTTP) != 0) break; else {// Handle cases where application ran out of data or buffer space curHTTP.httpStatus = HTTP_INTERNAL_SERVER_ERROR; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } } } #endif // We're done with POST smHTTP = SM_HTTP_PROCESS_REQUEST; // No break, continue to sending request case SM_HTTP_PROCESS_REQUEST: // Check for 404 if(curHTTP.file == MPFS_INVALID_HANDLE) { curHTTP.httpStatus = HTTP_NOT_FOUND; smHTTP = SM_HTTP_SERVE_HEADERS; isDone = FALSE; break; } // Set up the dynamic substitutions curHTTP.byteCount = 0; if(curHTTP.offsets == MPFS_INVALID_HANDLE) {// If no index file, then set next offset to huge curHTTP.nextCallback = 0xffffffff; } else {// Read in the next callback index MPFSGetLong(curHTTP.offsets, &(curHTTP.nextCallback)); } // Move to next state smHTTP = SM_HTTP_SERVE_HEADERS; case SM_HTTP_SERVE_HEADERS: // We're in write mode now: // Adjust the TCP FIFOs for optimal transmission of // the HTTP response to the browser TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_GIVE_REST_TO_TX); // Send headers TCPPutROMString(sktHTTP, (ROM BYTE*)HTTPResponseHeaders[curHTTP.httpStatus]); // If this is a redirect, print the rest of the Location: header if(curHTTP.httpStatus == HTTP_REDIRECT) { TCPPutString(sktHTTP, curHTTP.data); TCPPutROMString(sktHTTP, (ROM BYTE*)"\r\n\r\n304 Redirect: "); TCPPutString(sktHTTP, curHTTP.data); TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CRLF); } // If not GET or POST, we're done if(curHTTP.httpStatus != HTTP_GET && curHTTP.httpStatus != HTTP_POST) {// Disconnect smHTTP = SM_HTTP_DISCONNECT; break; } // Output the content type, if known if(curHTTP.fileType != HTTP_UNKNOWN) { TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Type: "); TCPPutROMString(sktHTTP, (ROM BYTE*)httpContentTypes[curHTTP.fileType]); TCPPutROMString(sktHTTP, HTTP_CRLF); } // Output the gzip encoding header if needed if(MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_ISZIPPED) { TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Encoding: gzip\r\n"); } // Output the cache-control TCPPutROMString(sktHTTP, (ROM BYTE*)"Cache-Control: "); if(curHTTP.httpStatus == HTTP_POST || curHTTP.nextCallback != 0xffffffff) {// This is a dynamic page or a POST request, so no cache TCPPutROMString(sktHTTP, (ROM BYTE*)"no-cache"); } else {// This is a static page, so save it for the specified amount of time TCPPutROMString(sktHTTP, (ROM BYTE*)"max-age="); TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CACHE_LEN); } TCPPutROMString(sktHTTP, HTTP_CRLF); // Check if we should output cookies if(curHTTP.hasArgs) smHTTP = SM_HTTP_SERVE_COOKIES; else {// Terminate the headers TCPPutROMString(sktHTTP, HTTP_CRLF); smHTTP = SM_HTTP_SERVE_BODY; } // Move to next stage isDone = FALSE; break; case SM_HTTP_SERVE_COOKIES: #if defined(HTTP_USE_COOKIES) // If the TX FIFO runs out of space, the client will never get CRLFCRLF // Avoid writing huge cookies - keep it under a hundred bytes max // Write cookies one at a time as space permits for(curHTTP.ptrRead = curHTTP.data; curHTTP.hasArgs != 0; curHTTP.hasArgs--) { // Write the header TCPPutROMString(sktHTTP, (ROM BYTE*)"Set-Cookie: "); // Write the name, URL encoded, one character at a time while((c = *(curHTTP.ptrRead++))) { if(c == ' ') TCPPut(sktHTTP, '+'); else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z') { TCPPut(sktHTTP, '%'); TCPPut(sktHTTP, btohexa_high(c)); TCPPut(sktHTTP, btohexa_low(c)); } else TCPPut(sktHTTP, c); } TCPPut(sktHTTP, '='); // Write the value, URL encoded, one character at a time while((c = *(curHTTP.ptrRead++))) { if(c == ' ') TCPPut(sktHTTP, '+'); else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z') { TCPPut(sktHTTP, '%'); TCPPut(sktHTTP, btohexa_high(c)); TCPPut(sktHTTP, btohexa_low(c)); } else TCPPut(sktHTTP, c); } // Finish the line TCPPutROMString(sktHTTP, HTTP_CRLF); } #endif // We're done, move to next state TCPPutROMString(sktHTTP, HTTP_CRLF); smHTTP = SM_HTTP_SERVE_BODY; case SM_HTTP_SERVE_BODY: isDone = FALSE; // Try to send next packet if(HTTPSendFile()) {// If EOF, then we're done so close and disconnect MPFSClose(curHTTP.file); curHTTP.file = MPFS_INVALID_HANDLE; smHTTP = SM_HTTP_DISCONNECT; isDone = TRUE; } // If the TX FIFO is full, then return to main app loop if(TCPIsPutReady(sktHTTP) == 0) isDone = TRUE; break; case SM_HTTP_SEND_FROM_CALLBACK: isDone = TRUE; // Check that at least the minimum bytes are free if(TCPIsPutReady(sktHTTP) < HTTP_MIN_CALLBACK_FREE) break; // Fill TX FIFO from callback HTTPPrint(curHTTP.callbackID); if(curHTTP.callbackPos == 0) {// Callback finished its output, so move on isDone = FALSE; smHTTP = SM_HTTP_SERVE_BODY; }// Otherwise, callback needs more buffer space, so return and wait break; case SM_HTTP_DISCONNECT: // Loopbacks have no wait state, so all data must be retrieved first if(TCPIsLoopback(sktHTTP) && TCPGetTxFIFOFull(sktHTTP) != 0) break; // Make sure any opened files are closed if(curHTTP.file != MPFS_INVALID_HANDLE) { MPFSClose(curHTTP.file); curHTTP.file = MPFS_INVALID_HANDLE; } if(curHTTP.offsets != MPFS_INVALID_HANDLE) { MPFSClose(curHTTP.offsets); curHTTP.offsets = MPFS_INVALID_HANDLE; } TCPDisconnect(sktHTTP); smHTTP = SM_HTTP_IDLE; break; } } while(!isDone); }
void TelnetTask(void) { BYTE vTelnetSession; WORD w, w2; TCP_SOCKET MySocket; char outstr[60]; // Perform one time initialization on power up if(!bInitialized) { for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++) { hTelnetSockets[vTelnetSession] = INVALID_SOCKET; vTelnetStates[vTelnetSession] = SM_HOME; } bInitialized = TRUE; } // Loop through each telnet session and process state changes and TX/RX data for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++) { // Load up static state information for this session MySocket = hTelnetSockets[vTelnetSession]; TelnetState = vTelnetStates[vTelnetSession]; // Reset our state if the remote client disconnected from us if(MySocket != INVALID_SOCKET) { if(TCPWasReset(MySocket)) TelnetState = SM_PRINT_LOGIN; } // Handle session state switch(TelnetState) { case SM_HOME: // Connect a socket to the remote TCP server MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET); // Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available // If this ever happens, you need to go add one to TCPIPConfig.h if(MySocket == INVALID_SOCKET) break; // Open an SSL listener if SSL server support is enabled #if defined(STACK_USE_SSL_SERVER) TCPAddSSLListener(MySocket, TELNETS_PORT); #endif TelnetState++; break; case SM_PRINT_LOGIN: #if defined(STACK_USE_SSL_SERVER) // Reject unsecured connections if TELNET_REJECT_UNSECURED is defined #if defined(TELNET_REJECT_UNSECURED) if(!TCPIsSSL(MySocket)) { if(TCPIsConnected(MySocket)) { TCPDisconnect(MySocket); TCPDisconnect(MySocket); break; } } #endif // Don't attempt to transmit anything if we are still handshaking. if(TCPSSLIsHandshaking(MySocket)) break; #endif sprintf(outstr,"%s%d%s",(char *)strTitle,AppConfig.SerialNumber,(char *)strTitle1); // Make certain the socket can be written to if(TCPIsPutReady(MySocket) < strlen(outstr)) break; // Place the application protocol data into the transmit buffer. TCPPutString(MySocket, (BYTE *)outstr); // Send the packet TCPFlush(MySocket); TelnetState++; case SM_GET_LOGIN: // Make sure we can put the password prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the username -- case insensitive w2 = TCPFindArray(MySocket, TELNET_USERNAME, strlen((char*)TELNET_USERNAME), 0, TRUE); if((w2 < 0) || !((w2 == ((w - strlen((char *)TELNET_USERNAME)) - 1)) || (w2 == (w - strlen((char *)TELNET_USERNAME))))) { // Did not find the username, but let's pretend we did so we don't leak the user name validity TelnetState = SM_GET_PASSWORD_BAD_LOGIN; } else { TelnetState = SM_GET_PASSWORD; } // Username verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the password prompt TCPPutROMString(MySocket, strPassword); TCPFlush(MySocket); break; case SM_GET_PASSWORD: case SM_GET_PASSWORD_BAD_LOGIN: // Make sure we can put the authenticated prompt if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated)) break; // See if the user pressed return w = TCPFind(MySocket, '\n', 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(MySocket) == 0u) { TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n"); TCPDisconnect(MySocket); } break; } // Search for the password -- case sensitive w2 = TCPFindArray(MySocket, TELNET_PASSWORD, strlen((char *)TELNET_PASSWORD), 0, FALSE); if((w2 != 3u) || !(((strlen((char *)TELNET_PASSWORD) == w-4)) || ((strlen((char *)TELNET_PASSWORD) == w-3))) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN)) { // Did not find the password TelnetState = SM_PRINT_LOGIN; TCPPutROMString(MySocket, strAccessDenied); TCPDisconnect(MySocket); break; } // Password verified, throw this line of data away TCPGetArray(MySocket, NULL, w + 1); // Print the authenticated prompt TCPPutROMString(MySocket, strAuthenticated); TCPFlush(MySocket); TelnetState = SM_AUTHENTICATED; // No break case SM_AUTHENTICATED: break; } // Save session state back into the static array hTelnetSockets[vTelnetSession] = MySocket; vTelnetStates[vTelnetSession] = TelnetState; } }