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;    
	}
}
Exemple #2
0
   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;
}
Exemple #5
0
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;
}
Exemple #6
0
ustring WindowsOutpost::OnlineBibleDirectCommandResponseGet(const ustring& command)
// Sends a command to the Online Bible and immediately receive its reply.
{
  send_line ("OLB " + command);
  return Readln ();
}