Re: [PATCH] EMI UCP - ot=02 : multiple address call input operation
Colin Pitrat <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Organization | Bull |
| Message-ID | <[email protected]> |
Wow it looks like I misread the documentation. Operations 02 and 03 can
only be initiated by the gateway, not by the SMSC, so this patch is
totally useless, and a part of the previous one too !
Colin Pitrat (Bull Services Telco)
Bull, Architect of an Open World (TM)
Tél : +33 (0) 1 30 80 72 93
www.bull.com
Colin Pitrat wrote:
> 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,
>
>
> ------------------------------------------------------------------------
>
> 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.
colin.pitrat.vcf
(text/x-vcard, 247 B)
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