diff options
Diffstat (limited to 'smsd/core.c')
-rw-r--r-- | smsd/core.c | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/smsd/core.c b/smsd/core.c index 80bbe3c..ff99f1b 100644 --- a/smsd/core.c +++ b/smsd/core.c @@ -139,6 +139,7 @@ void SMSD_SendSMSStatusCallback (GSM_StateMachine *sm, int status, int mr, void } else { Config->SendingSMSStatus = ERR_UNKNOWN; } + Config->StatusCode = status; } /** @@ -385,6 +386,7 @@ void SMSD_Log_Function(const char *text, void *data) GSM_SMSDConfig *SMSD_NewConfig(const char *name) { GSM_SMSDConfig *Config; + int i; Config = (GSM_SMSDConfig *)malloc(sizeof(GSM_SMSDConfig)); if (Config == NULL) return Config; @@ -418,6 +420,10 @@ GSM_SMSDConfig *SMSD_NewConfig(const char *name) Config->conn.pg = NULL; #endif + for (i = 0; i < GSM_MAX_MULTI_SMS; i++) { + Config->SkipMessage[i] = FALSE; + } + /* Prepare lists */ GSM_StringArray_New(&(Config->IncludeNumbersList)); GSM_StringArray_New(&(Config->ExcludeNumbersList)); @@ -862,6 +868,7 @@ GSM_Error SMSD_ReadConfig(const char *filename, GSM_SMSDConfig *Config, gboolean Config->RunOnReceive = INI_GetValue(Config->smsdcfgfile, "smsd", "runonreceive", FALSE); Config->RunOnFailure = INI_GetValue(Config->smsdcfgfile, "smsd", "runonfailure", FALSE); Config->RunOnSent = INI_GetValue(Config->smsdcfgfile, "smsd", "runonsent", FALSE); + Config->RunOnIncomingCall = INI_GetValue(Config->smsdcfgfile, "smsd", "runonincomingcall", FALSE); str = INI_GetValue(Config->smsdcfgfile, "smsd", "smsc", FALSE); if (str) { @@ -1061,6 +1068,9 @@ void SMSD_RunOnReceiveEnvironment(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Conf sprintf(buffer, "%d", sms->SMS[i].Class); sprintf(name, "SMS_%d_CLASS", i + 1); setenv(name, buffer, 1); + sprintf(buffer, "%d", sms->SMS[i].MessageReference); + sprintf(name, "SMS_%d_REFERENCE", i + 1); + setenv(name, buffer, 1); sprintf(name, "SMS_%d_NUMBER", i + 1); setenv(name, DecodeUnicodeConsole(sms->SMS[i].Number), 1); if (sms->SMS[i].Coding != SMS_Coding_8bit && sms->SMS[i].UDH.Type != UDH_UserUDH) { @@ -1113,7 +1123,7 @@ void SMSD_RunOnReceiveEnvironment(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Conf * * This is Windows variant. */ -gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, const char *locations) +gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, const char *locations, const char *event) { BOOL ret; STARTUPINFO si; @@ -1131,7 +1141,7 @@ gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfi si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - SMSD_Log(DEBUG_INFO, Config, "Starting run on command: %s", cmdline); + SMSD_Log(DEBUG_INFO, Config, "Starting run on %s: %s", event, cmdline); ret = CreateProcess(NULL, /* No module name (use command line) */ cmdline, /* Command line */ @@ -1160,7 +1170,7 @@ gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfi * * This is POSIX variant. */ -gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, const char *locations) +gboolean SMSD_RunOn(const char *command, GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, const char *locations, const char *event) { int pid; int pipefd[2]; @@ -1253,7 +1263,7 @@ out: /* Calculate command line */ cmdline = SMSD_RunOnCommand(locations, command); - SMSD_Log(DEBUG_INFO, Config, "Starting run on receive: %s", cmdline); + SMSD_Log(DEBUG_INFO, Config, "Starting run on %s: %s", event, cmdline); /* Close all file descriptors */ for (i = 0; i < 255; i++) { @@ -1363,7 +1373,7 @@ GSM_Error SMSD_ProcessSMS(GSM_SMSDConfig *Config, GSM_MultiSMSMessage *sms) error = Config->Service->SaveInboxSMS(sms, Config, &locations); /* RunOnReceive handling */ if (Config->RunOnReceive != NULL && error == ERR_NONE) { - SMSD_RunOn(Config->RunOnReceive, sms, Config, locations); + SMSD_RunOn(Config->RunOnReceive, sms, Config, locations, "receive"); } /* Free memory allocated by SaveInboxSMS */ free(locations); @@ -1653,6 +1663,7 @@ GSM_Error SMSD_SendSMS(GSM_SMSDConfig *Config) GSM_Error error; unsigned int j; int i, z; + char destinationnumber[3 * GSM_MAX_NUMBER_LENGTH + 1]; /* Clean structure before use */ for (i = 0; i < GSM_MAX_MULTI_SMS; i++) { @@ -1683,6 +1694,10 @@ GSM_Error SMSD_SendSMS(GSM_SMSDConfig *Config) if (Config->SMSID[0] != 0 && (Config->retries > Config->maxretries)) { SMSD_Log(DEBUG_NOTICE, Config, "Moved to errorbox, reached MaxRetries: %s", Config->SMSID); for (i=0;i<sms.Number;i++) { + if (Config->SkipMessage[i] == TRUE) { + SMSD_Log(DEBUG_NOTICE, Config, "Skipping %s:%d message for errorbox", Config->SMSID, i+1); + continue; + } Config->Status->Failed++; Config->Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i + 1, SMSD_SEND_SENDING_ERROR, Config->TPMR); } @@ -1694,6 +1709,11 @@ GSM_Error SMSD_SendSMS(GSM_SMSDConfig *Config) } for (i = 0; i < sms.Number; i++) { + if (Config->SkipMessage[i] == TRUE) { + SMSD_Log(DEBUG_NOTICE, Config, "Skipping %s:%d message for delivery", Config->SMSID, i+1); + continue; + } + /* No SMSC set in message */ if (sms.SMS[i].SMSC.Location == 0 && UnicodeLength(sms.SMS[i].SMSC.Number) == 0 && Config->SMSC.Location == 0) { SMSD_Log(DEBUG_INFO, Config, "Message without SMSC, using configured one"); @@ -1739,7 +1759,22 @@ GSM_Error SMSD_SendSMS(GSM_SMSDConfig *Config) SMSD_PhoneStatus(Config); Config->TPMR = -1; Config->SendingSMSStatus = ERR_TIMEOUT; - error = GSM_SendSMS(Config->gsm, &sms.SMS[i]); + Config->StatusCode = -1; + Config->Part = i + 1; + if (sms.SMS[i].Class == GSM_SMS_USSD) { + EncodeUTF8(destinationnumber, sms.SMS[i].Number); + SMSD_Log(DEBUG_NOTICE, Config, "Sending USSD request to %s", destinationnumber); + error = GSM_DialService(Config->gsm, destinationnumber); + /* Fallback to voice call, it can work with some phones */ + if (error == ERR_NOTIMPLEMENTED || error == ERR_NOTSUPPORTED) { + error = GSM_DialVoice(Config->gsm, destinationnumber, GSM_CALL_DefaultNumberPresence); + } + if (error == ERR_NONE) { + Config->SendingSMSStatus = ERR_NONE; + } + } else { + error = GSM_SendSMS(Config->gsm, &sms.SMS[i]); + } if (error != ERR_NONE) { SMSD_LogError(DEBUG_INFO, Config, "Error sending SMS", error); Config->TPMR = -1; @@ -1787,13 +1822,13 @@ GSM_Error SMSD_SendSMS(GSM_SMSDConfig *Config) } if (Config->RunOnSent != NULL && error == ERR_NONE) { - SMSD_RunOn(Config->RunOnSent, &sms, Config, Config->SMSID); + SMSD_RunOn(Config->RunOnSent, &sms, Config, Config->SMSID, "sent"); } return ERR_NONE; failure_unsent: if (Config->RunOnFailure != NULL) { - SMSD_RunOn(Config->RunOnFailure, NULL, Config, Config->SMSID); + SMSD_RunOn(Config->RunOnFailure, NULL, Config, Config->SMSID, "failure"); } Config->Status->Failed++; @@ -1924,6 +1959,7 @@ GSM_Error SMSD_FreeSharedMemory(GSM_SMSDConfig *Config, gboolean writable) */ void SMSD_IncomingCallCallback(GSM_StateMachine *s, GSM_Call *call, void *user_data) { GSM_SMSDConfig *Config = user_data; + GSM_Error error; switch (call->Status) { case GSM_CALL_IncomingCall: { time_t now = time(NULL); @@ -1933,9 +1969,26 @@ void SMSD_IncomingCallCallback(GSM_StateMachine *s, GSM_Call *call, void *user_d SMSD_Log(DEBUG_INFO, Config, "Incoming call! # hanging up @%ld %ld.\n", now, lastRing); lastRing = now; if (call->CallIDAvailable) { - GSM_CancelCall(s, call->CallID, TRUE); - } else { - GSM_CancelCall(s, 0, TRUE); + error = GSM_CancelCall(s, call->CallID, TRUE); + } + if (!call->CallIDAvailable || error == ERR_NOTSUPPORTED) { + error = GSM_CancelCall(s, 0, TRUE); + } + if (error != ERR_NONE) { + SMSD_LogError(DEBUG_ERROR, Config, "Failed call hangup!", error); + } + + if (Config->RunOnIncomingCall != NULL) { +#define BUFS 1024 + char buf[BUFS]; + int ret=0; + snprintf(buf, BUFS,"%s '%s'", + Config->RunOnIncomingCall, + DecodeUnicodeString(call->PhoneNumber)); + ret = system(buf); + if (ret<0) { + SMSD_Log(DEBUG_ERROR, Config, "Incoming call - could not run script: %s\n", strerror(errno) ); + } } } break; @@ -1950,6 +2003,29 @@ void SMSD_IncomingCallCallback(GSM_StateMachine *s, GSM_Call *call, void *user_d } } +void SMSD_IncomingUSSDCallback(GSM_StateMachine *sm UNUSED, GSM_USSDMessage *ussd, void *user_data) +{ + GSM_MultiSMSMessage sms; + GSM_Error error; + GSM_SMSDConfig *Config = user_data; + + SMSD_Log(DEBUG_NOTICE, Config, "%s", __FUNCTION__); + + memset(&sms, 0, sizeof(GSM_MultiSMSMessage)); + sms.Number = 1; + sms.SMS[0].Class = GSM_SMS_USSD; + memcpy(&sms.SMS[0].Text, ussd->Text, UnicodeLength(ussd->Text)*2); + sms.SMS[0].PDU = SMS_Deliver; + sms.SMS[0].Coding = SMS_Coding_Unicode_No_Compression; + GSM_GetCurrentDateTime(&sms.SMS[0].DateTime); + sms.SMS[0].DeliveryStatus = ussd->Status; + + error = SMSD_ProcessSMS(Config, &sms); + if (error != ERR_NONE) { + SMSD_LogError(DEBUG_INFO, Config, "Error processing USSD", error); + } +} + /** * Main loop which takes care of connection to phone and processing of * messages. @@ -2010,7 +2086,7 @@ GSM_Error SMSD_MainLoop(GSM_SMSDConfig *Config, gboolean exit_on_failure, int ma error = GSM_InitConnection_Log(Config->gsm, 2, SMSD_Log_Function, Config); /* run on error */ if (error != ERR_NONE && Config->RunOnFailure != NULL) { - SMSD_RunOn(Config->RunOnFailure, NULL, Config, "INIT"); + SMSD_RunOn(Config->RunOnFailure, NULL, Config, "INIT", "failure"); } switch (error) { case ERR_NONE: @@ -2029,6 +2105,9 @@ GSM_Error SMSD_MainLoop(GSM_SMSDConfig *Config, gboolean exit_on_failure, int ma /* We use polling so store messages to SIM */ GSM_SetIncomingSMS(Config->gsm, TRUE); + GSM_SetIncomingUSSDCallback(Config->gsm, SMSD_IncomingUSSDCallback, Config); + GSM_SetIncomingUSSD(Config->gsm, TRUE); + GSM_SetSendSMSStatusCallback(Config->gsm, SMSD_SendSMSStatusCallback, Config); /* On first start we need to initialize some variables */ if (first_start) { @@ -2039,7 +2118,7 @@ GSM_Error SMSD_MainLoop(GSM_SMSDConfig *Config, gboolean exit_on_failure, int ma error = Config->Service->InitAfterConnect(Config); if (error!=ERR_NONE) { if (Config->RunOnFailure != NULL) { - SMSD_RunOn(Config->RunOnFailure, NULL, Config, "INIT"); + SMSD_RunOn(Config->RunOnFailure, NULL, Config, "INIT", "failure"); } SMSD_Terminate(Config, "Post initialisation failed, stopping Gammu smsd", error, TRUE, -1); goto done_connected; @@ -2150,6 +2229,7 @@ GSM_Error SMSD_MainLoop(GSM_SMSDConfig *Config, gboolean exit_on_failure, int ma SMSD_InterruptibleSleep(Config, Config->loopsleep - lastsleep); } } + GSM_SetIncomingUSSD(Config->gsm, FALSE); Config->Service->Free(Config); done_connected: |