summaryrefslogtreecommitdiff
path: root/smsd/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'smsd/core.c')
-rw-r--r--smsd/core.c106
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: