On Fri, May 30, 2003 at 10:03:10AM +0200, [EMAIL PROTECTED] wrote:

> How can I get access to your modified code? The version I use know is 1.3.1 
> which I downloaded and compiled under a Suse Linux distribution 8.0. Do I get 
> your updated by downloading the newest src from the cvs? I also check the 
> signal quallity (AT+CSQ) which seems to be ok.

I think the included patch is what you want, I lost the oringal patch, so
diffed the orig with the patched version ... also forgot the author :(
I thought I'd archived it (I probably have somewhere very secure ...).

Steve

-- 
NetTek Ltd Phone/Fax +44-(0)20 7483 2455
SMS steve-pager (at) gbnet.net [body] gpg 1024D/468952DB 2001-09-19
--- smsc_at2.c.orig     2003-03-27 15:32:12.000000000 +0000
+++ smsc_at2.c  2003-03-27 15:55:08.000000000 +0000
@@ -452,14 +452,7 @@
 
     if (privdata->sms_memory_poll_interval && privdata->modem->message_storage) {
         /* set message storage location for "SIM buffering" using the CPMS command */
-        Octstr *temp;
-        temp = octstr_create("AT+CPMS=");
-        octstr_append_char(temp, 34);
-        octstr_append(temp, privdata->modem->message_storage);
-        octstr_append_char(temp, 34);
-        ret = at2_send_modem_command(privdata, octstr_get_cstr(temp), 0, 0);
-        octstr_destroy(temp);
-        if (ret != 0)
+        if (at2_set_message_storage(privdata, privdata->modem->message_storage) != 0)
             return -1;
     }
 
@@ -529,6 +522,16 @@
                 ret = 1;
                 goto end;
             }
+           if (octstr_search(line, octstr_imm("+CMTI:"), 0) != -1 || 
+               octstr_search(line, octstr_imm("+CDSI:"), 0) != -1) {
+               /*
+                  we received an incoming message indication
+                  put it in the pending_incoming_messages queue for later retrieval
+               */
+               debug("bb.smsc.at2", 0, "AT2[%s]: +CMTI incoming SMS indication: %s", 
octstr_get_cstr(privdata->name), octstr_get_cstr(line));
+               list_append(privdata->pending_incoming_messages, (void 
*)octstr_create(octstr_get_cstr(line)));
+                continue;
+           }
             if (octstr_search(line, octstr_imm("+CMT:"), 0) != -1 ||
                octstr_search(line, octstr_imm("+CDS:"), 0) != -1 ||
                 ((octstr_search(line, octstr_imm("+CMGR:"), 0) != -1) && (cmgr_flag = 
1)) ) {
@@ -606,11 +609,132 @@
     return ret;
 }
 
