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