boolean ModemGSM::SendSMS(const char *pDestPhoneNumber, const char *pBody) { boolean res = false; int idx; if(res = WriteSMS(pDestPhoneNumber, pBody, &idx)) { res = FSMSOutQueue.Enqueue(idx); if(res) { DEBUG_P(PSTR("SMS Enqueue OK index --> %d"LB), idx); } else DEBUG_P(PSTR("SMS Enqueue FAIL"LB)); } return res; }
GNOKII_API gint DB_Look(const gchar * const phone) { GString *buf, *phnStr, *timebuf; gint ret1, numError, error; time_t rawtime; struct tm * timeinfo; sqlite3_stmt * stmt; gint empty = 1; if (phone[0] == '\0') phnStr = g_string_new(""); else { phnStr = g_string_sized_new(32); g_string_printf(phnStr, "AND phone = '%s'", phone); } time(&rawtime); timeinfo = localtime(&rawtime); timebuf = g_string_sized_new(25); g_string_printf(timebuf, "'%02d:%02d:%02d'", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); sqlite3_exec(ppDbOutbox, "BEGIN TRANSACTION;", NULL, NULL, NULL); /* poll for outgoing messages */ buf = g_string_sized_new(256); g_string_printf(buf, "SELECT id, number, text, dreport FROM outbox \ WHERE processed=0 \ AND %s >= not_before \ AND %s <= not_after \ %s", timebuf->str, timebuf->str, phnStr->str); g_string_free(phnStr, TRUE); ret1 = sqlite3_prepare_v2(ppDbOutbox, buf->str, -1, &stmt, NULL); if (ret1 != SQLITE_OK) { g_print(_("%d: Parsing query %s failed!"), __LINE__, buf->str); g_print(_("Error: %s"), sqlite3_errmsg(ppDbOutbox)); return (SMSD_NOK); } g_string_printf(timebuf, "'%02d-%02d-%02d %02d:%02d:%02d'", timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec ); ret1 = sqlite3_step(stmt); while (ret1 == SQLITE_ROW) { int gerror = 0; gn_sms sms; empty = 0; gn_sms_default_submit(&sms); memset(&sms.remote.number, 0, sizeof (sms.remote.number)); sms.delivery_report = sqlite3_column_int(stmt, 3); strncpy(sms.remote.number, sqlite3_column_text(stmt, 1), sizeof (sms.remote.number) - 1); sms.remote.number[sizeof (sms.remote.number) - 1] = '\0'; if (sms.remote.number[0] == '+') sms.remote.type = GN_GSM_NUMBER_International; else sms.remote.type = GN_GSM_NUMBER_Unknown; strncpy((gchar *) sms.user_data[0].u.text, sqlite3_column_text(stmt, 2), 10 * GN_SMS_MAX_LENGTH + 1); sms.user_data[0].u.text[10 * GN_SMS_MAX_LENGTH] = '\0'; sms.user_data[0].length = strlen((gchar *) sms.user_data[0].u.text); sms.user_data[0].type = GN_SMS_DATA_Text; sms.user_data[1].type = GN_SMS_DATA_None; if (!gn_char_def_alphabet(sms.user_data[0].u.text)) sms.dcs.u.general.alphabet = GN_SMS_DCS_UCS2; gn_log_xdebug("Sending SMS: %s, %s\n", sms.remote.number, sms.user_data[0].u.text); numError = 0; do { if ((error = WriteSMS (&sms)) == GN_ERR_NONE) break; sleep(1); } while ((error == GN_ERR_TIMEOUT || error == GN_ERR_FAILED) && numError++ < 3); /* mark sended */ g_string_printf(buf, "UPDATE outbox SET processed=1, error='%d', \ processed_date=%s \ WHERE id=%d", gerror, timebuf->str, sqlite3_column_int(stmt, 0) ); sqlite3_exec(ppDbOutbox, buf->str, NULL, NULL, NULL); ret1 = sqlite3_step(stmt); } /* rollback if found any errors */ if (ret1 != SQLITE_DONE) { g_print(_("%d: SELECT FROM outbox command failed.\n"), __LINE__); g_print(_("Error: %s\n"), sqlite3_errmsg(ppDbOutbox)); sqlite3_finalize(stmt); sqlite3_exec(ppDbOutbox, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); g_string_free(timebuf, TRUE); g_string_free(buf, TRUE); return (SMSD_NOK); } sqlite3_finalize(stmt); sqlite3_exec(ppDbOutbox, "COMMIT;", NULL, NULL, NULL); g_string_free(timebuf, TRUE); g_string_free(buf, TRUE); if (empty) return (SMSD_OUTBOXEMPTY); else return (SMSD_OK); }
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; }
GNOKII_API gint DB_Look (const gchar * const phone) { DIR *dir; struct dirent *dirent; FILE *smsFile; GString *buf; gint numError, error; gint empty = 1; if (spool[0] == '\0') // if user don't set spool dir, sending is disabled return (SMSD_NOK); if ((dir = opendir (spool)) == NULL) { g_print (_("Cannot open directory %s\n"), spool); return (SMSD_NOK); } buf = g_string_sized_new (64); while ((dirent = readdir (dir))) { gn_sms sms; gint slen = 0; if (strcmp (dirent->d_name, ".") == 0 || strcmp (dirent->d_name, "..") == 0 || strncmp (dirent->d_name, "ERR.", 4) == 0) continue; g_string_printf (buf, "%s/%s", spool, dirent->d_name); if ((smsFile = fopen (buf->str, "r")) == NULL) { g_print (_("Can't open file %s for reading!\n"), buf->str); continue; } empty = 0; gn_sms_default_submit (&sms); memset (&sms.remote.number, 0, sizeof (sms.remote.number)); if (fgets (sms.remote.number, sizeof (sms.remote.number), smsFile)) slen = strlen (sms.remote.number); if (slen < 1) { error = -1; fclose (smsFile); g_print (_("Remote number is empty in %s!\n"), buf->str); goto handle_file; } if (sms.remote.number[slen - 1] == '\n') sms.remote.number[slen - 1] = '\0'; /* Initialize SMS text */ memset (&sms.user_data[0].u.text, 0, sizeof (sms.user_data[0].u.text)); slen = fread ((gchar *) sms.user_data[0].u.text, 1, GN_SMS_MAX_LENGTH, smsFile); if (slen > 0 && sms.user_data[0].u.text[slen - 1] == '\n') sms.user_data[0].u.text[slen - 1] = '\0'; fclose (smsFile); // sms.delivery_report = (smsdConfig.smsSets & SMSD_READ_REPORTS); if (sms.remote.number[0] == '+') sms.remote.type = GN_GSM_NUMBER_International; else sms.remote.type = GN_GSM_NUMBER_Unknown; sms.user_data[0].length = strlen ((gchar *) sms.user_data[0].u.text); sms.user_data[0].type = GN_SMS_DATA_Text; sms.user_data[1].type = GN_SMS_DATA_None; if (!gn_char_def_alphabet (sms.user_data[0].u.text)) sms.dcs.u.general.alphabet = GN_SMS_DCS_UCS2; gn_log_xdebug ("Sending SMS: %s, %s\n", sms.remote.number, sms.user_data[0].u.text); numError = 0; do { if ((error = WriteSMS (&sms)) == GN_ERR_NONE) break; sleep (1); } while ((error == GN_ERR_TIMEOUT || error == GN_ERR_FAILED) && numError++ < 3); handle_file: if (error == GN_ERR_NONE) { if (unlink (buf->str)) g_print (_("Cannot unlink %s."), buf->str); } else { GString *buf2; buf2 = g_string_sized_new (64); g_string_printf (buf2, "%s/ERR.%s", spool, dirent->d_name); g_print (_("Cannot send sms from file %s\n"), buf->str); if (rename (buf->str, buf2->str)) { g_print (_("Cannot rename file %s to %s. Trying to unlink it.\n"), buf->str, buf2->str); if (unlink (buf->str)) g_print (_("Cannot unlink %s."), buf->str); } g_string_free (buf2, TRUE); } } g_string_free (buf, TRUE); closedir (dir); if (empty) return (SMSD_OUTBOXEMPTY); else return (SMSD_OK); }