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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.