-
-void at2_read_sms_memory(PrivAT2data* privdata)
+int at2_read_delete_message(PrivAT2data* privdata, int message_number)
 {
     char cmd[20];
+    int message_count = 0;
+
+    sprintf(cmd, "AT+CMGR=%d", message_number);
+    /* read one message from memory */
+    at2_write_line(privdata, cmd);
+    if (at2_wait_modem_command(privdata, 0, 0, &message_count) != 0) {
+       debug("bb.smsc.at2", 0, "AT2[%s]: failed to get message %d.", 
+           octstr_get_cstr(privdata->name), message_number);
+        return 0; /* failed to read the message - skip to next message */
+    }
+
+    /* no need to delete if no message collected */
+    if (!message_count) { 
+       debug("bb.smsc.at2", 0, "AT2[%s]: not deleted.", 
+           octstr_get_cstr(privdata->name));
+        return 0;
+    }
+
+    sprintf(cmd, "AT+CMGD=%d", message_number); /* delete the message we just read */
+    /* 
+    * 3 seconds (default timeout of send_modem_command()) is not enough with some
+    * modems if the message is large, so we'll give it 7 seconds 
+    */
+    if (at2_send_modem_command(privdata, cmd, 7, 0) != 0) {  
+       /* 
+       * failed to delete the message, we'll just ignore it for now, 
+       * this is bad, since if the message really didn't get deleted
+       * we'll see it next time around. 
+       */                
+        error(2, "AT2[%s]: failed to delete message %d.",
+           octstr_get_cstr(privdata->name), message_number);
+    }
 
+    return 1;
+}
+
+/*
+ * This function loops through the pending_incoming_messages queue for CMTI
+ * notifications.
+ * Every notification is parsed and the messages are read (and deleted)
+ * accordingly.
+*/
+void at2_read_pending_incoming_messages(PrivAT2data* privdata)
+{
+    Octstr *current_storage = NULL;
+
+    if (privdata->modem->message_storage) {
+           current_storage = octstr_duplicate(privdata->modem->message_storage);
+    }
+    while (list_len(privdata->pending_incoming_messages) > 0) {
+        int pos;
+        long location;
+        Octstr *cmti_storage = NULL, *line = NULL;
+        
+        line = list_extract_first(privdata->pending_incoming_messages);
+       /* message memory starts after the first quote in the string */
+        if ((pos = octstr_search_char(line, '"', 0)) != -1) {
+            /* grab memory storage name */
+            int next_quote = octstr_search_char(line, '"', ++pos);
+            if (next_quote == -1) { /* no second qoute - this line must be broken 
somehow */
+                O_DESTROY(line);
+                continue;
+           }
+
+            /* store notification storage location for reference */
+            cmti_storage = octstr_copy(line, pos, next_quote - pos);
+        } else
+            /* reset pos for the next lookup which would start from the beginning if 
no memory
+             * location was found */
+            pos = 0; 
+
+        /* if no message storage is set in configuration - set now */
+        if (!privdata->modem->message_storage && cmti_storage) { 
+            info(2, "AT2[%s]: CMTI received, but no message-storage is set in 
confiuration."
+                "setting now to <%s>", octstr_get_cstr(privdata->name), 
octstr_get_cstr(cmti_storage));
+            privdata->modem->message_storage = octstr_duplicate(cmti_storage);
+            current_storage = octstr_duplicate(cmti_storage);
+            at2_set_message_storage(privdata, cmti_storage);
+       }
+
+        /* find the message id from the line, which should appear after the first 
comma */
+        if ((pos = octstr_search_char(line, ',', pos)) == -1) { /* this CMTI 
notification is probably broken */
+            error(2, "AT2[%s]: failed to find memory location in CMTI notification",
+                octstr_get_cstr(privdata->name));
+               O_DESTROY(line);
+               octstr_destroy(cmti_storage);
+            continue;
+        }
+
+        if ((pos = octstr_parse_long(&location, line, ++pos, 10)) == -1) {
+            /* there was an error parsing the message id. next! */
+            error(2, "AT2[%s]: error parsing memory location in CMTI notification",
+                octstr_get_cstr(privdata->name));
+               O_DESTROY(line);
+               octstr_destroy(cmti_storage);
+            continue;
+        }
+
+        /* check if we need to change storage location before issuing the read 
command */
+        if (!current_storage || (octstr_compare(current_storage, cmti_storage) != 0)) 
{
+           octstr_destroy(current_storage);
+           current_storage = octstr_duplicate(cmti_storage);
+            at2_set_message_storage(privdata, cmti_storage);
+       }
+        
+        if (!at2_read_delete_message(privdata, location)) {
+            error(1,"AT2[%s]: CMTI notification received, but no message found in 
memory!",
+                octstr_get_cstr(privdata->name));
+        }
+
+        
+        octstr_destroy(line);
+        octstr_destroy(cmti_storage);
+    }
+    /* set prefered message storage back to what configured */
+    if (current_storage && privdata->modem->message_storage && 
(octstr_compare(privdata->modem->message_storage, current_storage) != 0))
+       at2_set_message_storage(privdata, privdata->modem->message_storage);
+
+    octstr_destroy(current_storage);
+}
+
+void at2_read_sms_memory(PrivAT2data* privdata)
+{
     /* get memory status */
     if (at2_check_sms_memory(privdata) == -1) {
         debug("bb.smsc.at2", 0, "AT2[%s]: memory check error", 
octstr_get_cstr(privdata->name));
@@ -653,40 +777,15 @@
          * loop till end of memory or collected enouch messages
          */
         for (i = 1; i <= privdata->sms_memory_capacity &&
-             message_count < privdata->sms_memory_usage; ++i) { 
-            int old_message_count = message_count;
-            sprintf(cmd, "AT+CMGR=%d", i);
-            /* read one message from memory */
-            at2_write_line(privdata, cmd);
-            if (at2_wait_modem_command(privdata, 0, 0, &message_count) != 0) {
-                debug("bb.smsc.at2", 0, "AT2[%s]: failed to get message %d.", 
-                      octstr_get_cstr(privdata->name), i);
-                continue; /* failed to read the message - skip to next message */
-            }
-
-            /* no need to delete if no message collected */
-            if (old_message_count == message_count) { 
-                debug("bb.smsc.at2", 0, "AT2[%s]: not deleted.", 
-                      octstr_get_cstr(privdata->name));
-                continue;
-            }
-
-            sprintf(cmd, "AT+CMGD=%d", i); /* delete the message we just read */
-            /* 
-             * 3 seconds is not enough with some modems if the message is large,
-             * so we'll give it 7 seconds 
-             */
-            if (at2_send_modem_command(privdata, cmd, 7, 0) != 0) {  
-                /* 
-                 * failed to delete the message, we'll just ignore it for now, 
-                 * this is bad, since if the message really didn't get deleted
-                 * we'll see it next time around. 
-                 */                
-                debug("bb.smsc.at2", 0, "AT2[%s]: failed to delete message %d.", 
-                      octstr_get_cstr(privdata->name), i);
-                continue; 
+            message_count < privdata->sms_memory_usage; ++i) { 
 
-            }
+           /* if (meanwhile) there are pending CMTI notifications, process these first
+            * to not let CMTI and sim buffering sit in each others way */
+           while (list_len(privdata->pending_incoming_messages) > 0) {
+                   at2_read_pending_incoming_messages(privdata);
+           }
+           /* read the message and delete it */
+            message_count += at2_read_delete_message(privdata, i);
         }
     }
     /*
@@ -896,6 +995,10 @@
         } else
             at2_wait_modem_command(privdata, 1, 0, NULL);
 
+       while (list_len(privdata->pending_incoming_messages) > 0) {
+               at2_read_pending_incoming_messages(privdata);
+       }
+
         if (privdata->keepalive &&
             idle_timeout + privdata->keepalive < time(NULL)) {
             if (at2_send_modem_command(privdata, 
@@ -928,6 +1031,7 @@
     octstr_destroy(privdata->name);
     octstr_destroy(privdata->configfile);
     list_destroy(privdata->outgoing_queue, NULL);
+    list_destroy(privdata->pending_incoming_messages, octstr_destroy_item);
     gw_free(conn->data);
     conn->data = NULL;
     conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
@@ -1014,6 +1118,7 @@
 
     privdata = gw_malloc(sizeof(PrivAT2data));
     privdata->outgoing_queue = list_create();
+    privdata->pending_incoming_messages = list_create();
 
     privdata->configfile = cfg_get_configfile(cfg);
 
@@ -2261,3 +2366,19 @@
     O_DESTROY(temp);
     return out;        
 }
+
+int at2_set_message_storage(PrivAT2data* privdata, Octstr* memory_name)
+{
+    Octstr *temp;
+    int ret;
+
+    if (!memory_name || !privdata)
+        return -1;
+
+    temp = octstr_format("AT+CPMS=\"%S\"", memory_name);
+    ret = at2_send_modem_command(privdata, octstr_get_cstr(temp), 0, 0);
+    octstr_destroy(temp);
+    if (ret != 0)
+            return -1;
+    return 0;
+}

Reply via email to