ModemGSM::EStandardAnswer ModemGSM::WaitAnswer(unsigned int pTimeoutMS, boolean pHandleURC) { //DEBUG_P("WaitAnswer --> "); for(;;) { if(Readln(pTimeoutMS, false) == TIMEOUT) { DEBUG_P(PSTR("** TIMEOUT"LB)); return saTimeout; } //DEBUGLN(FRXBuff); if(strcmp_P(FRXBuff,PSTR("OK")) == 0) { //DEBUGLN_P("OK"); return saOk; } else if( (strcmp_P(FRXBuff,PSTR("ERROR")) == 0) || (strncmp_P(FRXBuff,PSTR("+CME ERROR:"), 11) == 0) || (strncmp_P(FRXBuff,PSTR("+CMS ERROR:"), 11) == 0)) { DEBUG_P(PSTR("** ")); DEBUGLN(FRXBuff); return saError; } else if(pHandleURC) HandleURC(); else return saUnknown; } }
GMC_DCL(tp_FileName, FileName) { tp_FilDsc FilDsc; tps_Str StrBuf; tp_Str Str; FilDsc = FileName_RFilDsc(FileName, FALSE); if (FilDsc == ERROR) { Write(StdOutFD, "** Could not read: "); Writeln(StdOutFD, FileName); return; }/*if*/; Unblock_Signals(); for (Str=Readln(StrBuf, FilDsc); Str!=NIL; Str=Readln(StrBuf, FilDsc)) { Local_ErrMessage(Str); Local_ErrMessage("\n"); }/*for*/; Block_Signals(); Close(FilDsc); }/*Local_FileErrMessage*/
boolean ModemGSM::ReadSMSAtIndex(int pIndex, TSMSPtr pSMS) { boolean hasEntry = false; DEBUG_P(PSTR("Reading SMS entry at --> %d"LB), pIndex); SendCommand(PSTR("AT+CMGR=%d"), pIndex); for(;;) { switch(WaitAnswer(5000)) { case saOk: return hasEntry; case saError: case saTimeout: return false; case saUnknown: { int idx; if(sscanf_P(FRXBuff, PSTR("+CMGR: \"%*[^\"]\",\"%20[^\"]\""), pSMS->phone) == 1) { DEBUG_P(PSTR(" SMS Number -> %s"LB), pSMS->phone); if(Readln(500, true) != 0) { DEBUG_P(PSTR(" SMS Text -> ")); DEBUGLN(FRXBuff); strncpy(pSMS->body, FRXBuff, sizeof(pSMS->body) - 1); pSMS->body[sizeof(pSMS->body) - 1] = '\0'; hasEntry = true; } else { DEBUG_P(PSTR("** Timeout reading SMS text"LB)); return false; } } else HandleURC(); } } } }
int ModemGSM::Dispatch() { int res = 0; int level; int ind; static int state=0; EvalNetworkLedStatus(); #ifdef REGISTRATION_DELAYED if(FNetworkRegDelayActive && FNetworkRegDelayTS.IsExpired()) { DEBUG_P(PSTR("Network Registration Delay Expired --> Now Registered To Network"LB)); FNetworkRegDelayActive = false; FRegisteredToNetwork = true; } #endif if(FLastKeepAliveTS.IsExpired()) { #if SIMULATION if(FPBReady) { int idx; char temp[30]; // switch(state % 3) //repeat commands switch(state) { case 0: { DEBUG_P(PSTR("---- Posting Fake SMS"LB)); WriteSMS("+390000000000", "ON 0000,22", &idx); sprintf_P(temp, PSTR("+CMTI: \"SM\",%d"), idx); break; } case 1: { DEBUG_P(PSTR("---- Posting Fake SMS"LB)); WriteSMS("+390000000000", "ON 0000,22", &idx); sprintf_P(temp, PSTR("+CMTI: \"SM\",%d"), idx); break; } default: { temp[0] = 0; if(!SendKeepAlive()) { FKeepAliveFailedCount++; //if the modem is not answering try the hard way ... if(FKeepAliveFailedCount > 5) { //Try to power off the modem SendCommand("AT+CPWROFF"); delay(1000); //Signal Error condition FError = true; return res; } } else { FError = false; FKeepAliveFailedCount = 0; } } } state++; if(temp[0]) { FURCQueue.Enqueue(temp); DEBUG_P(PSTR("---- Posted Fake SMS"LB)); } } else #endif if(!SendKeepAlive()) { FKeepAliveFailedCount++; //if the modem is not answering try the hard way ... if(FKeepAliveFailedCount > 5) { //Try to power off the modem SendCommand("AT+CPWROFF"); delay(1000); //Signal Error condition FError = true; return res; } } else { FError = false; FKeepAliveFailedCount = 0; } FLastKeepAliveTS.Reset(); }; int idx; //Check for Queued URC or Data from Modem SerialLine if((FURCQueue.Count() ? FURCQueue.Dequeue(FRXBuff, sizeof(FRXBuff)) : false) || (Readln(100, false) != TIMEOUT)) { if(sscanf_P(FRXBuff, PSTR("+CMTI: \"%*[^\"]\",%d"), &idx) == 1) { DEBUG_P(PSTR("SMS Received at -> %d"LB), idx); //Save SMS position in SM Memory, the SMS is stored by the Modem FSMSInQueue.Enqueue(idx); } else if((sscanf_P(FRXBuff,PSTR("+CMGS: %d"), &level) == 1) || (sscanf_P(FRXBuff,PSTR("+CMSS: %d"), &level) == 1)) { DEBUG_P(PSTR("Last Message Sent Successfully"LB)); } else if(sscanf_P(FRXBuff,PSTR("+CIEV: %d,%d"), &ind, &level) == 2) { if(ind == 2) { if((level >= 1) && (level <= 5)) { FSignalLevel = level; DEBUG_P(PSTR("Signal Strength --> %d"LB), level); } else { FSignalLevel = UNKNOWN_LEVEL; DEBUG_P(PSTR("**BAD Signal Strength --> %d"LB), level); } } } else if(sscanf_P(FRXBuff,PSTR("+CREG: %d"), &level) == 1) { if((level == 1) || (level == 5)) { #ifdef REGISTRATION_DELAYED DEBUG_P(PSTR("Registered to Network Indication --> Starting Delay"LB)); FNetworkRegDelayActive = true; //Wait for a while to be sure that SMS will work FNetworkRegDelayTS.Reset(); #else FRegisteredToNetwork = true; DEBUGLN_P(PSTR("Registered to Network"LB)); #endif } else { DEBUG_P(PSTR("NOT Registered to Network"LB)); FRegisteredToNetwork = false; #ifdef REGISTRATION_DELAYED FNetworkRegDelayActive = false; #endif } FLastBlinkTS.Reset(); EvalNetworkLedStatus(); } else if(strncmp(FRXBuff,"+XDRVI: ", 8) == 0) { resetCount++; DEBUG_P(PSTR("Module RESET"LB)); DiscardSerialInput(5000); InnerSetup(); } else if(strcmp_P(FRXBuff,PSTR("+PBREADY")) == 0) { FPBReady = true; for(int i = 0; i < 10; i++) if(ClearSMSMemory()) break; else { delay(1000); DEBUG_P(PSTR("Retrying .... "LB)); } FLastKeepAliveTS.Reset(); } else { DEBUG_P(PSTR("** Unhandled -> ")); DEBUGLN(FRXBuff); } } //Do not fire SMS retries if the network is not available if((FSMSOutQueue.Count() && FRegisteredToNetwork) && !(FSMSResendPending && !FSMSResendTS.IsExpired())) { int idx; FSMSOutQueue.Peek(&idx); if(SendSMSAtIndex(idx)) { SMSDequeue(qOut, NULL); FSMSResendPending = false; } else { //A retry failed ? if(FSMSResendPending) { //some other retry available ? if(FSMSRetry) { FSMSRetry--; FSMSResendTS.Reset(); DEBUG_P(PSTR("Retrying SMS Send. Retry Count --> %d"LB), (int)FSMSRetry); } else { //discard SMS FSMSResendPending = false; FSMSOutQueue.Dequeue(NULL); DEBUG_P(PSTR("** Too Many Retries SMS Send Aborted"LB)); } } else { //Start a delay and retry sequence FSMSRetry = SMS_RETRY_COUNT; FSMSResendPending = true; FSMSResendTS.Reset(); DEBUG_P(PSTR("Retrying SMS Send. Retry Count --> %d"LB), (int)FSMSRetry); } } } return res; }
void WindowsOutpost::thread_main() { thread_running = true; while (thread_run) { switch (stage) { case STAGE_ZERO: { // Next stage. stage = STAGE_START; break; } case STAGE_START: { // Start Outpost if it does not already run. if (!program_is_running(Directories->get_bwoutpost_exeonly())) { // Start Outpost and wait a few seconds till it settles. GwSpawn spawn(Directories->get_bwoutpost()); spawn.async(); spawn.run(); g_usleep(3000000); } // Decide on next stage. // TO DO: Don't poll in such an inefficient manner. if (program_is_running(Directories->get_bwoutpost_exeonly())) { stage = STAGE_CONNECT; } else { stage = STAGE_WAIT_RETRY; } break; } case STAGE_CONNECT: { ustring hostname = "localhost"; telnet(hostname); if (connected) { stage = STAGE_COMMUNICATE; } else { stage = STAGE_WAIT_RETRY; } break; } case STAGE_COMMUNICATE: { // Break if it communicates directly. if (OnlineBibleDirectMode) { break; } // Carry out the scheduled tasks. // Whether the Online Bible server should be connected to. if (online_bible_server_requested_action != 0) { if (online_bible_server_requested_action) { // There is a request to connect to the Online Bible server. if (!online_bible_server_connected) { if (online_bible_is_running ()) { send_line("OLB Connect"); log (Readln ()); online_bible_server_connected = true; } } } else { // There is a request to disconnect from the Online Bible server. if (online_bible_server_connected) { if (online_bible_is_running ()) { send_line("OLB Disconnect"); } } // Since the Online Bible may have been shutdown, it will always be disconnected. online_bible_server_connected = false; } // Requested action handled. online_bible_server_requested_action = 0; break; } if (!bibleworks_reference_set_value.empty()) { // Make a quick copy of the value, so that if the value is set again during the time // it takes to send this to BibleWorks, the new value will be kept for next time. ustring value (bibleworks_reference_set_value); bibleworks_reference_set_value.clear(); // If BibleWorks does not run, and Outpost tries to contact it, it // crashes in Wine and becomes unusable. Therefore check whether BibleWorks runs. if (bibleworks_is_running ()) { send_line(value); } break; } if (!santafefocus_reference_set_value.empty()) { ustring value (santafefocus_reference_set_value); santafefocus_reference_set_value.clear(); send_line(value); break; } if (!santafefocus_word_set_value.empty()) { ustring value (santafefocus_word_set_value); santafefocus_word_set_value.clear(); send_line(value); break; } if (!onlinebible_reference_set_value.empty()) { ustring value (onlinebible_reference_set_value); onlinebible_reference_set_value.clear(); bool online_bible_runs = online_bible_is_running (); if (online_bible_runs) { if (online_bible_server_connected) { send_line (value); } } else { online_bible_server_connected = false; } break; } if (!get_reference_command.empty()) { send_line (get_reference_command); get_reference_command.clear(); get_reference_reply = Readln (); break; } break; } case STAGE_WAIT_RETRY: { stage++; break; } case STAGE_RETRY: { clear(); break; } default: { stage++; } } g_usleep(300000); } thread_running = false; }
ustring WindowsOutpost::OnlineBibleDirectCommandResponseGet(const ustring& command) // Sends a command to the Online Bible and immediately receive its reply. { send_line ("OLB " + command); return Readln (); }