Andreas, do you mean that when sending a ringtone, I should not see the DCS
information (020104) in XSer part of the O/51 paquet ?
To help people who works on the development of emi2, I attached the diff
between the sources of smsc_emi2.c with the CVS version for which ringtones
work and the one for which it doesn't work.
Thanks in advance. Gildas.
> -----Message d'origine-----
> De : [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]De la part de Andreas Fink
> Envoy� : vendredi 14 septembre 2001 13:22
> � : [EMAIL PROTECTED]
> Objet : RE: Problem with the last CVS version when sending ringtone with
> emi2 (Xser incorrect ?)
>
>
> >The length is incorrect in the second one (010706050415810000020104).
> >The 020104 is not included in the length of the udh. Could it be that
> >these three bytes is appended after the length is calculated?
> >
> >/Christian.
> >
>
> no thats not it. The DCS value is NOT part of the UDH, its part of a
> EMI/UCP XSer structure. so the above means:
>
> XSer1 of 7 bytes being 06 05 04 15 81 00 00 thats the UDH header
> XSer2 of 1 byte being 04 thats the DCS information
>
>
> The question is why does it even have a DCS header?
>
>
>
> --
>
> Andreas Fink
> Fink-Consulting
>
> ------------------------------------------------------------------
> Tel: +41-61-6932730 Fax: +41-61-6932729 Mobile: +41-79-2457333
> Address: A. Fink, Schwarzwaldallee 16, 4058 Basel, Switzerland
> E-Mail: [EMAIL PROTECTED] Homepage: http://www.finkconsulting.com
> ------------------------------------------------------------------
> Something urgent? Try http://www.smsrelay.com/ Nickname afink
>
>
> diff smsc_emi2.c /opt/pck/gateway.old/gw/smsc_emi2.c
23d22
< #include "sms.h"
25d23
< #include "dlr.h"
45,47d42
< int keepalive; /* Seconds to send a Keepalive Command (OT=31)
*/
< int flowcontrol; /* 0=Windowing, 1=Stop-and-Wait */
< int waitack; /* Seconds to wait to ack */
103c98
< static struct emimsg *make_emi31(PrivData *privdata, int trn)
---
> static struct emimsg *make_emi31(PrivData *privdata)
107c102
< emimsg = emimsg_create_op(31, trn);
---
> emimsg = emimsg_create_op(31, 0);
200c195
< emimsg = make_emi31(privdata, 0);
---
> emimsg = make_emi31(privdata);
203,220c198,200
< result = wait_for_ack(privdata, server, 31, 30);
< /* XXX In here we can test if smsc doesn't know alert command, and we
< * could try to use other command, like 61
< */
< if (result == -2) {
< error(0, "smsc_emi2: Server rejected our alert, disabling keepalive");
< privdata->keepalive = 0;
< }
< else if (result == 0) {
< error(0, "smsc_emi2: Got no reply to alert attempt "
< "within 30 s");
< conn_destroy(server);
< continue;
< }
< else if (result == -1) { /* Broken connection, already logged */
< conn_destroy(server);
< continue;
< }
---
> privdata->unacked = 1;
> privdata->sendtype[0]= 31;
> privdata->sendtime[0] = time(NULL);
269,271d248
< int dcs;
< struct tm tm;
< char p[20];
273a251
>
275,289c253,256
< if(octstr_get_char(str,0) == '+') {
< /* either alphanum or international */
< if (!octstr_check_range(str, 1, 256, gw_isdigit)) {
< /* alphanumeric sender address with + in front*/
< charset_latin1_to_gsm(str);
< octstr_truncate(str, 11); /* max length of alphanumeric OaDC */
< emimsg->fields[E50_OTOA] = octstr_create("5039");
< pack_7bit(str);
< }
< else {
< /* international number. Set format and remove + */
< emimsg->fields[E50_OTOA] = octstr_create("1139");
< octstr_delete(str, 0, 1);
< octstr_truncate(str, 22); /* max length of numeric OaDC */
< }
---
> if (!octstr_check_range(str, 0, 256, gw_isdigit)) {
> /* alphanumeric sender address */
> emimsg->fields[E50_OTOA] = octstr_create("5039");
> pack_7bit(str);
291,300d257
< else {
< if (!octstr_check_range(str, 0, 256, gw_isdigit)) {
< /* alphanumeric sender address */
< charset_latin1_to_gsm(str);
< octstr_truncate(str, 11); /* max length of alphanumeric OaDC */
< emimsg->fields[E50_OTOA] = octstr_create("5039");
< pack_7bit(str);
< }
< }
<
303,315c260
< str = octstr_duplicate(msg->sms.receiver);
< if(octstr_get_char(str,0) == '+') {
< /* international number format */
< /* EMI doesnt understand + so we have to replace it with something useful */
< /* we try 00 here. Should really be done in the config instead so this */
< /* is only a workaround to make wrong configs work */
< octstr_delete(str, 0, 1);
< octstr_insert_data(str, 0, "00",2);
< }
< octstr_truncate(str, 16); /* max length of ADC */
< emimsg->fields[E50_ADC] = str;
<
< emimsg->fields[E50_XSER] = octstr_create("");
---
> emimsg->fields[E50_ADC] = octstr_duplicate(msg->sms.receiver);
317,318c262
< /* XSer1: UDH */
< if (octstr_len(msg->sms.udhdata)) {
---
> if (msg->sms.flag_udh) {
324,336c268
< octstr_append(emimsg->fields[E50_XSER],str);
< octstr_destroy(str);
< }
<
< /* XSer2: DCS */
< if ((dcs = fields_to_dcs(msg, 0))) {
< str = octstr_create("");
< octstr_append_char(str, 2);
< octstr_append_char(str, 1); /* len 01 */
< octstr_append_char(str, dcs);
< octstr_binary_to_hex(str, 1);
< octstr_append(emimsg->fields[E50_XSER],str);
< octstr_destroy(str);
---
> emimsg->fields[E50_XSER] = str;
339c271
< if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
---
> if (msg->sms.flag_8bit) {
361,387d292
< if (msg->sms.validity) {
< tm = gw_localtime(time(NULL) + msg->sms.validity * 60);
< sprintf(p, "%02d%02d%02d%02d%02d",
< tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100,
< tm.tm_hour, tm.tm_min);
< str = octstr_create(p);
< emimsg->fields[E50_VP] = str;
< }
< if (msg->sms.deferred) {
< str = octstr_create("1");
< emimsg->fields[E50_DD] = str;
< tm = gw_localtime(time(NULL) + msg->sms.deferred * 60);
< sprintf(p, "%02d%02d%02d%02d%02d",
< tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100,
< tm.tm_hour, tm.tm_min);
< str = octstr_create(p);
< emimsg->fields[E50_DDT] = str;
< }
<
< /* if delivery reports are asked, lets ask for them too */
< /* even the sender might not be interested in delivery or non delivery */
< /* we still need them back to clear out the memory after the message */
< /* has been delivered or non delivery has been confirmed */
< if(msg->sms.dlr_mask) {
< emimsg->fields[E50_NRQ] = octstr_create("1");
< emimsg->fields[E50_NT] = octstr_create("3");
< }
400c305
< Msg *msg = NULL;
---
> Msg *msg;
402d306
< int st_code;
404c308
<
---
> msg = msg_create(sms);
407d310
< msg = msg_create(sms);
446a350
> counter_increase(conn->received);
457d360
< msg = msg_create(sms);
476c379
< if (type != 1 && type != 2)
---
> if (type != 1)
479,496c382,386
< if (type == 1) {
< tempstr = octstr_copy(xser, 4, len * 2);
< if (octstr_hex_to_binary(tempstr) == -1)
< error(0, "Invalid UDH contents");
< msg->sms.udhdata = tempstr;
< }
< if (type == 2) {
< int dcs;
< tempstr = octstr_copy(xser, 4, 2);
< octstr_hex_to_binary(tempstr);
< dcs = octstr_get_char(tempstr, 0);
< octstr_destroy(tempstr);
< if (! dcs_to_fields(&msg, dcs)) {
< error(0, "emi2: invalid dcs received");
< /* XXX Should we discard message ? */
< dcs_to_fields(&msg, 0);
< }
< }
---
> tempstr = octstr_copy(xser, 4, len * 2);
> if (octstr_hex_to_binary(tempstr) == -1)
> error(0, "Invalid UDH contents");
> msg->sms.udhdata = tempstr;
> msg->sms.flag_udh = 1;
514a405
> msg->sms.flag_8bit = 1;
574,603d464
< case 53: /* delivery notification */
< st_code = atoi(octstr_get_cstr(emimsg->fields[E50_DST]));
< switch(st_code)
< {
< case 0: /* delivered */
< msg = dlr_find(octstr_get_cstr(conn->id),
< octstr_get_cstr(emimsg->fields[E50_SCTS]), /* timestamp */
< octstr_get_cstr(emimsg->fields[E50_OADC]), /* destination */
< DLR_SUCCESS);
< break;
< case 1: /* buffered */
< msg = NULL;
< break;
< case 2: /* not delivered */
< msg = dlr_find(octstr_get_cstr(conn->id),
< octstr_get_cstr(emimsg->fields[E50_SCTS]), /* timestamp */
< octstr_get_cstr(emimsg->fields[E50_OADC]), /* destination */
< DLR_FAIL);
< break;
< }
< if(msg != NULL) {
< bb_smscconn_receive(conn, msg);
< }
< reply = emimsg_create_reply(53, emimsg->trn, 1);
< if (emimsg_send(server, reply) < 0) {
< emimsg_destroy(reply);
< return -1;
< }
< emimsg_destroy(reply);
< return 1;
610a472
>
631,636c493
< time_t current_time, check_time, keepalive_time=0;
< int write = 1; /* write=1, read=0, for stop-and-wait flow control */
<
< /* Initialize keepalive time counter */
< if ( privdata->keepalive > 0 )
< keepalive_time = time(NULL);
---
> time_t current_time, check_time;
641,642c498
< while ((write || !privdata->flowcontrol) && privdata->unacked < 100
< && !privdata->shutdown &&
---
> while (privdata->unacked < 100 && !privdata->shutdown &&
657,682d512
<
< if ( privdata->keepalive > 0 )
< keepalive_time = time(NULL);
<
< write = 0;
< }
<
< /* Send keepalive if there's room in the sending window */
< if ((write || !privdata->flowcontrol) && privdata->keepalive > 0
< && time(NULL) > keepalive_time + privdata->keepalive &&
< privdata->unacked < 100 && !privdata->shutdown ) {
< while (privdata->sendtime[nexttrn % 100] != 0)
< nexttrn++; /* pick unused TRN */
< nexttrn %= 100;
< emimsg = make_emi31(privdata, nexttrn);
< privdata->sendtype[nexttrn]= 31;
< privdata->sendtime[nexttrn++] = time(NULL);
< privdata->unacked++;
< if (emimsg_send(server, emimsg) == -1) {
< emimsg_destroy(emimsg);
< return;
< }
< emimsg_destroy(emimsg);
< if (privdata->keepalive)
< keepalive_time = time(NULL);
< write = 0;
711d540
< write = 1;
716,747d544
< {
< /* we got an ack back. We might have to store the */
< /* timestamp for delivery notifications now */
< Octstr *ts, *adc;
< int i;
< Msg *m;
<
< ts = octstr_duplicate(emimsg->fields[2]);
< i = octstr_search_char(ts,':',0);
< if (i>0)
< {
< octstr_delete(ts,0,i+1);
< adc = octstr_duplicate(emimsg->fields[2]);
< octstr_truncate(adc,i);
<
< m = privdata->sendmsg[emimsg->trn];
< if(m == NULL)
< info(0,"uhhh m is NULL, very bad");
< else if(m->sms.dlr_mask)
< {
< dlr_add(octstr_get_cstr(conn->id),
< octstr_get_cstr(ts),
< octstr_get_cstr(adc),
< octstr_get_cstr(m->sms.dlr_keyword),
< octstr_get_cstr(m->sms.dlr_id),
< m->sms.dlr_mask);
< }
< octstr_destroy(ts);
< octstr_destroy(adc);
< }
< else
< octstr_destroy(ts);
750d546
< }
757,758c553
< ;
< /* We don't use the data in the reply */
---
> ; /* We don't use the data in the reply */
765d559
<
781c575
< && privdata->sendtime[i] < current_time - privdata->waitack) {
---
> && privdata->sendtime[i] < current_time - 60) {
785,786c579,580
< warning(0, "smsc_emi2: received neither ACK nor NACK for
message %d "
< "in %d seconds, resending message", i,
privdata->waitack);
---
> warning(0, "smsc_emi2: received neither ACK nor NACK "
> "in 60 seconds, resending message");
789d582
< if (privdata->flowcontrol) write=1;
796c589
< "ACKed within %d seconds", privdata->waitack);
---
> "ACKed within 60 seconds");
808,819c601,604
< if (privdata->flowcontrol && write && list_len(privdata->outgoing_queue))
< ;
< else if (privdata->unacked == 0) {
< if (privdata->keepalive > 0)
< conn_wait(server, privdata->keepalive + 1);
< else
< conn_wait(server, -1);
< } else
< if (privdata->keepalive > 0 && privdata->keepalive < 40)
< conn_wait(server, privdata->keepalive + 1);
< else
< conn_wait(server, 40);
---
> if (privdata->unacked == 0)
> conn_wait(server, -1);
> else
> conn_wait(server, 40);
842,843c627
< if (privdata->rport > 0)
< gwthread_wakeup(privdata->receiver_thread);
---
> gwthread_wakeup(privdata->receiver_thread);
853,854c637
< if (privdata->rport > 0)
< gwthread_join(privdata->receiver_thread);
---
> gwthread_join(privdata->receiver_thread);
1029,1030c812
< if (privdata->rport > 0)
< gwthread_wakeup(privdata->receiver_thread);
---
> gwthread_wakeup(privdata->receiver_thread);
1040,1041c822
< if (privdata->rport > 0)
< gwthread_wakeup(privdata->receiver_thread);
---
> gwthread_wakeup(privdata->receiver_thread);
1062,1063c843
< long portno, our_port, keepalive, flowcontrol, waitack;
< /* has to be long because of cfg_get_integer */
---
> long portno, our_port; /* has to be long because of cfg_get_integer */
1089,1112c869
< if (privdata->username && cfg_get_integer(&keepalive, cfg,
octstr_imm("keepalive")) < 0)
< privdata->keepalive = 0;
< else
< privdata->keepalive = keepalive;
<
< if (cfg_get_integer(&flowcontrol, cfg, octstr_imm("flow-control")) < 0)
< privdata->flowcontrol = 0;
< else
< privdata->flowcontrol = flowcontrol;
< if (privdata->flowcontrol < 0 || privdata->flowcontrol > 1) {
< error(0, "'flow-control' invalid in emi2 configuration.");
< goto error;
< }
<
< if (cfg_get_integer(&waitack, cfg, octstr_imm("wait-ack")) < 0)
< privdata->waitack = 60;
< else
< privdata->waitack = waitack;
< if (privdata->waitack < 30 ) {
< error(0, "'wait-ack' invalid in emi2 configuration.");
< goto error;
< }
<
< if (privdata->port <= 0 || privdata->port > 65535) {
---
> if (privdata->port == 0) {
1116c873
< if (privdata->rport < 0 || privdata->rport > 65535) {
---
> if (privdata->rport == 0) {
1129c886
< if (privdata->rport > 0 && emi2_open_listening_socket(privdata) < 0) {
---
> if (emi2_open_listening_socket(privdata) < 0) {
1148c905
< if ( privdata->rport > 0 && (privdata->receiver_thread =
---
> if ( (privdata->receiver_thread =
1154,1157c911,912
< if (privdata->rport > 0) {
< gwthread_wakeup(privdata->receiver_thread);
< gwthread_join(privdata->receiver_thread);
< }
---
> gwthread_wakeup(privdata->receiver_thread);
> gwthread_join(privdata->receiver_thread);