On Fri, May 30, 2003 at 01:02:15PM +0200, [EMAIL PROTECTED] wrote:
> I patched the file which worked without any error but got this when compiling
> the new file:
OK, here's the original patch ...
It's from "Rene Kluwen" <[EMAIL PROTECTED]>
I personally believe this should be included, or at least made an option
either at compile or runtime ...
Steve
--
NetTek Ltd Phone/Fax +44-(0)20 7483 2455
SMS steve-pager (at) gbnet.net [body] gpg 1024D/468952DB 2001-09-19
Index: gw/smsc/smsc_at2.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_at2.c,v
retrieving revision 1.12
diff -u -r1.12 smsc_at2.c
--- gw/smsc/smsc_at2.c 25 Nov 2002 16:29:27 -0000 1.12
+++ gw/smsc/smsc_at2.c 9 Dec 2002 17:00:18 -0000
@@ -458,14 +458,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;
}
@@ -535,6 +528,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)) ) {
@@ -609,11 +612,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));
@@ -656,40 +780,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);
}
}
/*
@@ -918,6 +1017,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,
@@ -950,6 +1053,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;
@@ -1036,6 +1140,7 @@
privdata = gw_malloc(sizeof(PrivAT2data));
privdata->outgoing_queue = list_create();
+ privdata->pending_incoming_messages = list_create();
privdata->configfile = cfg_get_configfile(cfg);
@@ -2284,4 +2389,20 @@
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;
}
Index: gw/smsc/smsc_at2.h
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_at2.h,v
retrieving revision 1.3
diff -u -r1.3 smsc_at2.h
--- gw/smsc/smsc_at2.h 25 Nov 2002 16:29:27 -0000 1.3
+++ gw/smsc/smsc_at2.h 9 Dec 2002 17:00:19 -0000
@@ -82,6 +82,7 @@
int sms_memory_poll_interval;
int sms_memory_capacity;
int sms_memory_usage;
+ List *pending_incoming_messages;
} PrivAT2data;
@@ -282,6 +283,13 @@
void at2_destroy_modem(ModemDef *modem);
/*
+ * Check 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);
+
+/*
* Checks whether any messages are buffered in message storage and extract them.
*/
void at2_read_sms_memory(PrivAT2data *privdata);
@@ -290,6 +298,18 @@
* Memory capacity and usage check
*/
int at2_check_sms_memory(PrivAT2data* privdata);
+
+/*
+ * Set the memory storage location of the modem by sending a +CPMS command
+ */
+int at2_set_message_storage(PrivAT2data* privdata, Octstr* memory_name);
+
+/*
+ * Reads a message from selected memory location and deletes it afterwards.
+ * returns 0 on failure and 1 on success
+ */
+int at2_read_delete_message(PrivAT2data* privdata, int message_number);
+
/*
* This silly thing here will just translate a "swapped nibble"