// Receive a NET msg from the OVMS server void net_msg_in(char* msg) { int k; if (net_msg_serverok == 0) { if (memcmppgm2ram(msg, (char const rom far*)"MP-S 0 ", 7) == 0) { net_msg_server_welcome(msg+7); } return; // otherwise ignore it } // Ok, we've got an encrypted message waiting for work. // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg,net_scratchpad); RC4_crypt(&rx_crypto1, &rx_crypto2, net_scratchpad, k); if (memcmppgm2ram(net_scratchpad, (char const rom far*)"MP-0 ", 5) == 0) { msg = net_scratchpad+5; switch (*msg) { case 'A': // PING strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 a"); if (net_msg_sendpending==0) { net_msg_start(); net_msg_encode_puts(); net_msg_send(); } break; case 'Z': // PEER connection if (msg[1] != '0') { net_apps_connected = 1; if (net_msg_sendpending==0) { net_msg_start(); net_msg_stat(); net_msg_gps(); net_msg_tpms(); net_msg_firmware(); net_msg_environment(); net_msg_send(); } } else { net_apps_connected = 0; } break; } } }
BOOL FTPVerify(char *login, char *password) { if ( !memcmppgm2ram(login, (ROM void*)FTP_USER_NAME, FTP_USER_NAME_LEN) ) { if ( !memcmppgm2ram(password, (ROM void*)FTP_USER_PASS, FTP_USER_PASS_LEN) ) return TRUE; } return FALSE; }
tZGBool convertAsciiToHexInPlace( tZGS8 *p_string, tZGU8 expectedHexBinSize ) { tZGS8 ascii_buffer[3]; tZGU8 hex_binary_index = 0; tZGS8 *hex_string_start = p_string; tZGU16 hex_buffer = 0; /* gobble up any hex prefix */ if ( memcmppgm2ram (hex_string_start, (const ROM FAR char*) "0x", 2) == 0 ) hex_string_start+=2; if ( strlen( (char *) hex_string_start) != (expectedHexBinSize*2) ) return kZGBoolFalse; while ( hex_binary_index < expectedHexBinSize ) { memcpy ( ascii_buffer, (const char*) hex_string_start, 2 ); ascii_buffer[2] = '\0'; /* convert the hex string to a machine hex value */ if ( !ConvertASCIIHexToBinary( ascii_buffer,&hex_buffer) ) return kZGBoolFalse; p_string[hex_binary_index++] = (tZGU8) hex_buffer; hex_string_start +=2; } return kZGBoolTrue; }
BOOL convertAsciiToHexInPlace( INT8 *p_string, UINT8 expectedHexBinSize ) { INT8 ascii_buffer[3]; UINT8 hex_binary_index = 0; INT8 *hex_string_start = p_string; UINT16 hex_buffer = 0; /* gobble up any hex prefix */ if ( memcmppgm2ram (hex_string_start, (const ROM FAR char*) "0x", 2) == 0 ) hex_string_start+=2; if ( strlen( (char *) hex_string_start) != (expectedHexBinSize*2) ) return FALSE; while ( hex_binary_index < expectedHexBinSize ) { memcpy ( ascii_buffer, (const char*) hex_string_start, 2 ); ascii_buffer[2] = '\0'; /* convert the hex string to a machine hex value */ if ( !ConvertASCIIHexToBinary( ascii_buffer,&hex_buffer) ) return FALSE; p_string[hex_binary_index++] = (UINT8) hex_buffer; hex_string_start +=2; } return TRUE; }
BYTE HTTPNeedsAuth(BYTE* cFile) { /* If you want to restrict the access to some page, include it in the folder "protect" */ if(memcmppgm2ram(cFile, (ROM void*)"protect", 7) == 0) return 0x00; /* Authentication will be needed later */ return 0x80; /* No authentication required */ }
/***************************************************************************** * FUNCTION: WFConsoleProcessEpilogue * * RETURNS: None * * PARAMS: None * * NOTES: Check if there is a left console msg, and release it if found. * *****************************************************************************/ void WFConsoleProcessEpilogue(void) { if (WFConsoleIsConsoleMsgReceived()) { if (( memcmppgm2ram(ARGV[0], "iperf", 5) == 0 ) || ( memcmppgm2ram(ARGV[0], "kill", 4) == 0 )) { return; } if ( memcmppgm2ram(ARGV[0], "help", 4) != 0 ) { WFConsolePrintRomStr("Unknown cmd: ", FALSE); WFConsolePrintRamStr(ARGV[0], TRUE); } WFConsoleReleaseConsoleMsg(); } }
void ClearNVM( NVM_ADDR *dest, WORD count ) { BYTE dummy = 0; WORD i; for (i=0; i<count; i++) { #if defined(VERIFY_WRITE) while (memcmppgm2ram( &dummy, (rom void *)dest, 1 )) #elif defined(CHECK_BEFORE_WRITE) if (memcmppgm2ram( &dummy, (rom void *)dest, 1 )) #endif { NVMWrite( dest, &dummy, 1 ); } dest++; CLRWDT(); } }
static FTP_COMMAND ParseFTPCommand(char *cmd) { FTP_COMMAND i; for ( i = 0; i < (FTP_COMMAND)FTP_COMMAND_TABLE_SIZE; i++ ) { if ( !memcmppgm2ram((void*)cmd, (ROM void*)FTPCommandString[i], 4) ) return i; } return FTP_CMD_UNKNOWN; }
/***************************************************************************** * FUNCTION: WFConsoleProcessEpilogue * * RETURNS: None * * PARAMS: None * * NOTES: Check if there is a left console msg, and release it if found. * *****************************************************************************/ void WFConsoleProcessEpilogue(void) { if (WFConsoleIsConsoleMsgReceived()) { #if defined(WF_EASY_CONFIG_DEMO) && !defined(__C32__) putrsUART("Iperf supports only PIC32 for EasyConfig\n\r"); #else if (( memcmppgm2ram(ARGV[0], "iperf", 5) == 0 ) || ( memcmppgm2ram(ARGV[0], "kill", 4) == 0 )) { return; } #endif if ( memcmppgm2ram(ARGV[0], "help", 4) != 0 ) { WFConsolePrintRomStr("Unknown cmd: ", FALSE); WFConsolePrintRamStr(ARGV[0], TRUE); } WFConsoleReleaseConsoleMsg(); } }
BYTE HTTPNeedsAuth(BYTE* cFile) { // If the filename begins with the folder "protect", then require auth if(memcmppgm2ram(cFile, (ROM void*)"protect", 7) == 0) return 0x00; // Authentication will be needed later // If the filename begins with the folder "snmp", then require auth if(memcmppgm2ram(cFile, (ROM void*)"snmp", 4) == 0) return 0x00; // Authentication will be needed later #if defined(HTTP_MPFS_UPLOAD_REQUIRES_AUTH) if(memcmppgm2ram(cFile, (ROM void*)"mpfsupload", 10) == 0) return 0x00; #endif // You can match additional strings here to password protect other files. // You could switch this and exclude files from authentication. // You could also always return 0x00 to require auth for all files. // You can return different values (0x00 to 0x79) to track "realms" for below. return 0x80; // No authentication required }
BOOL net_sms_in(char *caller, char *buf) { // The buf contains an SMS command // and caller contains the caller telephone number char *p; int k; // Convert SMS command (first word) to upper-case for (p=buf; ((*p!=0)&&(*p!=' ')); p++) if ((*p > 0x60) && (*p < 0x7b)) *p=*p-0x20; if (*p==' ') p++; // Command parsing... for (k=0; sms_cmdtable[k][0] != 0; k++) { if (memcmppgm2ram(buf, (char const rom far*)sms_cmdtable[k]+1, strlenpgm((char const rom far*)sms_cmdtable[k])-1) == 0) { BOOL result = FALSE; char *arguments = net_sms_initargs(p); if (!net_sms_checkauth(sms_cmdtable[k][0], caller, &arguments)) return FALSE; // auth error if (vehicle_fn_smshandler != NULL) { if (vehicle_fn_smshandler(TRUE, caller, buf, arguments)) return TRUE; // handled } result = (*sms_hfntable[k])(caller, buf, arguments); if (result) { if (vehicle_fn_smshandler != NULL) vehicle_fn_smshandler(FALSE, caller, buf, arguments); net_send_sms_finish(); } return result; } } if (vehicle_fn_smsextensions != NULL) { // Try passing the command to the vehicle module for handling... if (vehicle_fn_smsextensions(caller, buf, p)) return TRUE; // handled } // SMS didn't match any command pattern, forward to user via net msg net_msg_forward_sms(caller, buf); return FALSE; // unknown command }
/***************************************************************************** Function: HTTP_IO_RESULT HTTPExecutePost(void) Internal: See documentation in the TCP/IP Stack API or HTTP2.h for details. ***************************************************************************/ HTTP_IO_RESULT HTTPExecutePost(void) { // Resolve which function to use and pass along BYTE filename[20]; // Load the file name // Make sure BYTE filename[] above is large enough for your longest name MPFSGetFilename(curHTTP.file, filename, sizeof(filename)); /******************************************/ // If it's the configure.htm page, use settings to reconfigure wifi settings /******************************************/ #if defined(STACK_USE_EZ_CONFIG) if(!memcmppgm2ram(filename, "configure.htm", 13)) return HTTPPostWifiConfig(); #endif return HTTP_IO_DONE; }
BYTE* HTTPGetROMArg(BYTE *data, ROM BYTE* arg) { // Search through the array while bytes remain while(*data != '\0') { // Look for arg at current position if(!memcmppgm2ram(data, (ROM void*)arg, strlenpgm((ROM char*)arg) + 1)) {// Found it, so skip to next string return data + strlenpgm((ROM char*)arg) + 1; } // Skip past two strings (NUL bytes) data += strlen((char*)data) + 1; data += strlen((char*)data) + 1; } // Return NULL if not found return NULL; }
/***************************************************************************** Function: void _Validate(void) Summary: Validates the MPFS Image Description: Verifies that the MPFS image is valid, and reads the number of available files from the image header. This function is called on boot, and again after any image is written. Precondition: None Parameters: None Returns: None ***************************************************************************/ static void _Validate(void) { // If this function causes an Address Error Exception on 16-bit // platforms with code stored in internal Flash, make sure your // compiler memory model settings are correct. // // In MPLAB, choose Project Menu > Build Options > Project. // Select the MPLAB C30 tab and change Cagetory to Memory Model. // Ensure that Large Code Model is selected, and that the remaining // options are set to Default. // Validate the image and update numFiles MPFSStubs[0].addr = 0; MPFSStubs[0].bytesRem = 8; MPFSGetArray(0, (BYTE*)&fatCache, 6); if(!memcmppgm2ram((void*)&fatCache, (ROM void*)"MPFS\x02\x01", 6)) MPFSGetArray(0, (BYTE*)&numFiles, 2); else numFiles = 0; fatCacheID = MPFS_INVALID_FAT; }
void net_sms_in(char *caller, char *buf, unsigned char pos) { // The buf contains an SMS command // and caller contains the caller telephone number char *p; // Convert SMS command (first word) to upper-case for (p=buf; ((*p!=0)&&(*p!=' ')); p++) if ((*p > 0x60) && (*p < 0x7b)) *p=*p-0x20; // Command parsing... if (memcmppgm2ram(buf, (char const rom far*)"REGISTER ", 9) == 0) { // Register phone p = par_get(PARAM_REGPASS); if (strncmp(p,buf+9,strlen(p))==0) { par_set(PARAM_REGPHONE, caller); net_send_sms_rom(caller,NET_MSG_REGISTERED); } else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"PASS ", 5) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { par_set(PARAM_REGPASS, buf+5); net_send_sms_rom(caller,NET_MSG_PASSWORD); } else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"GPS ", 4) == 0) { p = par_get(PARAM_REGPASS); if (strncmp(p,buf+4,strlen(p))==0) net_sms_gps(caller); else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"GPS", 3) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_gps(caller); else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"STAT ", 5) == 0) { p = par_get(PARAM_REGPASS); if (strncmp(p,buf+5,strlen(p))==0) net_sms_stat(caller); else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"STAT", 4) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_stat(caller); else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"PARAMS?", 7) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_params(caller); else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"PARAMS ", 7) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { unsigned char d = PARAM_MILESKM; unsigned char x = 7; unsigned char y = x; while ((y<=(pos+1))&&(d < PARAM_MAX)) { if ((buf[y] == ' ')||(buf[y] == '\0')) { buf[y] = '\0'; if ((buf[x]=='-')&&(buf[x+1]=='\0')) buf[x] = '\0'; // Special case '-' is empty value par_set(d++, buf+x); x=++y; } else y++; } net_send_sms_rom(caller,NET_MSG_PARAMS); net_state_enter(NET_STATE_SOFTRESET); } else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"FEATURE ", 8) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { unsigned char y = 8; unsigned int f; while (y<=(pos+1)) { if ((buf[y] == ' ')||(buf[y] == '\0')) { buf[y] = '\0'; f = atoi(buf+8); if ((f>=0)&&(f<FEATURES_MAX)) sys_features[f] = atoi(buf+y+1); break; // Exit the while loop, as we are done } else y++; } } else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else if (memcmppgm2ram(buf, (char const rom far*)"RESET", 5) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { net_state_enter(NET_STATE_HARDRESET); } else { #ifndef OVMS_SUPPRESS_ACCESSDENIED_SMS net_send_sms_rom(caller,NET_MSG_DENIED); #endif } } else // SMS didn't match any command pattern, forward to user via net msg { net_msg_forward_sms(caller, buf); } }
void NVMWrite( NVM_ADDR *dest, BYTE *src, BYTE count ) { NVM_ADDR *pEraseBlock; BYTE *memBlock; BYTE *pMemBlock; BYTE writeIndex; BYTE writeStart; BYTE writeCount; BYTE oldGIEH; DWORD oldTBLPTR; #if defined(VERIFY_WRITE) while (memcmppgm2ram( src, (ROM void *)dest, count )) #elif defined(CHECK_BEFORE_WRITE) if (memcmppgm2ram( src, (ROM void *)dest, count )) #endif { if ((memBlock = SRAMalloc( ERASE_BLOCK_SIZE )) == NULL) return; #if 0 ConsolePutROMString( (ROM char * const)"NVMWrite at " ); PrintChar( (BYTE)(((WORD)dest>>8)&0xFF) ); PrintChar( (BYTE)((WORD)dest&0xFF) ); ConsolePutROMString( (ROM char * const)" count " ); PrintChar( count ); ConsolePutROMString( (ROM char * const)"\r\n" ); #endif // First, get the nearest "left" erase block boundary pEraseBlock = (NVM_ADDR*)((long)dest & (long)(~(ERASE_BLOCK_SIZE-1))); writeStart = (BYTE)((BYTE)dest & (BYTE)(ERASE_BLOCK_SIZE-1)); while( count ) { // Now read the entire erase block size into RAM. NVMRead(memBlock, (ROM void*)pEraseBlock, ERASE_BLOCK_SIZE); // Erase the block. // Erase flash memory, enable write control. EECON1 = 0x94; oldGIEH = 0; if ( INTCONbits.GIEH ) oldGIEH = 1; INTCONbits.GIEH = 0; #if defined(MCHP_C18) TBLPTR = (unsigned short long)pEraseBlock; #elif defined(HI_TECH_C) TBLPTR = (void*)pEraseBlock; #endif CLRWDT(); EECON2 = 0x55; EECON2 = 0xaa; EECON1bits.WR = 1; NOP(); EECON1bits.WREN = 0; oldTBLPTR = TBLPTR; if ( oldGIEH ) INTCONbits.GIEH = 1; // Modify 64-byte block of RAM buffer as per what is required. pMemBlock = &memBlock[writeStart]; while( writeStart < ERASE_BLOCK_SIZE && count ) { *pMemBlock++ = *src++; count--; writeStart++; } // After first block write, next start would start from 0. writeStart = 0; // Now write entire 64 byte block in one write block at a time. writeIndex = ERASE_BLOCK_SIZE / WRITE_BLOCK_SIZE; pMemBlock = memBlock; while( writeIndex ) { oldGIEH = 0; if ( INTCONbits.GIEH ) oldGIEH = 1; INTCONbits.GIEH = 0; TBLPTR = oldTBLPTR; // Load individual block writeCount = WRITE_BLOCK_SIZE; while( writeCount-- ) { TABLAT = *pMemBlock++; TBLWTPOSTINC(); } // Start the write process: reposition tblptr back into memory block that we want to write to. #if defined(MCHP_C18) _asm tblrdpostdec _endasm #elif defined(HITECH_C18) asm(" tblrd*-"); #endif // Write flash memory, enable write control. EECON1 = 0x84; CLRWDT(); EECON2 = 0x55; EECON2 = 0xaa; EECON1bits.WR = 1; NOP(); EECON1bits.WREN = 0; // One less block to write writeIndex--; TBLPTR++; oldTBLPTR = TBLPTR; if ( oldGIEH ) INTCONbits.GIEH = 1; } // Go back and do it all over again until we write all // data bytes - this time the next block. #if !defined(WIN32) pEraseBlock += ERASE_BLOCK_SIZE; #endif } SRAMfree( memBlock ); } }
void ProcessBlindsCommand(int channelNo) { BYTE *ptr; /* parameter command holds the requested action */ ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"command"); if (!ptr) return; if (!memcmppgm2ram(ptr, "move", 4)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"move\0"); ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"position"); if (!ptr) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } int position = atoi((char *)ptr); if (position < 0 || position > 100) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = MOVE; channels[channelNo - 1].channelStatus.blinds.channelStatus.targetPosition = ConvertTargetPositionFromPercent(channelNo, position); } else if (!memcmppgm2ram(ptr, "up", 2)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"up\0"); channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = MOVE; if (GetCurrentPositionInPercent(channelNo) == 100) channels[channelNo - 1].channelStatus.blinds.channelStatus.targetPosition = ConvertTargetPositionFromPercent(channelNo, 99); else channels[channelNo - 1].channelStatus.blinds.channelStatus.targetPosition = ConvertTargetPositionFromPercent(channelNo, 0); } else if (!memcmppgm2ram(ptr, "down", 4)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"down\0"); channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = MOVE; channels[channelNo - 1].channelStatus.blinds.channelStatus.targetPosition = ConvertTargetPositionFromPercent(channelNo, 100); } else if (!memcmppgm2ram(ptr, "stop", 4)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"stop\0"); channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = STOPPED; } else if (!memcmppgm2ram(ptr, "zero_cal", 8)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"zero_cal\0"); channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = MOVE_ZERO_CAL; } else if (!memcmppgm2ram(ptr, "max_cal", 7)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"max_cal\0"); channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = MOVE_MAX_CAL; } else if (!memcmppgm2ram(ptr, "set_max_pos", 11)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"set_max_pos\0"); /* read argument value from position paramenter */ int position = ReadPositionParameter(); if (position < 0) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.calibrationStatus.maxOpenStatus = CALIBRATED; channels[channelNo - 1].channelStatus.blinds.calibrationStatus.maxOpenPosition = position; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = STOPPED; SaveCalibrationStateToFlash(); } else if (!memcmppgm2ram(ptr, "set_part_pos", 12)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"set_part_pos\0"); /* read argument value from position paramenter */ int position = ReadPositionParameter(); if (position < 0) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.calibrationStatus.partOpenStatus = CALIBRATED; channels[channelNo - 1].channelStatus.blinds.calibrationStatus.partOpenPosition = position; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = STOPPED; SaveCalibrationStateToFlash(); } else if (!memcmppgm2ram(ptr, "set_cur_pos", 11)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"set_cur_pos\0"); /* read argument value from position paramenter */ int position = ReadPositionParameter(); if (position < 0) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelStatus.blinds.channelStatus.currentPosition = position; channels[channelNo - 1].channelStatus.blinds.channelStatus.state = STOPPED; } else if (!memcmppgm2ram(ptr, "set_power", 9)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"set_power\0"); int power = ReadPowerParameter(); if (power < 0) { channels[channelNo - 1].lastCommandStatus = ARG_ERR; return; } channels[channelNo - 1].lastCommandStatus = OK; channels[channelNo - 1].channelPower = power; SaveCalibrationStateToFlash(); } else if (!memcmppgm2ram(ptr, "up_btn_set", 10)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"up_btn_set\0"); int success = ReadAndSetButtonSettings(&(channels[channelNo - 1].channelStatus.blinds.channelStatus.buttonUpStatus.buttonSettings)); if (success == 0) { channels[channelNo - 1].lastCommandStatus = OK; SaveCalibrationStateToFlash(); } else { channels[channelNo - 1].lastCommandStatus = ARG_ERR; } } else if (!memcmppgm2ram(ptr, "down_btn_set", 12)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"down_btn_set\0"); int success = ReadAndSetButtonSettings(&(channels[channelNo - 1].channelStatus.blinds.channelStatus.buttonDownStatus.buttonSettings)); if (success == 0) { channels[channelNo - 1].lastCommandStatus = OK; SaveCalibrationStateToFlash(); } else { channels[channelNo - 1].lastCommandStatus = ARG_ERR; } } else { strncpy((char *)&channels[channelNo - 1].lastCommandName, (char *)ptr, 10); channels[channelNo - 1].lastCommandStatus = CMD_ERR; } }
void ProcessOnOffCommand(int channelNo) { BYTE *ptr; /* parameter command holds the requested action */ ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"command"); if (!ptr) return; if (!memcmppgm2ram(ptr, "on", 2)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"on\0"); channels[channelNo - 1].lastCommandStatus = OK; ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"value"); int value = atoi((char *)ptr); if (value < 0 || value > 100) { return; } switch (channels[channelNo - 1].channelType) { case ONOFF_COMMAND: case ONOFF_PULSE: channels[channelNo - 1].channelStatus.onOffCommand.onOffState = ONOFF_ON; break; case ONOFF_W_KEY: case ONOFF_W_BUTTON: channels[channelNo - 1].channelStatus.onOff.channelStatus.state = ONOFF_ON; channels[channelNo - 1].channelStatus.onOff.channelStatus.currentValue = value; break; default: break; } } else if (!memcmppgm2ram(ptr, "off", 3)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"off\0"); channels[channelNo - 1].lastCommandStatus = OK; switch (channels[channelNo - 1].channelType) { case ONOFF_COMMAND: case ONOFF_PULSE: channels[channelNo - 1].channelStatus.onOffCommand.onOffState = ONOFF_OFF; break; case ONOFF_W_KEY: case ONOFF_W_BUTTON: channels[channelNo - 1].channelStatus.onOff.channelStatus.state = ONOFF_OFF; break; default: break; } } else if (!memcmppgm2ram(ptr, "btn_set", 7)) { strcpypgm2ram((char *)&channels[channelNo - 1].lastCommandName, (ROM char*)"btn_set\0"); int success = -1; switch (channels[channelNo - 1].channelType) { case ONOFF_BUTTON: success = ReadAndSetButtonSettings(&(channels[channelNo - 1].channelStatus.onOffButton.buttonStatus.buttonSettings)); break; case ONOFF_W_KEY: case ONOFF_W_BUTTON: success = ReadAndSetButtonSettings(&(channels[channelNo - 1].channelStatus.onOff.channelStatus.buttonStatus.buttonSettings)); break; default: break; } if (success == 0) { channels[channelNo - 1].lastCommandStatus = OK; SaveCalibrationStateToFlash(); } else { channels[channelNo - 1].lastCommandStatus = ARG_ERR; } } else { strncpy((char *)&channels[channelNo - 1].lastCommandName, (char *)ptr, 10); channels[channelNo - 1].lastCommandStatus = CMD_ERR; } }
//////////////////////////////////////////////////////////////////////// // vehicle_initialise() // This function is an entry point from the main() program loop, and // gives the vehicle framework an opportunity to initialise itself. // void vehicle_initialise(void) { char *p; vehicle_fn_init = NULL; vehicle_fn_poll0 = NULL; vehicle_fn_poll1 = NULL; vehicle_fn_ticker1 = NULL; vehicle_fn_ticker10 = NULL; vehicle_fn_ticker60 = NULL; vehicle_fn_ticker300 = NULL; vehicle_fn_ticker600 = NULL; vehicle_fn_ticker = NULL; vehicle_fn_ticker10th = NULL; vehicle_fn_idlepoll = NULL; vehicle_fn_commandhandler = NULL; vehicle_fn_smshandler = NULL; vehicle_fn_smsextensions = NULL; // Clear the internal GPS flag, unless specifically requested by the module net_fnbits &= ~(NET_FN_INTERNALGPS); p = par_get(PARAM_VEHICLETYPE); if (p == NULL) { car_type[0] = 0; // Car is undefined car_type[1] = 0; car_type[2] = 0; car_type[3] = 0; car_type[4] = 0; } #ifdef OVMS_CAR_TESLAROADSTER else if (memcmppgm2ram(p, (char const rom far*)"TR", 2) == 0) { void vehicle_teslaroadster_initialise(void); vehicle_teslaroadster_initialise(); } #endif #ifdef OVMS_CAR_VOLTAMPERA else if (memcmppgm2ram(p, (char const rom far*)"VA", 2) == 0) { void vehicle_voltampera_initialise(void); vehicle_voltampera_initialise(); } #endif #ifdef OVMS_CAR_RENAULTTWIZY else if (memcmppgm2ram(p, (char const rom far*)"RT", 2) == 0) { void vehicle_twizy_initialise(void); vehicle_twizy_initialise(); } #endif #ifdef OVMS_CAR_OBDII else if (memcmppgm2ram(p, (char const rom far*)"O2", 2) == 0) { void vehicle_obdii_initialise(void); vehicle_obdii_initialise(); } #endif #ifdef OVMS_CAR_THINKCITY else if (memcmppgm2ram(p, (char const rom far*)"TC", 2) == 0) { void vehicle_thinkcity_initialise(void); vehicle_thinkcity_initialise(); } #endif #ifdef OVMS_CAR_NISSANLEAF else if (memcmppgm2ram(p, (char const rom far*)"NL", 2) == 0) { void vehicle_nissanleaf_initialise(void); vehicle_nissanleaf_initialise(); } #endif #ifdef OVMS_CAR_NONE else { void vehicle_none_initialise(void); vehicle_none_initialise(); } #endif RCONbits.IPEN = 1; // Enable Interrupt Priority PIE3bits.RXB1IE = 1; // CAN Receive Buffer 1 Interrupt Enable bit PIE3bits.RXB0IE = 1; // CAN Receive Buffer 0 Interrupt Enable bit IPR3 = 0b00000011; // high priority interrupts for Buffers 0 and 1 p = par_get(PARAM_MILESKM); can_mileskm = *p; }
/* 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; }
// Receive a NET msg from the OVMS server void net_msg_in(char* msg) { int k; char s; if (net_msg_serverok == 0) { if (memcmppgm2ram(msg, (char const rom far*)"MP-S 0 ", 7) == 0) { net_msg_server_welcome(msg+7); net_granular_tick = 3590; // Nasty hack to force a status transmission in 10 seconds } return; // otherwise ignore it } // Ok, we've got an encrypted message waiting for work. // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... CHECKPOINT(0x40) if (((strlen(msg)*4)/3) >= (NET_BUF_MAX-3)) { // Quick exit to reset link if incoming message is too big net_state_enter(NET_STATE_DONETINIT); return; } strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg,net_scratchpad); CHECKPOINT(0x41) RC4_crypt(&rx_crypto1, &rx_crypto2, net_scratchpad, k); if (memcmppgm2ram(net_scratchpad, (char const rom far*)"MP-0 ", 5) != 0) { net_state_enter(NET_STATE_DONETINIT); return; } msg = net_scratchpad+5; if ((*msg == 'E')&&(msg[1]=='M')) { // A paranoid-mode message from the server (or, more specifically, app) // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... msg += 2; // Now pointing to the code just before encrypted paranoid message strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg+1,net_msg_scratchpad+1); RC4_setup(&pm_crypto1, &pm_crypto2, pdigest, MD5_SIZE); for (k=0;k<1024;k++) { net_scratchpad[0] = 0; RC4_crypt(&pm_crypto1, &pm_crypto2, net_scratchpad, 1); } RC4_crypt(&pm_crypto1, &pm_crypto2, net_msg_scratchpad+1, k); net_msg_scratchpad[0] = *msg; // The code // The message is now out of paranoid mode... msg = net_msg_scratchpad; } CHECKPOINT(0x42) switch (*msg) { case 'A': // PING strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 a"); if (net_msg_sendpending==0) { net_msg_start(); net_msg_encode_puts(); net_msg_send(); } break; case 'Z': // PEER connection if (msg[1] != '0') { net_apps_connected = 1; if (net_msg_sendpending==0) { net_msg_start(); net_msgp_stat(0); net_msgp_gps(0); net_msgp_tpms(0); net_msgp_firmware(0); net_msgp_environment(0); net_msg_send(); } } else { net_apps_connected = 0; } break; case 'h': // Historical data acknowledgement #ifdef OVMS_LOGGINGMODULE logging_ack(atoi(msg+1)); #endif // #ifdef OVMS_LOGGINGMODULE break; case 'C': // COMMAND net_msg_cmd_in(msg+1); if (net_msg_sendpending==0) net_msg_cmd_do(); break; } }
/* Every request to the board is a GET request */ HTTP_IO_RESULT HTTPExecuteGet(void) { BYTE filename[12]; /* loads the filename - max length of file name is 12 characters */ MPFSGetFilename(curHTTP.file, filename, 12); /* board.cgi does not require any parameters so return immediatelly */ if (!memcmppgm2ram(filename, "board.cgi",9)) { return HTTP_IO_DONE; } #if defined(FW_UPGRADE_USE_OTA) if (!memcmppgm2ram(filename, "upgrade.cgi",11)) { ProcessUpgradeCommand(); return HTTP_IO_DONE; } #endif /* all other pages require at least the channel number parameter */ int channelNo = GetChannelNo(); if (channelNo == 0) return HTTP_IO_DONE; /* checks if the filename is known and the channel type requested coresponds with the channel */ if(!memcmppgm2ram(filename, "blinds.cgi", 10) && (channels[channelNo - 1].channelType == BLINDS)) { ProcessBlindsCommand(channelNo); return HTTP_IO_DONE; } if (!memcmppgm2ram(filename, "onoff.cgi", 9) && ((channels[channelNo - 1].channelType == ONOFF_W_KEY) || (channels[channelNo - 1].channelType == ONOFF_W_BUTTON))) { ProcessOnOffCommand(channelNo); return HTTP_IO_DONE; } if (!memcmppgm2ram(filename, "onoffbtn.cgi", 12) && (channels[channelNo - 1].channelType == ONOFF_BUTTON)) { ProcessOnOffCommand(channelNo); return HTTP_IO_DONE; } if (!memcmppgm2ram(filename, "onoffcmd.cgi", 12) && (channels[channelNo - 1].channelType == ONOFF_COMMAND)) { ProcessOnOffCommand(channelNo); return HTTP_IO_DONE; } if (!memcmppgm2ram(filename, "onoffpls.cgi", 12) && (channels[channelNo - 1].channelType == ONOFF_PULSE)) { ProcessOnOffCommand(channelNo); return HTTP_IO_DONE; } return HTTP_IO_DONE; }
/***************************************************************************** Function: HTTP_IO_RESULT HTTPExecuteGet(void) Internal: See documentation in the TCP/IP Stack API or HTTP2.h for details. ***************************************************************************/ HTTP_IO_RESULT HTTPExecuteGet(void) { BYTE *ptr; BYTE filename[20]; // Load the file name // Make sure BYTE filename[] above is large enough for your longest name MPFSGetFilename(curHTTP.file, filename, 20); /******************************************/ // If it's the leds.cgi LED update file /******************************************/ if(!memcmppgm2ram(filename, "leds.cgi", 8)) { // Determine which LED to toggle ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"led"); // Toggle the specified LED switch(*ptr) { case '1': LED1_INV(); break; case '2': LED2_INV(); break; default: break; } } /******************************************/ // If it's the wifi.xml scan file /******************************************/ if(!memcmppgm2ram(filename, "wifi.xml", 8)) { ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"scan"); if (ptr != NULL) { if(IS_SCAN_IN_PROGRESS(SCANCXT.scanState)) return HTTP_IO_WAITING; if(IS_SCAN_STATE_DISPLAY(SCANCXT.scanState)) return HTTP_IO_DONE; // Start Scan Request if (WFStartScan() == WF_SUCCESS) { SCAN_SET_DISPLAY(SCANCXT.scanState); SCANCXT.displayIdx = 0; return HTTP_IO_WAITING; } } } else { ; } return HTTP_IO_DONE; }
void main(void) { CLRWDT(); ENABLE_WDT(); currentPrimitive = NO_PRIMITIVE; NetworkDescriptor = NULL; orphanTries = 3; // If you are going to send data to a terminal, initialize the UART. ConsoleInit(); ConsolePutROMString( (ROM char *)"Universidade Paulista - UNIP\r\n" ); ConsolePutROMString( (ROM char *)"Daniel Gonçalves\r\n" ); ConsolePutROMString( (ROM char *)"Projeto: Baba Eletronica\r\n\r\n" ); ConsolePutROMString( (ROM char *)"\r\n\r\n\r\n*************************************\r\n" ); ConsolePutROMString( (ROM char *)"Microchip ZigBee(TM) Stack - v1.0-3.8\r\n\r\n" ); ConsolePutROMString( (ROM char *)"ZigBee RFD\r\n\r\n" ); ConsolePutROMString( (ROM char *)"Transceiver-MRF24J40\r\n\r\n" ); // Inicializa o Hardware HardwareInit(); // Inicializa a pilha ZigBee ZigBeeInit(); // ************************************************************************* // Outras Inicializações // ************************************************************************* myStatusFlags.Val = STATUS_FLAGS_INIT; // Endereço padrão do Coordenador destinationAddress.Val = 0x0000; // Inicializa os LEDS MOVE_SENSOR_LED = ON; LEVEL_SENSOR_LED = ON; // Habilita as interrupções RCONbits.IPEN = 1; INTCONbits.GIEH = 1; while (1) { CLRWDT(); ZigBeeTasks( ¤tPrimitive ); switch (currentPrimitive) { case NLME_NETWORK_DISCOVERY_confirm: currentPrimitive = NO_PRIMITIVE; if (!params.NLME_NETWORK_DISCOVERY_confirm.Status) { if (!params.NLME_NETWORK_DISCOVERY_confirm.NetworkCount) { ConsolePutROMString( (ROM char *)"No networks found. Trying again...\r\n" ); } else { // Save the descriptor list pointer so we can destroy it later. NetworkDescriptor = params.NLME_NETWORK_DISCOVERY_confirm.NetworkDescriptor; // Select a network to try to join. We're not going to be picky right now... currentNetworkDescriptor = NetworkDescriptor; SubmitJoinRequest: // not needed for new join params.NLME_JOIN_request.ScanDuration = ; // not needed for new join params.NLME_JOIN_request.ScanChannels = ; params.NLME_JOIN_request.PANId = currentNetworkDescriptor->PanID; ConsolePutROMString( (ROM char *)"Network(s) found. Trying to join " ); PrintChar( params.NLME_JOIN_request.PANId.byte.MSB ); PrintChar( params.NLME_JOIN_request.PANId.byte.LSB ); ConsolePutROMString( (ROM char *)".\r\n" ); params.NLME_JOIN_request.JoinAsRouter = FALSE; params.NLME_JOIN_request.RejoinNetwork = FALSE; params.NLME_JOIN_request.PowerSource = NOT_MAINS_POWERED; params.NLME_JOIN_request.RxOnWhenIdle = FALSE; params.NLME_JOIN_request.MACSecurity = FALSE; currentPrimitive = NLME_JOIN_request; } } else { PrintChar( params.NLME_NETWORK_DISCOVERY_confirm.Status ); ConsolePutROMString( (ROM char *)" Error finding network. Trying again...\r\n" ); } break; case NLME_JOIN_confirm: currentPrimitive = NO_PRIMITIVE; if (!params.NLME_JOIN_confirm.Status) { ConsolePutROMString( (ROM char *)"Join successful!\r\n" ); // Free the network descriptor list, if it exists. If we joined as an orphan, it will be NULL. while (NetworkDescriptor) { currentNetworkDescriptor = NetworkDescriptor->next; free( NetworkDescriptor ); NetworkDescriptor = currentNetworkDescriptor; } } else { PrintChar( params.NLME_JOIN_confirm.Status ); // If we were trying as an orphan, see if we have some more orphan attempts. if (ZigBeeStatus.flags.bits.bTryOrphanJoin) { // If we tried to join as an orphan, we do not have NetworkDescriptor, so we do // not have to free it. ConsolePutROMString( (ROM char *)" Could not join as orphan. " ); orphanTries--; if (orphanTries == 0) { ConsolePutROMString( (ROM char *)"Must try as new node...\r\n" ); ZigBeeStatus.flags.bits.bTryOrphanJoin = 0; } else { ConsolePutROMString( (ROM char *)"Trying again...\r\n" ); } } else { ConsolePutROMString( (ROM char *)" Could not join selected network. " ); currentNetworkDescriptor = currentNetworkDescriptor->next; if (currentNetworkDescriptor) { ConsolePutROMString( (ROM char *)"Trying next discovered network...\r\n" ); goto SubmitJoinRequest; } else { // We ran out of descriptors. Free the network descriptor list, and fall // through to try discovery again. ConsolePutROMString( (ROM char *)"Cleaning up and retrying discovery...\r\n" ); while (NetworkDescriptor) { currentNetworkDescriptor = NetworkDescriptor->next; free( NetworkDescriptor ); NetworkDescriptor = currentNetworkDescriptor; } } } } break; case NLME_LEAVE_indication: if (!memcmppgm2ram( ¶ms.NLME_LEAVE_indication.DeviceAddress, (ROM void *)&macLongAddr, 8 )) { ConsolePutROMString( (ROM char *)"We have left the network.\r\n" ); } else { ConsolePutROMString( (ROM char *)"Another node has left the network.\r\n" ); } currentPrimitive = NO_PRIMITIVE; break; case NLME_RESET_confirm: ConsolePutROMString( (ROM char *)"ZigBee Stack has been reset.\r\n" ); currentPrimitive = NO_PRIMITIVE; break; case NLME_SYNC_confirm: switch (params.NLME_SYNC_confirm.Status) { case SUCCESS: // I have heard from my parent, but it has no data for me. Note that // if my parent has data for me, I will get an APSDE_DATA_indication. ConsolePutROMString( (ROM char *)"No data available.\r\n" ); break; case NWK_SYNC_FAILURE: // I cannot communicate with my parent. ConsolePutROMString( (ROM char *)"I cannot communicate with my parent.\r\n" ); break; case NWK_INVALID_PARAMETER: // If we call NLME_SYNC_request correctly, this doesn't occur. ConsolePutROMString( (ROM char *)"Invalid sync parameter.\r\n" ); break; } currentPrimitive = NO_PRIMITIVE; break; case APSDE_DATA_indication: { WORD_VAL attributeId; BYTE command; BYTE data; BYTE dataLength; //BYTE dataType; BYTE frameHeader; BYTE sequenceNumber; BYTE transaction; BYTE transByte; currentPrimitive = NO_PRIMITIVE; frameHeader = APLGet(); switch (params.APSDE_DATA_indication.DstEndpoint) { case EP_ZDO: ConsolePutROMString( (ROM char *)" Receiving ZDO cluster " ); PrintChar( params.APSDE_DATA_indication.ClusterId ); ConsolePutROMString( (ROM char *)"\r\n" ); // Put code here to handle any ZDO responses that we requested if ((frameHeader & APL_FRAME_TYPE_MASK) == APL_FRAME_TYPE_MSG) { frameHeader &= APL_FRAME_COUNT_MASK; for (transaction=0; transaction<frameHeader; transaction++) { sequenceNumber = APLGet(); dataLength = APLGet(); transByte = 1; // Account for status byte switch( params.APSDE_DATA_indication.ClusterId ) { // ******************************************************** // Put a case here to handle each ZDO response that we requested. // ******************************************************** case NWK_ADDR_rsp: if (APLGet() == SUCCESS) { ConsolePutROMString( (ROM char *)" Receiving NWK_ADDR_rsp.\r\n" ); // Skip over the IEEE address of the responder. for (data=0; data<8; data++) { APLGet(); transByte++; } destinationAddress.byte.LSB = APLGet(); destinationAddress.byte.MSB = APLGet(); transByte += 2; myStatusFlags.bits.bDestinationAddressKnown = 1; } break; default: break; } // Read out the rest of the MSG in case there is another transaction. for (; transByte<dataLength; transByte++) { APLGet(); } } } break; // ************************************************************************ // Place a case for each user defined endpoint. // ************************************************************************ case EP_LIGHT: if ((frameHeader & APL_FRAME_TYPE_MASK) == APL_FRAME_TYPE_KVP) { frameHeader &= APL_FRAME_COUNT_MASK; for (transaction=0; transaction<frameHeader; transaction++) { sequenceNumber = APLGet(); command = APLGet(); attributeId.byte.LSB = APLGet(); attributeId.byte.MSB = APLGet(); //dataType = command & APL_FRAME_DATA_TYPE_MASK; command &= APL_FRAME_COMMAND_MASK; if ((params.APSDE_DATA_indication.ClusterId == OnOffSRC_CLUSTER) && (attributeId.Val == OnOffSRC_OnOff)) { if ((command == APL_FRAME_COMMAND_SET) || (command == APL_FRAME_COMMAND_SETACK)) { // Prepare a response in case it is needed. TxBuffer[TxData++] = APL_FRAME_TYPE_KVP | 1; // KVP, 1 transaction TxBuffer[TxData++] = sequenceNumber; TxBuffer[TxData++] = APL_FRAME_COMMAND_SET_RES | (APL_FRAME_DATA_TYPE_UINT8 << 4); TxBuffer[TxData++] = attributeId.byte.LSB; TxBuffer[TxData++] = attributeId.byte.MSB; // Data type for this attibute must be APL_FRAME_DATA_TYPE_UINT8 data = APLGet(); switch (data) { case LIGHT_OFF: ConsolePutROMString( (ROM char *)" Turning light off.\r\n" ); LEVEL_SENSOR_LED = 0; TxBuffer[TxData++] = SUCCESS; break; case LIGHT_ON: ConsolePutROMString( (ROM char *)" Turning light on.\r\n" ); LEVEL_SENSOR_LED = 1; TxBuffer[TxData++] = SUCCESS; break; case LIGHT_TOGGLE: ConsolePutROMString( (ROM char *)" Toggling light.\r\n" ); LEVEL_SENSOR_LED ^= 1; TxBuffer[TxData++] = SUCCESS; break; default: PrintChar( data ); ConsolePutROMString( (ROM char *)" Invalid light message.\r\n" ); TxBuffer[TxData++] = KVP_INVALID_ATTRIBUTE_DATA; break; } } if (command == APL_FRAME_COMMAND_SETACK) { // Send back an application level acknowledge. ZigBeeBlockTx(); // Take care here that parameters are not overwritten before they are used. // We can use the data byte as a temporary variable. params.APSDE_DATA_request.DstAddrMode = params.APSDE_DATA_indication.SrcAddrMode; params.APSDE_DATA_request.DstEndpoint = params.APSDE_DATA_indication.SrcEndpoint; params.APSDE_DATA_request.DstAddress.ShortAddr = params.APSDE_DATA_indication.SrcAddress.ShortAddr; //params.APSDE_DATA_request.asduLength; TxData //params.APSDE_DATA_request.ProfileId; unchanged params.APSDE_DATA_request.RadiusCounter = DEFAULT_RADIUS; params.APSDE_DATA_request.DiscoverRoute = ROUTE_DISCOVERY_ENABLE; #ifdef I_SUPPORT_SECURITY params.APSDE_DATA_request.TxOptions.Val = 1; #else params.APSDE_DATA_request.TxOptions.Val = 0; #endif params.APSDE_DATA_request.SrcEndpoint = EP_LIGHT; //params.APSDE_DATA_request.ClusterId; unchanged currentPrimitive = APSDE_DATA_request; } else { // We are not sending an acknowledge, so reset the transmit message pointer. TxData = TX_DATA_START; } } // TODO read to the end of the transaction. } // each transaction } // frame type break; default: break; } APLDiscardRx(); } break; case APSDE_DATA_confirm: if (params.APSDE_DATA_confirm.Status) { ConsolePutROMString( (ROM char *)"Error " ); PrintChar( params.APSDE_DATA_confirm.Status ); ConsolePutROMString( (ROM char *)" sending message.\r\n" ); } else { ConsolePutROMString( (ROM char *)" Message sent successfully.\r\n" ); } currentPrimitive = NO_PRIMITIVE; break; case NO_PRIMITIVE: if (!ZigBeeStatus.flags.bits.bNetworkJoined) { if (!ZigBeeStatus.flags.bits.bTryingToJoinNetwork) { if (ZigBeeStatus.flags.bits.bTryOrphanJoin) { ConsolePutROMString( (ROM char *)"Trying to join network as an orphan...\r\n" ); params.NLME_JOIN_request.JoinAsRouter = FALSE; params.NLME_JOIN_request.RejoinNetwork = TRUE; params.NLME_JOIN_request.PowerSource = NOT_MAINS_POWERED; params.NLME_JOIN_request.RxOnWhenIdle = FALSE; params.NLME_JOIN_request.MACSecurity = FALSE; params.NLME_JOIN_request.ScanDuration = 8; params.NLME_JOIN_request.ScanChannels.Val = ALLOWED_CHANNELS; currentPrimitive = NLME_JOIN_request; } else { ConsolePutROMString( (ROM char *)"Trying to join network as a new device...\r\n" ); params.NLME_NETWORK_DISCOVERY_request.ScanDuration = 6; params.NLME_NETWORK_DISCOVERY_request.ScanChannels.Val = ALLOWED_CHANNELS; currentPrimitive = NLME_NETWORK_DISCOVERY_request; } } } else { // See if I can do my own internal tasks. We don't want to try to send a message // if we just asked for one. if (ZigBeeStatus.flags.bits.bDataRequestComplete && ZigBeeReady()) { // ************************************************************************ // Place all processes that can send messages here. Be sure to call // ZigBeeBlockTx() when currentPrimitive is set to APSDE_DATA_request. // ************************************************************************ if ( myStatusFlags.bits.bMoveSensorButtonPressed) { // Send a light toggle message to the other node. myStatusFlags.bits.bMoveSensorButtonPressed = FALSE; BLINK_LED(MOVE_SENSOR_LED); // envia a mensagem para ligar/desligar o led RFDSendMessage(MoveSensor_Activated, 0x00); } else if (myStatusFlags.bits.bLevelSensorButtonPressed) { // Envia mensagem indicando que o sensor de nível foi acionado myStatusFlags.bits.bLevelSensorButtonPressed = FALSE; BLINK_LED(LEVEL_SENSOR_LED); RFDSendMessage(LevelSensor_Activated, 0x00); } // We've processed any key press, so re-enable interrupts. INTCONbits.RBIE = 1; } // If we don't have to execute a primitive, see if we need to request data from // our parent, or if we can go to sleep. if (currentPrimitive == NO_PRIMITIVE) { if (!ZigBeeStatus.flags.bits.bDataRequestComplete) { // We have not received all data from our parent. If we are not waiting // for an answer from a data request, send a data request. if (!ZigBeeStatus.flags.bits.bRequestingData) { if (ZigBeeReady()) { // Our parent still may have data for us. params.NLME_SYNC_request.Track = FALSE; currentPrimitive = NLME_SYNC_request; ConsolePutROMString( (ROM char *)"Requesting data...\r\n" ); } } } else { if (!ZigBeeStatus.flags.bits.bHasBackgroundTasks && myProcessesAreDone()) { // We do not have a primitive to execute, we've extracted all messages // that our parent has for us, the stack has no background tasks, // and all application-specific processes are complete. Now we can // go to sleep. Make sure that the UART is finished, turn off the transceiver, // and make sure that we wakeup from key press. if(APLDisable() == TRUE) { ConsolePutROMString( (ROM char *)"Going to sleep...\r\n" ); while (!ConsoleIsPutReady()); APLDisable(); INTCONbits.RBIE = 1; SLEEP(); NOP(); // We just woke up from sleep. Turn on the transceiver and // request data from our parent. APLEnable(); params.NLME_SYNC_request.Track = FALSE; currentPrimitive = NLME_SYNC_request; ConsolePutROMString( (ROM char *)"Requesting data...\r\n" ); } } } } } break; default: PrintChar( currentPrimitive ); ConsolePutROMString( (ROM char *)" Unhandled primitive.\r\n" ); currentPrimitive = NO_PRIMITIVE; } // ********************************************************************* // Place any non-ZigBee related processing here. Be sure that the code // will loop back and execute ZigBeeTasks() in a timely manner. // ********************************************************************* } }
/***************************************************************************** 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; }
//////////////////////////////////////////////////////////////////////// // net_state_activity() // State Model: Some async data has been received // This is called to indicate to the state that a complete piece of async // data has been received in net_buf (with length net_buf_pos, and mode // net_buf_mode), and the data should be completely handled before // returning. // void net_state_activity() { if (net_buf_mode == NET_BUF_SMS) { // An SMS has arrived, and net_caller has been primed if ((net_reg != 0x01)&&(net_reg != 0x05)) { // Treat this as a network registration net_watchdog=0; // Disable watchdog, as we have connectivity net_reg = 0x05; led_net(1); } net_sms_in(net_caller,net_buf,net_buf_pos); return; } else if (net_buf_mode != NET_BUF_CRLF) { // An IP data message has arrived net_msg_in(net_buf); return; } switch (net_state) { case NET_STATE_DOINIT: if ((net_buf_pos >= 2)&&(net_buf[0] == 'O')&&(net_buf[1] == 'K')) { net_state_enter(NET_STATE_COPS); } break; case NET_STATE_COPS: if ((net_buf_pos >= 2)&&(net_buf[0] == 'O')&&(net_buf[1] == 'K')) net_state_enter(NET_STATE_DONETINIT); // COPS reconnect was OK else if ((net_buf_pos >= 5)&&(net_buf[0] == 'E')&&(net_buf[1] == 'R')) net_state_enter(NET_STATE_SOFTRESET); // Reset the entire async break; case NET_STATE_DONETINIT: if ((net_buf_pos >= 2)&& (net_buf[0] == 'E')&& (net_buf[1] == 'R')&& (net_state_vchar == 5)) // ERROR response to AT+CIFSR { // This is a nasty case. The GPRS has locked up. // The only solution I can find is a hard reset of the modem led_act(0); net_state_enter(NET_STATE_HARDRESET); } else if ((net_buf_pos >= 2)&& (((net_buf[0] == 'O')&&(net_buf[1] == 'K')))|| // OK (((net_buf[0] == 'S')&&(net_buf[1] == 'H')))|| // SHUT OK (net_state_vchar == 5)) // Local IP address { net_buf_pos = 0; net_timeout_ticks = 60; net_link = 0; delay100(1); switch (++net_state_vchar) { case 1: net_puts_rom("AT+CGDCONT=1,\"IP\",\""); net_puts_ram(par_get(PARAM_GPRSAPN)); net_puts_rom("\"\r"); break; case 2: net_puts_rom("AT+CSTT=\""); net_puts_ram(par_get(PARAM_GPRSAPN)); net_puts_rom("\",\""); net_puts_ram(par_get(PARAM_GPRSUSER)); net_puts_rom("\",\""); net_puts_ram(par_get(PARAM_GPRSPASS)); net_puts_rom("\"\r"); break; case 3: net_puts_rom("AT+CIICR\r"); break; case 4: net_puts_rom("AT+CIPHEAD=1\r"); break; case 5: net_puts_rom("AT+CIFSR\r"); break; case 6: net_puts_rom("AT+CLPORT=\"TCP\",\"6867\"\r"); break; case 7: net_puts_rom("AT+CIPSTART=\"TCP\",\""); net_puts_ram(par_get(PARAM_SERVERIP)); net_puts_rom("\",\"6867\"\r"); break; case 8: net_state_enter(NET_STATE_READY); break; } } else if ((net_buf_pos>=7)&& (memcmppgm2ram(net_buf, (char const rom far*)"+CREG: 0", 8) == 0)) { // Lost network connectivity during NETINIT net_state_enter(NET_STATE_SOFTRESET); } else if (memcmppgm2ram(net_buf, (char const rom far*)"+PDP: DEACT", 11) == 0) { // PDP couldn't be activated - try again... net_state_enter(NET_STATE_SOFTRESET); } break; case NET_STATE_READY: if (memcmppgm2ram(net_buf, (char const rom far*)"+CREG", 5) == 0) { // "+CREG" Network registration if (net_buf[8]==',') net_reg = net_buf[9]&0x07; // +CREG: 1,x else net_reg = net_buf[7]&0x07; // +CREG: x if ((net_reg == 0x01)||(net_reg == 0x05)) // Registered to network? { net_watchdog=0; // Disable watchdog, as we have connectivity led_net(1); } else if (net_watchdog == 0) { net_watchdog = 120; // We need connectivity within 120 seconds led_net(0); } } else if (memcmppgm2ram(net_buf, (char const rom far*)"+CLIP", 5) == 0) { // Incoming CALL if ((net_reg != 0x01)&&(net_reg != 0x05)) { // Treat this as a network registration net_watchdog=0; // Disable watchdog, as we have connectivity net_reg = 0x05; led_net(1); } delay100(1); net_puts_rom(NET_HANGUP); net_notify_status(); } else if (memcmppgm2ram(net_buf, (char const rom far*)"CONNECT OK", 10) == 0) { if (net_link == 0) { net_msg_start(); net_msg_register(); net_msg_send(); } net_link = 1; } else if (memcmppgm2ram(net_buf, (char const rom far*)"STATE: ", 7) == 0) { // Incoming CIPSTATUS if (memcmppgm2ram(net_buf, (char const rom far*)"STATE: CONNECT OK", 17) == 0) { if (net_link == 0) { net_msg_start(); net_msg_register(); net_msg_send(); } net_link = 1; } else { net_link = 0; if ((net_reg == 0x01)||(net_reg == 0x05)) { // We have a GSM network, but CIPSTATUS is not up net_msg_disconnected(); net_state_enter(NET_STATE_DONETINIT); } } } else if (memcmppgm2ram(net_buf, (char const rom far*)"SEND OK", 7) == 0) { net_msg_sendpending = 0; } else if ( (memcmppgm2ram(net_buf, (char const rom far*)"SEND FAIL", 9) == 0)|| (memcmppgm2ram(net_buf, (char const rom far*)"CLOSED", 6) == 0)|| (memcmppgm2ram(net_buf, (char const rom far*)"+CME ERROR", 10) == 0)|| (memcmppgm2ram(net_buf, (char const rom far*)"+PDP: DEACT", 11) == 0) ) { // Various GPRS error results // Re-initialize GPRS network and TCP socket net_msg_disconnected(); net_state_enter(NET_STATE_DONETINIT); } break; } }
/********************************************************************* * 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 net_sms_in(char *caller, char *buf, unsigned char pos) { // The buf contains an SMS command // and caller contains the caller telephone number char *p; // Convert SMS command (first word) to upper-case for (p=buf; ((*p!=0)&&(*p!=' ')); p++) if ((*p > 0x60) && (*p < 0x7b)) *p=*p-0x20; // Command parsing... if (memcmppgm2ram(buf, (char const rom far*)"REGISTER ", 9) == 0) { // Register phone p = par_get(PARAM_REGPASS); if (strncmp(p,buf+9,strlen(p))==0) { par_set(PARAM_REGPHONE, caller); net_send_sms_rom(caller,NET_MSG_REGISTERED); } else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"PASS ", 5) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { par_set(PARAM_REGPASS, buf+5); net_send_sms_rom(caller,NET_MSG_PASSWORD); } else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"GPS ", 4) == 0) { p = par_get(PARAM_REGPASS); if (strncmp(p,buf+4,strlen(p))==0) net_sms_gps(caller); else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"GPS", 3) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_gps(caller); else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"STAT ", 5) == 0) { p = par_get(PARAM_REGPASS); if (strncmp(p,buf+5,strlen(p))==0) net_sms_stat(caller); else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"STAT", 4) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_stat(caller); else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"PARAMS?", 7) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) net_sms_params(caller); else net_send_sms_rom(caller,NET_MSG_DENIED); } else if (memcmppgm2ram(buf, (char const rom far*)"PARAMS ", 7) == 0) { p = par_get(PARAM_REGPHONE); if (strncmp(p,caller,strlen(p)) == 0) { unsigned char d = PARAM_MILESKM; unsigned char x = 7; unsigned char y = x; while ((y<=(pos+1))&&(d < PARAM_MAX)) { if ((buf[y] == ' ')||(buf[y] == '\0')) { buf[y] = '\0'; if ((buf[x]=='-')&&(buf[x+1]=='\0')) buf[x] = '\0'; // Special case '-' is empty value par_set(d++, buf+x); x=++y; } else y++; } net_send_sms_rom(caller,NET_MSG_PARAMS); net_state_enter(NET_STATE_SOFTRESET); } else net_send_sms_rom(caller,NET_MSG_DENIED); } }
void NVMWrite(BYTE *src, ROM BYTE* dest, WORD count) { ROM char *pEraseBlock; static BYTE memBlock[ERASE_BLOCK_SIZE]; BYTE *pMemBlock; BYTE writeIndex; BYTE writeStart; BYTE writeCount; BYTE oldGIEH; DWORD oldTBLPTR; #if defined(VERIFY_WRITE) while( memcmppgm2ram( src, (MEM_MODEL ROM void *)dest, count)) #elif defined(CHECK_BEFORE_WRITE) if (memcmppgm2ram( src, (MEM_MODEL ROM void *)dest, count )) #endif { // First of all get nearest "left" erase block boundary pEraseBlock = (ROM char*)((long)dest & (long)(~(ERASE_BLOCK_SIZE-1))); writeStart = (BYTE)((BYTE)dest & (BYTE)(ERASE_BLOCK_SIZE-1)); while( count ) { // Now read the entire erase block size into RAM. NVMRead(memBlock, (far ROM void*)pEraseBlock, ERASE_BLOCK_SIZE); // Erase the block. // Erase flash memory, enable write control. EECON1 = 0x94; oldGIEH = INTCONbits.GIEH; INTCONbits.GIEH = 0; #if defined(__18CXX) TBLPTR = (unsigned short long)pEraseBlock; #endif EECON2 = 0x55; EECON2 = 0xaa; EECON1bits.WR = 1; MacroNop(); EECON1bits.WREN = 0; oldTBLPTR = TBLPTR; INTCONbits.GIEH = oldGIEH; // Modify 64-byte block of RAM buffer as per what is required. pMemBlock = &memBlock[writeStart]; while( writeStart < ERASE_BLOCK_SIZE && count ) { *pMemBlock++ = *src++; count--; writeStart++; } // After first block write, next start would start from 0. writeStart = 0; // Now write entire 64 byte block in one write block at a time. writeIndex = ERASE_BLOCK_SIZE / WRITE_BLOCK_SIZE; pMemBlock = memBlock; while( writeIndex ) { oldGIEH = INTCONbits.GIEH; INTCONbits.GIEH = 0; TBLPTR = oldTBLPTR; // Load individual block writeCount = WRITE_BLOCK_SIZE; while( writeCount-- ) { TABLAT = *pMemBlock++; //TBLWTPOSTINC(); _asm tblwtpostinc _endasm } // Start the write process: reposition tblptr back into memory block that we want to write to. #if defined(__18CXX) _asm tblrdpostdec _endasm #endif // Write flash memory, enable write control. EECON1 = 0x84; EECON2 = 0x55; EECON2 = 0xaa; EECON1bits.WR = 1; MacroNop(); EECON1bits.WREN = 0; // One less block to write writeIndex--; TBLPTR++; oldTBLPTR = TBLPTR; INTCONbits.GIEH = oldGIEH; } // Go back and do it all over again until we write all // data bytes - this time the next block. #if !defined(WIN32) pEraseBlock += ERASE_BLOCK_SIZE; #endif } }
void main(void) { CLRWDT(); ENABLE_WDT(); currentPrimitive = NO_PRIMITIVE; NetworkDescriptor = NULL; // If you are going to send data to a terminal, initialize the UART. ConsoleInit(); // Initialize the hardware - must be done before initializing ZigBee. HardwareInit(); // Initialize the ZigBee Stack. ZigBeeInit(); // ************************************************************************* // Perform any other initialization here // ************************************************************************* // Enable interrupts to get everything going. IPEN = 1; GIEH = 1; while (1) { CLRWDT(); ZigBeeTasks( ¤tPrimitive ); switch (currentPrimitive) { case NLME_NETWORK_DISCOVERY_confirm: currentPrimitive = NO_PRIMITIVE; if (!params.NLME_NETWORK_DISCOVERY_confirm.Status) { if (!params.NLME_NETWORK_DISCOVERY_confirm.NetworkCount) { ConsolePutROMString( (ROM char *)"No networks found. Trying again...\r\n" ); } else { // Save the descriptor list pointer so we can destroy it later. NetworkDescriptor = params.NLME_NETWORK_DISCOVERY_confirm.NetworkDescriptor; // Select a network to try to join. We're not going to be picky right now... currentNetworkDescriptor = NetworkDescriptor; // not needed for new join params.NLME_JOIN_request.ScanDuration = ; // not needed for new join params.NLME_JOIN_request.ScanChannels = ; params.NLME_JOIN_request.PANId = currentNetworkDescriptor->PanID; params.NLME_JOIN_request.JoinAsRouter = FALSE; params.NLME_JOIN_request.RejoinNetwork = FALSE; params.NLME_JOIN_request.PowerSource = NOT_MAINS_POWERED; params.NLME_JOIN_request.RxOnWhenIdle = FALSE; params.NLME_JOIN_request.MACSecurity = FALSE; currentPrimitive = NLME_JOIN_request; ConsolePutROMString( (ROM char *)"Network(s) found. Trying to join " ); PrintChar( params.NLME_JOIN_request.PANId.byte.MSB ); PrintChar( params.NLME_JOIN_request.PANId.byte.LSB ); ConsolePutROMString( (ROM char *)".\r\n" ); } } else { PrintChar( params.NLME_NETWORK_DISCOVERY_confirm.Status ); ConsolePutROMString( (ROM char *)" Error finding network. Trying again...\r\n" ); } break; case NLME_JOIN_confirm: currentPrimitive = NO_PRIMITIVE; if (!params.NLME_JOIN_confirm.Status) { ConsolePutROMString( (ROM char *)"Join successful!\r\n" ); if (NetworkDescriptor) { // If we joined as an orphan, this will be NULL. free( NetworkDescriptor ); } // We are now on the network. Enable routing. params.NLME_START_ROUTER_request.BeaconOrder = MAC_PIB_macBeaconOrder; params.NLME_START_ROUTER_request.SuperframeOrder = MAC_PIB_macSuperframeOrder; params.NLME_START_ROUTER_request.BatteryLifeExtension = FALSE; currentPrimitive = NLME_START_ROUTER_request; } else { PrintChar( params.NLME_JOIN_confirm.Status ); ConsolePutROMString( (ROM char *)" Could not join. Trying again as new device..." ); } break; case NLME_LEAVE_indication: if (!memcmppgm2ram( ¶ms.NLME_LEAVE_indication.DeviceAddress, (ROM void *)&macLongAddr, 8 )) { ConsolePutROMString( (ROM char *)"We have left the network.\r\n" ); } else { ConsolePutROMString( (ROM char *)"Another node has left the network.\r\n" ); } currentPrimitive = NO_PRIMITIVE; break; case NLME_RESET_confirm: ConsolePutROMString( (ROM char *)"ZigBee Stack has been reset.\r\n" ); currentPrimitive = NO_PRIMITIVE; break; case NLME_START_ROUTER_confirm: if (!params.NLME_START_ROUTER_confirm.Status) { ConsolePutROMString( (ROM char *)"Router Started!\r\n" ); } else { PrintChar( params.NLME_JOIN_confirm.Status ); ConsolePutROMString( (ROM char *)" Router start unsuccessful. We cannot route frames.\r\n" ); } // We are now ready to do ZigBee related tasks. currentPrimitive = NO_PRIMITIVE; break; case APSDE_DATA_indication: { WORD_VAL attributeId; BYTE command; BYTE data; BYTE dataLength; //BYTE dataType; BYTE frameHeader; BYTE sequenceNumber; BYTE transaction; BYTE transByte; currentPrimitive = NO_PRIMITIVE; frameHeader = APLGet(); switch (params.APSDE_DATA_indication.DstEndpoint) { case EP_ZDO: if ((frameHeader & APL_FRAME_TYPE_MASK) == APL_FRAME_TYPE_MSG) { frameHeader &= APL_FRAME_COUNT_MASK; for (transaction=0; transaction<frameHeader; transaction++) { sequenceNumber = APLGet(); dataLength = APLGet(); transByte = 0; switch( params.APSDE_DATA_indication.ClusterId ) { // ******************************************************** // Put a case here to handle each ZDO response that we requested. // Be sure to increment transByte for each APLGet(). // ******************************************************** default: break; } // Read out the rest of the MSG in case there is another transaction. for (; transByte<dataLength; transByte++) { APLGet(); } } } break; // ************************************************************************ // Place a case for each user defined endpoint. // ************************************************************************ default: // If the command type was something that requested an acknowledge, we could send back // KVP_INVALID_ENDPOINT here. break; } APLDiscardRx(); } break; case APSDE_DATA_confirm: if (params.APSDE_DATA_confirm.Status) { ConsolePutROMString( (ROM char *)"Error " ); PrintChar( params.APSDE_DATA_confirm.Status ); ConsolePutROMString( (ROM char *)" sending message.\r\n" ); } else { ConsolePutROMString( (ROM char *)" Message sent successfully.\r\n" ); } currentPrimitive = NO_PRIMITIVE; break; case NO_PRIMITIVE: if (!ZigBeeStatus.flags.bits.bNetworkJoined) { if (!ZigBeeStatus.flags.bits.bTryingToJoinNetwork) { if (ZigBeeStatus.flags.bits.bTryOrphanJoin) { ConsolePutROMString( (ROM char *)"Trying to join network as an orphan...\r\n" ); params.NLME_JOIN_request.ScanDuration = 8; params.NLME_JOIN_request.ScanChannels.Val = ALLOWED_CHANNELS; // not needed for orphan join - params.NLME_JOIN_request.PANId params.NLME_JOIN_request.JoinAsRouter = FALSE; params.NLME_JOIN_request.RejoinNetwork = TRUE; params.NLME_JOIN_request.PowerSource = NOT_MAINS_POWERED; params.NLME_JOIN_request.RxOnWhenIdle = FALSE; params.NLME_JOIN_request.MACSecurity = FALSE; currentPrimitive = NLME_JOIN_request; } else { ConsolePutROMString( (ROM char *)"Trying to join network as a new device...\r\n" ); params.NLME_NETWORK_DISCOVERY_request.ScanDuration = 8; params.NLME_NETWORK_DISCOVERY_request.ScanChannels.Val = ALLOWED_CHANNELS; currentPrimitive = NLME_NETWORK_DISCOVERY_request; } } } else { // See if we can do our own internal tasks. if (ZigBeeReady()) { // ************************************************************************ // Place all processes that can send messages here. Be sure to call // ZigBeeBlockTx() when currentPrimitive is set to APSDE_DATA_request. // ************************************************************************ } } break; default: PrintChar( currentPrimitive ); ConsolePutROMString( (ROM char *)" Unhandled primitive.\r\n" ); currentPrimitive = NO_PRIMITIVE; break; } // ********************************************************************* // Place any non-ZigBee related processing here. Be sure that the code // will loop back and execute ZigBeeTasks() in a timely manner. // ********************************************************************* } }