Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
[gnokii.git] / smsd / db.c
index 8d553b2..204369f 100644 (file)
--- a/smsd/db.c
+++ b/smsd/db.c
 
 */
 
 
 */
 
+#define ATS_PRAHA 1
+
 #include <string.h>
 #include <glib.h>
 #include <string.h>
 #include <glib.h>
-#include <libpq-fe.h>
+#include <pgsql/libpq-fe.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
 #include "db.h"
 #include "smsd.h"
 #include "gsm-common.h"
 #include "db.h"
 #include "smsd.h"
 #include "gsm-common.h"
+#include "gsm-ringtones.h"
+#include "gsm-filetypes.h"
 
 static PGconn *connIn = NULL;
 static PGconn *connOut = NULL;
 
 static PGconn *connIn = NULL;
 static PGconn *connOut = NULL;
@@ -71,7 +81,7 @@ gint DB_InsertSMS (const GSM_SMSMessage * const data)
   buf = g_string_sized_new (128);
   g_string_sprintf (buf, "INSERT INTO inbox VALUES ('%s',
                     '%02d-%02d-%02d %02d:%02d:%02d+01', 'now', '%s', 'f')",
   buf = g_string_sized_new (128);
   g_string_sprintf (buf, "INSERT INTO inbox VALUES ('%s',
                     '%02d-%02d-%02d %02d:%02d:%02d+01', 'now', '%s', 'f')",
-                    data->RemoteNumber.number, data->Time.Year + 2000, data->Time.Month,
+                    data->Sender, data->Time.Year + 2000, data->Time.Month,
                     data->Time.Day, data->Time.Hour, data->Time.Minute,
                     data->Time.Second, data->MessageText);
   res = PQexec(connIn, buf->str);
                     data->Time.Day, data->Time.Hour, data->Time.Minute,
                     data->Time.Second, data->MessageText);
   res = PQexec(connIn, buf->str);
@@ -87,6 +97,30 @@ gint DB_InsertSMS (const GSM_SMSMessage * const data)
   return (0);
 }
 
   return (0);
 }
 
