static GSM_Error SMSDSQL_InitAfterConnect(GSM_SMSDConfig * Config) { SQL_result res; struct GSM_SMSDdbobj *db = Config->db; SQL_Var vars[3] = {{SQL_TYPE_STRING, {NULL}}, {SQL_TYPE_STRING, {NULL}}, {SQL_TYPE_NONE, {NULL}}}; if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_DELETE_PHONE], NULL, NULL, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error deleting from database (%s)", __FUNCTION__); return ERR_UNKNOWN; } db->FreeResult(Config, &res); SMSD_Log(DEBUG_INFO, Config, "Inserting phone info"); vars[0].v.s = Config->enable_send ? "yes" : "no"; vars[1].v.s = Config->enable_receive ? "yes" : "no"; if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_INSERT_PHONE], NULL, vars, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error inserting into database (%s)", __FUNCTION__); return ERR_UNKNOWN; } db->FreeResult(Config, &res); return ERR_NONE; }
static GSM_Error SMSDSQL_RefreshSendStatus(GSM_SMSDConfig * Config, char *ID) { SQL_result res; struct GSM_SMSDdbobj *db = Config->db; SQL_Var vars[2] = { {SQL_TYPE_STRING, {ID}}, {SQL_TYPE_NONE, {NULL}}}; if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_REFRESH_SEND_STATUS], NULL, vars, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__); return ERR_UNKNOWN; } if (db->AffectedRows(Config, &res) == 0) { db->FreeResult(Config, &res); return ERR_UNKNOWN; } db->FreeResult(Config, &res); return ERR_NONE; }
static GSM_Error SMSDSQL_UpdateRetries(GSM_SMSDConfig * Config, char *ID) { SQL_result res; struct GSM_SMSDdbobj *db = Config->db; SQL_Var vars[3] = { {SQL_TYPE_STRING, {ID}}, {SQL_TYPE_INT, {NULL}}, {SQL_TYPE_NONE, {NULL}}}; vars[1].v.i = Config->retries; if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_UPDATE_RETRIES], NULL, vars, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__); return ERR_UNKNOWN; } if (db->AffectedRows(Config, &res) == 0) { db->FreeResult(Config, &res); return ERR_UNKNOWN; } db->FreeResult(Config, &res); return ERR_NONE; }
/* Find one multi SMS to sending and return it (or return ERR_EMPTY) * There is also set ID for SMS */ static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char *ID) { SQL_result res; struct GSM_SMSDdbobj *db = Config->db; int i; time_t timestamp; const char *coding; const char *text; size_t text_len; const char *text_decoded; const char *destination; const char *udh; const char *q; size_t udh_len; SQL_Var vars[3]; vars[0].type = SQL_TYPE_INT; vars[0].v.i = 1; vars[1].type = SQL_TYPE_NONE; while (TRUE) { if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_SMS_ID], NULL, vars, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error reading from database (%s)", __FUNCTION__); return ERR_UNKNOWN; } if (db->NextRow(Config, &res) != 1) { db->FreeResult(Config, &res); return ERR_EMPTY; } sprintf(ID, "%ld", (long)db->GetNumber(Config, &res, 0)); timestamp = db->GetDate(Config, &res, 1); db->FreeResult(Config, &res); if (timestamp == -1) { SMSD_Log(DEBUG_INFO, Config, "Invalid date for InsertIntoDB."); return ERR_UNKNOWN; } SMSDSQL_Time2String(Config, timestamp, Config->DT, sizeof(Config->DT)); if (SMSDSQL_RefreshSendStatus(Config, ID) == ERR_NONE) { break; } } sms->Number = 0; for (i = 0; i < GSM_MAX_MULTI_SMS; i++) { GSM_SetDefaultSMSData(&sms->SMS[i]); sms->SMS[i].SMSC.Number[0] = 0; sms->SMS[i].SMSC.Number[1] = 0; } for (i = 1; i < GSM_MAX_MULTI_SMS + 1; i++) { vars[0].type = SQL_TYPE_STRING; vars[0].v.s = ID; vars[1].type = SQL_TYPE_INT; vars[1].v.i = i; vars[2].type = SQL_TYPE_NONE; if (i == 1) { q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_BODY]; } else { q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_MULTIPART]; } if (SMSDSQL_NamedQuery(Config, q, NULL, vars, &res) != SQL_OK) { SMSD_Log(DEBUG_ERROR, Config, "Error reading from database (%s)", __FUNCTION__); return ERR_UNKNOWN; } if (db->NextRow(Config, &res) != 1) { db->FreeResult(Config, &res); return ERR_NONE; } coding = db->GetString(Config, &res, 1); text = db->GetString(Config, &res, 0); if (text == NULL) { text_len = 0; } else { text_len = strlen(text); } text_decoded = db->GetString(Config, &res, 4); udh = db->GetString(Config, &res, 2); if (udh == NULL) { udh_len = 0; } else { udh_len = strlen(udh); } sms->SMS[sms->Number].Coding = GSM_StringToSMSCoding(coding); if (sms->SMS[sms->Number].Coding == 0) { if (text == NULL || text_len == 0) { SMSD_Log(DEBUG_NOTICE, Config, "Assuming default coding for text message"); sms->SMS[sms->Number].Coding = SMS_Coding_Default_No_Compression; } else { SMSD_Log(DEBUG_NOTICE, Config, "Assuming 8bit coding for binary message"); sms->SMS[sms->Number].Coding = SMS_Coding_8bit; } } if (text == NULL || text_len == 0) { if (text_decoded == NULL) { SMSD_Log(DEBUG_ERROR, Config, "Message without text!"); return ERR_UNKNOWN; } else { SMSD_Log(DEBUG_NOTICE, Config, "Message: %s", text_decoded); DecodeUTF8(sms->SMS[sms->Number].Text, text_decoded, strlen(text_decoded)); } } else { switch (sms->SMS[sms->Number].Coding) { case SMS_Coding_Unicode_No_Compression: case SMS_Coding_Default_No_Compression: DecodeHexUnicode(sms->SMS[sms->Number].Text, text, text_len); break; case SMS_Coding_8bit: DecodeHexBin(sms->SMS[sms->Number].Text, text, text_len); sms->SMS[sms->Number].Length = text_len / 2; break; default: break; } } if (i == 1) { destination = db->GetString(Config, &res, 6); if (destination == NULL) { SMSD_Log(DEBUG_ERROR, Config, "Message without recipient!"); return ERR_UNKNOWN; } DecodeUTF8(sms->SMS[sms->Number].Number, destination, strlen(destination)); } else { CopyUnicodeString(sms->SMS[sms->Number].Number, sms->SMS[0].Number); } sms->SMS[sms->Number].UDH.Type = UDH_NoUDH; if (udh != NULL && udh_len != 0) { sms->SMS[sms->Number].UDH.Type = UDH_UserUDH; sms->SMS[sms->Number].UDH.Length = udh_len / 2; DecodeHexBin(sms->SMS[sms->Number].UDH.Text, udh, udh_len); } sms->SMS[sms->Number].Class = db->GetNumber(Config, &res, 3); sms->SMS[sms->Number].PDU = SMS_Submit; sms->Number++; if (i == 1) { strcpy(Config->CreatorID, db->GetString(Config, &res, 10)); Config->relativevalidity = db->GetNumber(Config, &res, 8); Config->currdeliveryreport = db->GetBool(Config, &res, 9); /* Is this a multipart message? */ if (!db->GetBool(Config, &res, 7)) { db->FreeResult(Config, &res); break; } } db->FreeResult(Config, &res); } return ERR_NONE; }
/* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */ static GSM_Error SMSDSQL_SaveInboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char **Locations) { SQL_result res, res2; SQL_Var vars[3]; struct GSM_SMSDdbobj *db = Config->db; const char *q, *status; char smstext[3 * GSM_MAX_SMS_LENGTH + 1]; char destinationnumber[3 * GSM_MAX_NUMBER_LENGTH + 1]; char smsc_message[3 * GSM_MAX_NUMBER_LENGTH + 1]; int i; time_t t_time1, t_time2; gboolean found; long diff; unsigned long long new_id; size_t locations_size = 0, locations_pos = 0; const char *state, *smsc; *Locations = NULL; for (i = 0; i < sms->Number; i++) { EncodeUTF8(destinationnumber, sms->SMS[i].Number); EncodeUTF8(smsc_message, sms->SMS[i].SMSC.Number); if (sms->SMS[i].PDU == SMS_Status_Report) { EncodeUTF8(smstext, sms->SMS[i].Text); SMSD_Log(DEBUG_INFO, Config, "Delivery report: %s to %s", smstext, destinationnumber); if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_SELECT], &sms->SMS[i], NULL, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error reading from database (%s)", __FUNCTION__); return ERR_UNKNOWN; } found = FALSE; while (db->NextRow(Config, &res)) { smsc = db->GetString(Config, &res, 4); state = db->GetString(Config, &res, 1); SMSD_Log(DEBUG_NOTICE, Config, "Checking for delivery report, SMSC=%s, state=%s", smsc, state); if (strcmp(smsc, smsc_message) != 0) { if (Config->skipsmscnumber[0] == 0 || strcmp(Config->skipsmscnumber, smsc)) { continue; } } if (strcmp(state, "SendingOK") == 0 || strcmp(state, "DeliveryPending") == 0) { t_time1 = db->GetDate(Config, &res, 2); if (t_time1 < 0) { SMSD_Log(DEBUG_ERROR, Config, "Invalid SendingDateTime -1 for SMS TPMR=%i", sms->SMS[i].MessageReference); return ERR_UNKNOWN; } t_time2 = Fill_Time_T(sms->SMS[i].DateTime); diff = t_time2 - t_time1; if (diff > -Config->deliveryreportdelay && diff < Config->deliveryreportdelay) { found = TRUE; break; } else { SMSD_Log(DEBUG_NOTICE, Config, "Delivery report would match, but time delta is too big (%ld), consider increasing DeliveryReportDelay", diff); } } } if (found) { if (!strcmp(smstext, "Delivered")) { q = Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_UPDATE_DELIVERED]; } else { q = Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_UPDATE]; } if (!strcmp(smstext, "Delivered")) { status = "DeliveryOK"; } else if (!strcmp(smstext, "Failed")) { status = "DeliveryFailed"; } else if (!strcmp(smstext, "Pending")) { status = "DeliveryPending"; } else if (!strcmp(smstext, "Unknown")) { status = "DeliveryUnknown"; } else { status = ""; } vars[0].type = SQL_TYPE_STRING; vars[0].v.s = status; /* Status */ vars[1].type = SQL_TYPE_INT; vars[1].v.i = (long)db->GetNumber(Config, &res, 0); /* ID */ vars[2].type = SQL_TYPE_NONE; if (SMSDSQL_NamedQuery(Config, q, &sms->SMS[i], vars, &res2) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__); return ERR_UNKNOWN; } db->FreeResult(Config, &res2); } db->FreeResult(Config, &res); continue; } if (sms->SMS[i].PDU != SMS_Deliver) continue; if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_INSERT], &sms->SMS[i], NULL, &res) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__); return ERR_UNKNOWN; } new_id = db->SeqID(Config, "inbox_ID_seq"); if (new_id == 0) { SMSD_Log(DEBUG_INFO, Config, "Failed to get inserted row ID (%s)", __FUNCTION__); return ERR_UNKNOWN; } SMSD_Log(DEBUG_NOTICE, Config, "Inserted message id %lu", (long)new_id); db->FreeResult(Config, &res); if (new_id != 0) { if (locations_pos + 10 >= locations_size) { locations_size += 40; *Locations = (char *)realloc(*Locations, locations_size); assert(*Locations != NULL); if (locations_pos == 0) { *Locations[0] = 0; } } locations_pos += sprintf((*Locations) + locations_pos, "%lu ", (long)new_id); } if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_UPDATE_RECEIVED], &sms->SMS[i], NULL, &res2) != SQL_OK) { SMSD_Log(DEBUG_INFO, Config, "Error updating number of received messages (%s)", __FUNCTION__); return ERR_UNKNOWN; } db->FreeResult(Config, &res2); } return ERR_NONE; }