BOOL net_sms_handle_reset(char *caller, char *command, char *arguments) { char *p; net_state_enter(NET_STATE_HARDSTOP); return FALSE; }
// GPRS <APN> <username> <password> BOOL net_sms_handle_gprs(char *caller, char *command, char *arguments) { BOOL gprsq_result; par_set(PARAM_GPRSAPN, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { if ((arguments[0]=='-')&&(arguments[1]==0)) par_set(PARAM_GPRSUSER, arguments+1); else par_set(PARAM_GPRSUSER, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { if ((arguments[0]=='-')&&(arguments[1]==0)) par_set(PARAM_GPRSPASS, arguments+1); else par_set(PARAM_GPRSPASS, arguments); } } gprsq_result = net_sms_handle_gprsq(caller, command, arguments); if (net_state != NET_STATE_DIAGMODE) { net_state_vint = NET_GPRS_RETRIES; net_state_enter(NET_STATE_NETINITP); } return gprsq_result; }
// SERVER <serverip> <serverpassword> <paranoidmode> BOOL net_sms_handle_server(char *caller, char *command, char *arguments) { BOOL serverq_result; par_set(PARAM_SERVERIP, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { par_set(PARAM_SERVERPASS, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { par_set(PARAM_PARANOID, arguments); } } serverq_result = net_sms_handle_serverq(caller, command, arguments); if (net_state != NET_STATE_DIAGMODE) { net_state_vint = NET_GPRS_RETRIES; net_state_enter(NET_STATE_NETINITP); } return serverq_result; }
// MODULE <vehicleid> <units> <notifications> BOOL net_sms_handle_module(char *caller, char *command, char *arguments) { BOOL moduleq_result; par_set(PARAM_VEHICLEID, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { par_set(PARAM_MILESKM, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { par_set(PARAM_NOTIFIES, arguments); arguments = net_sms_nextarg(arguments); if (arguments != NULL) { par_set(PARAM_VEHICLETYPE, arguments); } } } moduleq_result = net_sms_handle_moduleq(caller, command, arguments); vehicle_initialise(); if (net_state != NET_STATE_DIAGMODE) { net_state_vint = NET_GPRS_RETRIES; net_state_enter(NET_STATE_NETINITP); } return moduleq_result; }
//////////////////////////////////////////////////////////////////////// // net_initialise() // This function is an entry point from the main() program loop, and // gives the NET framework an opportunity to initialise itself. // void net_initialise(void) { // I/O configuration PORT C TRISC = 0x80; // Port C RC0-6 output, RC7 input PORTBbits.RB0 = 1; UARTIntInit(); led_net(0); net_reg = 0; net_state_enter(NET_STATE_START); }
// VEHICLE <vehicletype> BOOL net_sms_handle_vehicle(char *caller, char *command, char *arguments) { BOOL vehicleq_result; if (arguments[0]=='-') arguments[0]=0; par_set(PARAM_VEHICLETYPE, arguments); vehicleq_result = net_sms_handle_vehicleq(caller, command, arguments); vehicle_initialise(); if (net_state != NET_STATE_DIAGMODE) net_state_enter(NET_STATE_DONETINIT); return vehicleq_result; }
BOOL net_sms_handle_ap(char *caller, char *command, char *arguments) { unsigned char d = 0; char *p = par_get(PARAM_MODULEPASS); while ((d < PARAM_MAX)&&(arguments != NULL)) { if ((arguments[0]=='-')&&(arguments[1]==0)) par_set(d++, arguments+1); else par_set(d++, arguments); arguments = net_sms_nextarg(arguments); } if (net_state != NET_STATE_DIAGMODE) net_state_enter(NET_STATE_FIRSTRUN); return FALSE; }
// GSMLOCK <provider> BOOL net_sms_handle_gsmlock(char *caller, char *command, char *arguments) { BOOL gsmlockq_result; if (arguments == NULL) { char e[1] = ""; par_set(PARAM_GSMLOCK, e); } else { par_set(PARAM_GSMLOCK, arguments); } gsmlockq_result = net_sms_handle_gsmlockq(caller, command, arguments); if (net_state != NET_STATE_DIAGMODE) net_state_enter(NET_STATE_DONETINIT); return gsmlockq_result; }
//////////////////////////////////////////////////////////////////////// // net_ticker() // This function is an entry point from the main() program loop, and // gives the NET framework a ticker call approximately once per second. // It is used to internally generate the other net_state_ticker*() calls. // void net_ticker(void) { // This ticker is called once every second net_granular_tick++; if ((net_timeout_goto > 0)&&(net_timeout_ticks-- == 0)) { net_state_enter(net_timeout_goto); } else { net_state_ticker1(); } if ((net_granular_tick % 60)==0) net_state_ticker60(); if ((net_granular_tick % 300)==0) net_state_ticker300(); if ((net_granular_tick % 600)==0) { net_state_ticker600(); net_granular_tick -= 600; } }
BOOL net_sms_handle_params(char *caller, char *command, char *arguments) { unsigned char d = PARAM_MILESKM; while ((d < PARAM_MAX)&&(arguments != NULL)) { if ((arguments[0]=='-')&&(arguments[1]==0)) par_set(d++, arguments+1); else par_set(d++, arguments); arguments = net_sms_nextarg(arguments); } net_send_sms_start(caller); net_puts_rom(NET_MSG_PARAMS); net_send_sms_finish(); vehicle_initialise(); if (net_state != NET_STATE_DIAGMODE) net_state_enter(NET_STATE_DONETINIT); return FALSE; }
// 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; } } else // we lost sync, and can not decrypt, reconnect { //net_msg_disconnected(); net_state_enter(NET_STATE_DONETINIT); } }
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 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); } }
//////////////////////////////////////////////////////////////////////// // net_state_ticker1() // State Model: Per-second ticker // This function is called approximately once per second, and gives // the state a timeslice for activity. // void net_state_ticker1(void) { char *p; switch (net_state) { case NET_STATE_START: net_state_vchar = net_state_vchar ^ 1; // Toggle LED on/off led_act(net_state_vchar); break; case NET_STATE_DOINIT: if ((net_timeout_ticks==10)&&(net_timeout_ticks==20)) net_puts_rom(NET_INIT); // Try again... break; case NET_STATE_COPS: net_state_vchar = net_state_vchar ^ 1; // Toggle LED on/off led_net(net_state_vchar); led_act(net_state_vchar^1); break; case NET_STATE_SOFTRESET: net_state_enter(NET_STATE_START); break; case NET_STATE_READY: if (net_watchdog > 0) { if (--net_watchdog == 0) { net_state_enter(NET_STATE_COPS); // Reset network connection return; } } if (net_msg_sendpending>0) { net_msg_sendpending++; if (net_msg_sendpending>60) { // Pending for more than 60 seconds.. net_state_enter(NET_STATE_DONETINIT); // Reset GPRS link return; } } if ((net_reg == 0x01)||(net_reg == 0x05)) { if ((net_msg_notify==1)&&(net_msg_serverok==1)) { net_msg_notify = 0; delay100(10); net_msg_alert(); return; } if (net_sms_notify==1) { net_sms_notify = 0; delay100(10); p = par_get(PARAM_REGPHONE); net_sms_stat(p); return; } if ((net_msg_notifyenvironment==1)&& (net_msg_serverok==1)&& (net_apps_connected>0)&& (net_msg_sendpending==0)) { net_msg_notifyenvironment = 0; delay100(10); net_msg_start(); net_msg_environment(); net_msg_send(); } } break; } }
//////////////////////////////////////////////////////////////////////// // 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; } }
// 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; } }
BOOL net_msg_cmd_exec(void) { int k; char *p, *s; delay100(2); CHECKPOINT(0x43) switch (net_msg_cmd_code) { case 1: // Request feature list (params unused) for (k=0;k<FEATURES_MAX;k++) { s = stp_i(net_scratchpad, "MP-0 c1,0,", k); s = stp_i(s, ",", FEATURES_MAX); s = stp_i(s, ",", sys_features[k]); net_msg_encode_puts(); } break; case 2: // Set feature (params: feature number, value) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the command, and <p> to the param value k = atoi(net_msg_cmd_msg); if ((k>=0)&&(k<FEATURES_MAX)) { sys_features[k] = atoi(p); if (k>=FEATURES_MAP_PARAM) // Top N features are persistent par_set(PARAM_FEATURE_S+(k-FEATURES_MAP_PARAM), p); if (k == FEATURE_CANWRITE) vehicle_initialise(); STP_OK(net_scratchpad, net_msg_cmd_code); } else { STP_INVALIDRANGE(net_scratchpad, net_msg_cmd_code); } } else { STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); break; case 3: // Request parameter list (params unused) for (k=0;k<PARAM_MAX;k++) { p = par_get(k); if (k==PARAM_SERVERPASS) *p=0; // Don't show netpass1 s = stp_i(net_scratchpad, "MP-0 c3,0,", k); s = stp_i(s, ",", PARAM_MAX); s = stp_s(s, ",", p); net_msg_encode_puts(); } break; case 4: // Set parameter (params: param number, value) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the command, and <p> to the param value k = atoi(net_msg_cmd_msg); if ((k>=0)&&(k<PARAM_FEATURE_S)) { par_set(k, p); STP_OK(net_scratchpad, net_msg_cmd_code); if ((k==PARAM_MILESKM) || (k==PARAM_VEHICLETYPE)) vehicle_initialise(); } else { STP_INVALIDRANGE(net_scratchpad, net_msg_cmd_code); } } else { STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); break; case 5: // Reboot (params unused) STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); net_state_enter(NET_STATE_HARDSTOP); break; case 6: // CHARGE ALERT (params unused) net_msg_alert(); net_msg_encode_puts(); break; case 40: // Send SMS (params: phone number, SMS message) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the phone number, and <p> to the SMS message net_send_sms_start(net_msg_cmd_msg); net_puts_ram(p); net_puts_rom("\x1a"); delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); } else { net_msg_start(); STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); delay100(2); break; case 41: // Send MMI/USSD Codes (param: USSD_CODE) net_puts_rom("AT+CUSD=1,\""); net_puts_ram(net_msg_cmd_msg); net_puts_rom("\",15\r"); // cmd reply #1 to acknowledge command: delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); delay100(2); // cmd reply #2 sent on USSD response, see net_msg_reply_ussd() break; case 49: // Send raw AT command (param: raw AT command) net_puts_ram(net_msg_cmd_msg); net_puts_rom("\r"); delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); delay100(2); break; default: return FALSE; } return TRUE; }
BOOL net_msg_cmd_exec(void) { int k; char *p, *s; delay100(2); CHECKPOINT(0x43) switch (net_msg_cmd_code) { case 1: // Request feature list (params unused) for (k=0;k<FEATURES_MAX;k++) { s = stp_i(net_scratchpad, "MP-0 c1,0,", k); s = stp_i(s, ",", FEATURES_MAX); s = stp_i(s, ",", sys_features[k]); net_msg_encode_puts(); } break; case 2: // Set feature (params: feature number, value) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the command, and <p> to the param value k = atoi(net_msg_cmd_msg); if ((k>=0)&&(k<FEATURES_MAX)) { sys_features[k] = atoi(p); if (k>=FEATURES_MAP_PARAM) // Top N features are persistent par_set(PARAM_FEATURE_S+(k-FEATURES_MAP_PARAM), p); if (k == FEATURE_CANWRITE) vehicle_initialise(); STP_OK(net_scratchpad, net_msg_cmd_code); } else { STP_INVALIDRANGE(net_scratchpad, net_msg_cmd_code); } } else { STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); break; case 3: // Request parameter list (params unused) for (k=0;k<PARAM_MAX;k++) { p = par_get(k); if (k==PARAM_SERVERPASS) *p=0; // Don't show netpass1 s = stp_i(net_scratchpad, "MP-0 c3,0,", k); s = stp_i(s, ",", PARAM_MAX); s = stp_s(s, ",", p); net_msg_encode_puts(); } break; case 4: // Set parameter (params: param number, value) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the command, and <p> to the param value k = atoi(net_msg_cmd_msg); if ((k>=0)&&(k<PARAM_FEATURE_S)) { par_set(k, p); STP_OK(net_scratchpad, net_msg_cmd_code); if ((k==PARAM_MILESKM) || (k==PARAM_VEHICLETYPE)) vehicle_initialise(); #ifdef OVMS_ACCMODULE // Reset the ACC state it an ACC parameter is changed if ((k>=PARAM_ACC_S)&&(k<(PARAM_ACC_S+PARAM_ACC_COUNT))) acc_state_enter(ACC_STATE_FIRSTRUN); #endif } else { STP_INVALIDRANGE(net_scratchpad, net_msg_cmd_code); } } else { STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); break; case 5: // Reboot (params unused) STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); net_state_enter(NET_STATE_HARDSTOP); break; case 6: // CHARGE ALERT (params unused) net_msg_alert(); net_msg_encode_puts(); break; case 7: // SMS command wrapper // process command: net_msg_bufpos = net_msg_scratchpad; k = net_sms_in(par_get(PARAM_REGPHONE), net_msg_cmd_msg); net_msg_bufpos = NULL; // output is now in net_msg_scratchpad // create return string: s = stp_i(net_scratchpad, NET_MSG_CMDRESP, net_msg_cmd_code); s = stp_i(s, ",", 1-k); // 0=ok 1=error if (k) { *s++ = ','; for (p = net_msg_scratchpad; *p; p++) { if (*p == '\n') *s++ = '\r'; // translate LF to CR else if (*p == ',') *s++ = ';'; // translate , to ; else *s++ = *p; } *s = 0; } // send return string: net_msg_encode_puts(); break; case 40: // Send SMS (params: phone number, SMS message) for (p=net_msg_cmd_msg;(*p != 0)&&(*p != ',');p++) ; // check if a value exists and is separated by a comma if (*p == ',') { *p++ = 0; // At this point, <net_msg_cmd_msg> points to the phone number, and <p> to the SMS message net_send_sms_start(net_msg_cmd_msg); net_puts_ram(p); net_puts_rom("\x1a"); delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); } else { net_msg_start(); STP_INVALIDSYNTAX(net_scratchpad, net_msg_cmd_code); } net_msg_encode_puts(); delay100(2); break; case 41: // Send MMI/USSD Codes (param: USSD_CODE) net_puts_rom("AT+CUSD=1,\""); net_puts_ram(net_msg_cmd_msg); net_puts_rom("\",15\r"); // cmd reply #1 to acknowledge command: delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); delay100(2); // cmd reply #2 sent on USSD response, see net_msg_reply_ussd() break; case 49: // Send raw AT command (param: raw AT command) net_puts_ram(net_msg_cmd_msg); net_puts_rom("\r"); delay100(5); net_msg_start(); STP_OK(net_scratchpad, net_msg_cmd_code); net_msg_encode_puts(); delay100(2); break; default: return FALSE; } return TRUE; }