+#define DBL_FieldString "id, number, text, hexencode, type, fromfile, netcode, udhpresent, longuseudh, eightbit, smsc"
+enum DBL_Field {
+  DBLF_id,
+  DBLF_number,
+  DBLF_text,
+  DBLF_hexencode,
+  DBLF_type,
+  DBLF_fromfile,
+  DBLF_netcode,
+  DBLF_udhpresent,
+  DBLF_longuseudh,
+  DBLF_eightbit,
+  DBLF_smsc,
+  };
+
+#define DBL_true  "t"
+#define DBL_false "f"
+
+static int DBL_safestrcasecmp(const char *s1,const char *s2)
+{
+       if (!s1 || !s2)
+               return((!!s1)-(!!s2));
+       return(strcasecmp(s1,s2));
+}
 
 void DB_Look (void)
 {
 
 void DB_Look (void)
 {
@@ -96,12 +130,13 @@ void DB_Look (void)
 
   buf = g_string_sized_new (128);
 
 
   buf = g_string_sized_new (128);
 
+#ifndef ATS_PRAHA
   g_string_sprintf (buf, "BEGIN");
   g_string_sprintf (buf, "BEGIN");
-
   res1 = PQexec(connOut, buf->str);
   PQclear (res1);
   res1 = PQexec(connOut, buf->str);
   PQclear (res1);
+#endif
 
 
-  g_string_sprintf (buf, "SELECT id, number, text FROM outbox \
+  g_string_sprintf (buf, "SELECT " DBL_FieldString " FROM outbox \
                           WHERE processed='f' FOR UPDATE");
 
   res1 = PQexec(connOut, buf->str);
                           WHERE processed='f' FOR UPDATE");
 
   res1 = PQexec(connOut, buf->str);
@@ -119,34 +154,133 @@ void DB_Look (void)
   for (i = 0; i < PQntuples (res1); i++)
   {
     GSM_SMSMessage sms;
   for (i = 0; i < PQntuples (res1); i++)
   {
     GSM_SMSMessage sms;
+    char *type = PQgetvalue (res1, i, DBLF_type);
+    bool fromfile = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_fromfile));
+    char *smsc = PQgetvalue (res1, i, DBLF_smsc);
+    char *smsbuf = PQgetvalue (res1, i, DBLF_text);
+    size_t smsbuflen = strlen(smsbuf);
+    bool sendlogo;
     
     
-    sms.MessageCenter.No = 1;
-    sms.Type = SMS_Submit;
-    sms.DCS.Type = SMS_GeneralDataCoding;
-    sms.DCS.u.General.Compressed = false;
-    sms.DCS.u.General.Alphabet = SMS_DefaultAlphabet;
-    sms.DCS.u.General.Class = 0;
-    sms.Validity.VPF = SMS_RelativeFormat;
-    sms.Validity.u.Relative = 4320; /* 4320 minutes == 72 hours */
-    sms.UDH_No = 0;
-    sms.Report = false;
-
-    strncpy (sms.RemoteNumber.number, PQgetvalue (res1, i, 1), GSM_MAX_DESTINATION_LENGTH + 1);
-    sms.RemoteNumber.number[GSM_MAX_DESTINATION_LENGTH] = '\0';
-    if (sms.RemoteNumber.number[0] == '+') sms.RemoteNumber.type = SMS_International;
-    else sms.RemoteNumber.type = SMS_Unknown;
-    
-    strncpy (sms.MessageText, PQgetvalue (res1, i, 2), GSM_MAX_SMS_LENGTH + 1);
-    sms.MessageText[GSM_MAX_SMS_LENGTH] = '\0';
+    if (!smsc)
+      sms.MessageCenter.No = 1;
+    else {
+      sms.MessageCenter.No = 0;
+      if (strlen(smsc)+1 > sizeof(sms.MessageCenter.Number))
+       continue;       /* error */
+      strcpy(sms.MessageCenter.Number, smsc);
+      }
+
+    sms.Type = GST_MO;
+    sms.Class = -1;
+    sms.Compression = false;
+    sms.EightBit = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_eightbit));
+    sms.Validity = 4320;
+    sms.UDHPresent = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_udhpresent));
+
+    if (!DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_hexencode))) {
+char *d_end = (char *)SMS_BlockFromHex(smsbuf/*d*/, smsbuf/*s*/, smsbuflen);
+
+      if (!d_end)
+       continue;
+      smsbuflen = d_end - smsbuf;
+      }
 
 
+    sendlogo=false;
+         if (!DBL_safestrcasecmp("ringtone"    ,type)) {
+      SMS_SetupUDH(&sms, GSM_RingtoneUDH);
+      if (fromfile) {
+GSM_Ringtone ringtone;
+static char ringbuf[GSM_MAX_RINGTONE_PACKAGE_LENGTH];
+int ringbuflen=GSM_MAX_RINGTONE_PACKAGE_LENGTH;
+
+       if (GSM_ReadRingtoneFile(smsbuf, &ringtone))
+         continue;     /* error */
+       GSM_PackRingtone(&ringtone, ringbuf, &ringbuflen);
+       smsbuf=ringbuf;
+       smsbuflen=ringbuflen;
+       }
+      }
+    else if (!DBL_safestrcasecmp("oplogo"      ,type)) {
+      SMS_SetupUDH(&sms, GSM_OpLogo);
+      sendlogo=true;
+      }
+    else if (!DBL_safestrcasecmp("calleridlogo",type)) {
+      SMS_SetupUDH(&sms, GSM_CallerIDLogo);
+      sendlogo=true;
+      }
+    else { /* "text" */
+      if (fromfile) {
+static char textbuf[GSM_MAX_CONCATENATED_SMS_LENGTH];
+int textbuflen;
+int fd;
+
+       if (-1==(fd=open(smsbuf,O_RDONLY)))
+         continue;     /* error */
+       if (-1==(textbuflen=read(fd,textbuf,sizeof(textbuf))))
+         continue;     /* error */
+       close(fd);
+       smsbuf=textbuf;
+       smsbuflen=textbuflen;
+       }
+      if (sms.UDHPresent) {
+u8 len=1+(*(u8 *)smsbuf);
+
+       if (len>smsbuflen || len>sizeof(sms.UDH))
+         g_print ("%d: UDH too long: UDHlen=%d, smsbuflen=%d, sizeof(sms.UDH)=%d !!!\n", __LINE__,
+           len, smsbuflen,sizeof(sms.UDH));
+       else {
+         memcpy(sms.UDH,smsbuf,len);
+         memmove(smsbuf,smsbuf+len,smsbuflen-len);
+         smsbuflen-=len;
+         }
+       }
+      }
+
+    if (sendlogo) {
+GSM_Bitmap bitmap;
+static u8 bin[sizeof(bitmap.bitmap) +64/*headers safety*/];
+u8 *d;
+char *usernetcode=PQgetvalue (res1, i, DBLF_netcode);
+
+      if (GE_NONE!=GSM_ReadBitmapFile(smsbuf, &bitmap))
+       continue;       /* error */
+
+      d=bin;
+      if (!DBL_safestrcasecmp("oplogo"      ,type)) {
+       if (usernetcode) {
+         if (strlen(usernetcode)+1 > sizeof(bitmap.netcode))
+           continue;   /* error */
+         strcpy(bitmap.netcode, usernetcode);
+         }
+       *d++ = ((bitmap.netcode[1] & 0x0f) << 4) | (bitmap.netcode[0] & 0xf);
+       *d++ = 0xf0 | (bitmap.netcode[2] & 0x0f);
+       *d++ = ((bitmap.netcode[5] & 0x0f) << 4) | (bitmap.netcode[4] & 0xf);
+       }
+      /* Set the logo size */
+      *d++ = 0x00;         /* RFU by Nokia */
+      *d++ = bitmap.width;
+      *d++ = bitmap.height;
+      *d++ = 0x01;         /* depth=number of grayscales */
+
+      memcpy(d,bitmap.bitmap,bitmap.size);
+      d+=bitmap.size;
+
+      smsbuf=bin;
+      smsbuflen=d-bin;
+      }
+
+    strncpy (sms.Destination, PQgetvalue (res1, i, DBLF_number), GSM_MAX_DESTINATION_LENGTH + 1);
+    sms.Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';
+    
 #ifdef XDEBUG
 #ifdef XDEBUG
