Hi,
here is a patch that adds support for operation type 02 in EMI UCP. It allows to send a sms to multiple recipient. I get all the recipient and send one message to each. I'm not sure this is the proper way to handle this, but I looked at SMPP and it's not implemented either, and I didn't find function of the bearerbox that allow multiple recipients.

In order to write this patch, I had to modify the field_count_op and emimsg_create_op to add the ability to handle variable size messages. Tell me what you think of the way I did it, and if you have a better idea.

As the previous one, this patch should be applied after the others.

Regards,
--
Colin Pitrat (Bull Services Telco)
Bull,  Architect of an Open World (TM)
Tél : +33 (0)  1 30 80 72 93
www.bull.com
diff -ru gateway/gw/smsc/emimsg.c gateway-new/gw/smsc/emimsg.c
--- gateway/gw/smsc/emimsg.c    2006-08-23 15:39:59.000000000 +0200
+++ gateway-new/gw/smsc/emimsg.c        2006-08-25 14:33:48.000000000 +0200
@@ -108,13 +108,13 @@
 }
 
 
-static int field_count_op(int ot, Octstr *whoami)
+static int field_count_op(int ot, Octstr *whoami, int supplementary)
 {
     switch (ot) {
     case 01:
        return SZ01;
     case 02:
-       return SZ02;
+       return SZ02 + supplementary;
     case 03:
        return SZ03;
     case 31:
@@ -173,12 +173,12 @@
 }
 
 
-struct emimsg *emimsg_create_op(int ot, int trn, Octstr *whoami)
+struct emimsg *emimsg_create_op(int ot, int trn, Octstr *whoami, int 
supplementary)
 {
     int len;
     struct emimsg *ret;
 
-    len = field_count_op(ot, whoami);
+    len = field_count_op(ot, whoami, supplementary);
     if (len < 0)
        return NULL;
     ret = emimsg_create_withlen(len);
@@ -297,7 +297,14 @@
     if (octstr_parse_long(&ot, message, 12, 10) != 14)
        goto error;
     if (or == 'O')
-       result = emimsg_create_op(ot, trn, whoami);
+    {
+       long supplementary = 0;
+        if(ot == 2 && octstr_parse_long(&supplementary, message, 15, 10) < 0)
+           goto error;
+       if(supplementary)
+           supplementary--;
+       result = emimsg_create_op(ot, trn, whoami, supplementary);
+    }
     else {
        posit = octstr_get_char(message, 15);
        if (posit == 'A')
diff -ru gateway/gw/smsc/emimsg.h gateway-new/gw/smsc/emimsg.h
--- gateway/gw/smsc/emimsg.h    2006-08-23 15:39:59.000000000 +0200
+++ gateway-new/gw/smsc/emimsg.h        2006-08-25 14:12:37.000000000 +0200
@@ -105,7 +105,7 @@
 };
 
 
-struct emimsg *emimsg_create_op(int ot, int trn, Octstr *whoami);
+struct emimsg *emimsg_create_op(int ot, int trn, Octstr *whoami, int 
supplementary);
 
 
 struct emimsg *emimsg_create_reply(int ot, int trn, int positive,
diff -ru gateway/gw/smsc/smsc_emi.c gateway-new/gw/smsc/smsc_emi.c
--- gateway/gw/smsc/smsc_emi.c  2006-08-25 14:34:17.000000000 +0200
+++ gateway-new/gw/smsc/smsc_emi.c      2006-08-25 14:33:03.000000000 +0200
@@ -262,7 +262,7 @@
     struct emimsg *emimsg;
 
     if(octstr_len(privdata->username) || octstr_len(privdata->my_number)) {
-        emimsg = emimsg_create_op(31, trn, privdata->name);
+        emimsg = emimsg_create_op(31, trn, privdata->name, 0);
         if(octstr_len(privdata->username)) {
             emimsg->fields[0] = octstr_duplicate(privdata->username);
        } else {
@@ -280,7 +280,7 @@
 {
     struct emimsg *emimsg;
 
-    emimsg = emimsg_create_op(60, 0, privdata->name);
+    emimsg = emimsg_create_op(60, 0, privdata->name, 0);
     emimsg->fields[E60_OADC] = octstr_duplicate(privdata->username);
     emimsg->fields[E60_OTON] = octstr_create("6");
     emimsg->fields[E60_ONPI] = octstr_create("5");
@@ -437,7 +437,7 @@
     struct tm tm;
     char p[20];
 
-    emimsg = emimsg_create_op(51, trn, privdata->name);
+    emimsg = emimsg_create_op(51, trn, privdata->name, 0);
     str = octstr_duplicate(msg->sms.sender);
     if(octstr_get_char(str,0) == '+') {
        /* either alphanum or international */
@@ -939,6 +939,156 @@
      * of the protocol implementation.
      */
     case 02:
+       {
+           int offset, nb_messages;
+           Octstr *str1, *str2, *str3, *comma;
+           int i;
+           Msg **messages = NULL;
+           /* 
+            * The offset should be added to all E02_XXX except NPL
+            * because there are nb_messages fields for E02_RAD
+            */
+           if(emimsg->fields[E02_NPL] == NULL)
+           {
+               warning(0, "EMI2[%s]: required field NPL missing for ot=2",
+                       octstr_get_cstr(privdata->name));
+               return -1;
+           }
+           nb_messages = atoi(octstr_get_cstr(emimsg->fields[E02_NPL]));
+           offset = nb_messages - 1;
+           messages = gw_malloc(sizeof(Msg*) * nb_messages);
+           for(i = 0; i < nb_messages; i++)
+               messages[i] = msg_create(sms);
+
+           if (emimsg->fields[E02_MT + offset] == NULL) {
+               warning(0, "EMI2[%s]: required field MT missing",
+                       octstr_get_cstr(privdata->name));
+               /* This guess could be incorrect, maybe the message should just
+                  be dropped */
+               emimsg->fields[E02_MT + offset] = octstr_create("3");
+           }
+
+           switch(octstr_get_char(emimsg->fields[E02_MT + offset], 0))
+           {
+               case '2':
+                   if (emimsg->fields[E02_AMSG + offset] == NULL)
+                       emimsg->fields[E02_AMSG + offset] = octstr_create("");
+                   for(i = 0; i < nb_messages; i++)
+                   {
+                       messages[i]->sms.msgdata = 
octstr_duplicate(emimsg->fields[E02_AMSG + offset]);
+                   }
+                   break;
+
+               case '3':
+                   if (emimsg->fields[E02_AMSG + offset] == NULL)
+                       emimsg->fields[E02_AMSG + offset] = octstr_create("");
+                   else if (octstr_hex_to_binary(emimsg->fields[E02_AMSG + 
offset]) == -1)
+                       warning(0, "EMI2[%s]: Couldn't decode message text",
+                               octstr_get_cstr(privdata->name));
+
+                   //else if (octstr_get_char(emimsg->fields[E02_MT + offset], 
0) == '3') 
+                   for(i = 0; i < nb_messages; i++)
+                   {
+                       messages[i]->sms.msgdata = 
octstr_duplicate(emimsg->fields[E02_AMSG + offset]);
+
+                       /* obey the NRC (national replacement codes) */
+                       if (privdata->alt_charset == EMI_NRC_ISO_21)
+                           
charset_nrc_iso_21_german_to_gsm(messages[i]->sms.msgdata);
+
+                       charset_gsm_to_latin1(messages[i]->sms.msgdata);
+                   }
+                   break; 
+
+               default:
+                   error(0, "EMI2[%s]: MT == %s isn't supported for operation 
type 01",
+                           octstr_get_cstr(privdata->name),
+                           octstr_get_cstr(emimsg->fields[E02_MT + offset]));
+                   for(i = 0; i < nb_messages; i++)
+                       messages[i]->sms.msgdata = octstr_create("");
+                   break;
+           }
+
+           if(octstr_len(emimsg->fields[E02_OADC + offset]))
+           {
+               for(i = 0; i < nb_messages; i++)
+                   messages[i]->sms.sender = 
octstr_duplicate(emimsg->fields[E02_OADC + offset]);
+           }
+           else
+           {
+               warning(0, "EMI2[%s]: Empty sender field in received message",
+                       octstr_get_cstr(privdata->name));
+               for(i = 0; i < nb_messages; i++)
+                   messages[i]->sms.sender = octstr_create("");
+           }
+
+           if(octstr_len(PRIVDATA(conn)->my_number)) 
+           {
+               for(i = 0; i < nb_messages; i++)
+                   messages[i]->sms.receiver = 
octstr_duplicate(PRIVDATA(conn)->my_number);
+           }
+           else
+           {
+               for(i = 0; i < nb_messages; i++)
+               {
+                   if(octstr_len(emimsg->fields[E02_RAD + i]))
+                   {
+                       messages[i]->sms.receiver = 
octstr_duplicate(emimsg->fields[E02_RAD + i]);
+                   }
+                   else
+                   {
+                       warning(0, "EMI2[%s]: Empty receiver field in received 
message",
+                               octstr_get_cstr(privdata->name));
+                       messages[i]->sms.receiver = octstr_create("");
+                   }
+               }
+           }
+
+           for(i = 0; i < nb_messages; i++)
+           {
+               /* Operation type 02 doesn't have a time stamp field */
+               time(&messages[i]->sms.time);
+
+               messages[i]->sms.smsc_id = octstr_duplicate(conn->id);
+               bb_smscconn_receive(conn, messages[i]);
+           }
+
+           reply = emimsg_create_reply(02, emimsg->trn, 1, privdata->name);
+           /*
+            * SM field should contain a comma separated list of AdC:SCTS
+            * where SCTS is the timestamp on existing addresses, or empty
+            * on non existing addresses.
+            * If there is no existing addresses, SM should contain a 
+            * negative value.
+            * As we don't have this information, we always put the timestamp.
+            */
+           str1 = NULL;
+           str2 = NULL;
+           str3 = NULL;
+           comma = octstr_create(",");
+           for(i = 0; i < nb_messages; i++)
+           {
+               str1 = create_0x_SM_field(emimsg->fields[E02_RAD + i]);
+               if(str3 == NULL)
+               {
+                   str2 = octstr_create("");
+               }
+               else
+               {
+                   str2 = octstr_cat(str3, comma);
+                   octstr_destroy(str3);
+               }
+               str3 = octstr_cat(str2, str1);
+               octstr_destroy(str2);
+               octstr_destroy(str1);
+           }
+           octstr_destroy(comma);
+           reply->fields[1] = str3;
+           str3 = NULL;
+
+           st_code = emi2_emimsg_send(conn, server, reply);
+           emimsg_destroy(reply);
+           return (st_code < 0 ? -1 : 1);
+       }
     /*
      * Handle OP/03 call input with suplementary services operation. This is 
      * the MO side of the protocol implementation. 
begin:vcard
fn:Colin Pitrat
n:Pitrat;Colin
org:Bull;Telco
adr:;;rue Jean Jaures;Les Clayes sous Bois;;78340;France
email;internet:[EMAIL PROTECTED]
tel;work:+33 1 30 80 72 93
x-mozilla-html:FALSE
url:http://www.bull.com
version:2.1
end:vcard

Reply via email to