-    g_print ("%s, %s\n", sms.Destination, sms.MessageText);
+    g_print ("To: %s\n", sms.Destination);
 #endif
     
 #endif
     
-    if (WriteSMS (&sms) != 0)
+    if (GE_SMSSENDOK == WriteSMS_deconcatenated (&sms, smsbuf, smsbuflen,
+               !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_longuseudh))))
     {
       g_string_sprintf (buf, "UPDATE outbox SET processed='t' WHERE id='%s'",
     {
       g_string_sprintf (buf, "UPDATE outbox SET processed='t' WHERE id='%s'",
-                        PQgetvalue (res1, i, 0));
+                        PQgetvalue (res1, i, DBLF_id));
       res2 = PQexec(connOut, buf->str);
       if (!res2 || PQresultStatus (res2) != PGRES_COMMAND_OK)
       {
       res2 = PQexec(connOut, buf->str);
       if (!res2 || PQresultStatus (res2) != PGRES_COMMAND_OK)
       {
@@ -159,9 +293,20 @@ void DB_Look (void)
 
   PQclear (res1);
 
 
   PQclear (res1);
 
+#ifndef ATS_PRAHA
   g_string_sprintf (buf, "COMMIT");
   res1 = PQexec(connOut, buf->str);
   g_string_sprintf (buf, "COMMIT");
   res1 = PQexec(connOut, buf->str);
+  PQclear (res1);
+#endif
 
   g_string_free(buf, TRUE);
 
   g_string_free(buf, TRUE);
-  PQclear (res1);
+
+#ifdef ATS_PRAHA
+  if (!access("/tmp/smsd-exit",F_OK)) {
+    g_print("/tmp/smsd-exit exists, terminating\n");
+    if (unlink("/tmp/smsd-exit"))
+      g_print("/tmp/smsd-exit unlink failed: %s\n",strerror(errno));
+    exit(0);
+    }
+#endif
 }
 }