aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_sms.c
diff options
context:
space:
mode:
authorrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-21 16:50:26 +0000
committerrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-12-21 16:50:26 +0000
commit2ea5003b5b3739a6b54dcd5a42c12c767309adea (patch)
tree5dd2d236cac3ff819ae229528f0adfa4c96ac2d8 /apps/app_sms.c
parent8a8ca18633fa892fb2c3aedc6935191987367933 (diff)
Add a bit of documentation on this code, including pointers
to relevant documents and comment on timing issues. Initial merge of the code in http://bugs.digium.com/view.php?id=8586 by Filippo Grassilli (Hyppo) to support the SMS Protocol 2. In this commit i have tried to minimize the diffs, so further code cleanup will come in subsequent commits. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@48736 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_sms.c')
-rw-r--r--apps/app_sms.c412
1 files changed, 376 insertions, 36 deletions
diff --git a/apps/app_sms.c b/apps/app_sms.c
index 0fb796109..c6cb93473 100644
--- a/apps/app_sms.c
+++ b/apps/app_sms.c
@@ -16,10 +16,24 @@
/*! \file
*
- * \brief SMS application - ETSI ES 201 912 protocol 1 implimentation
+ * \brief SMS application - ETSI ES 201 912 protocol 1 implementation
+ *
+ * \par Development notes
+ * \note The ETSI standards are available free of charge from ETSI at
+ * http://pda.etsi.org/pda/queryform.asp
+ * Among the relevant documents here we have:
+ *
+ * ES 201 912 SMS for PSTN/ISDN
+ * TS 123 040 Technical realization of SMS
+ *
+ * \note 2006-09-19: ETSI ES 201 912 protocol 2 used in Italy and Spain
+ * support added by Filippo Grassilli (Hyppo)
+ * <http://hyppo.com> (Hyppo)
+ * Not fully tested, under development
+ *
* \ingroup applications
*
- * \author Adrian Kennard
+ * \author Adrian Kennard (for the original protocol 1 code)
*/
#include "asterisk.h"
@@ -65,9 +79,10 @@ static char *app = "SMS";
static char *synopsis = "Communicates with SMS service centres and SMS capable analogue phones";
static char *descrip =
- " SMS(name|[a][s]): SMS handles exchange of SMS data with a call to/from SMS capabale\n"
+ " SMS(name|[a][s][t]): SMS handles exchange of SMS data with a call to/from SMS capable\n"
"phone or SMS PSTN service center. Can send and/or receive SMS messages.\n"
"Works to ETSI ES 201 912 compatible with BT SMS PSTN service in UK\n"
+ "and Telecom Italia in Italy.\n"
"Typical usage is to use to handle called from the SMS service centre CLI,\n"
"or to set up a call using 'outgoing' or manager interface to connect\n"
"service centre to SMS()\n"
@@ -75,9 +90,13 @@ static char *descrip =
"Arguments:\n"
" a: answer, i.e. send initial FSK packet.\n"
" s: act as service centre talking to a phone.\n"
+ " t: use protocol 2 (default used is protocol 1).\n"
"Messages are processed as per text file message queues.\n"
"smsq (a separate software) is a command to generate message\n"
- "queues and send messages.\n";
+ "queues and send messages.\n"
+ "NOTE: the protocol has tight delay bounds. Please use short frames\n"
+ "and disable/keep short the jitter buffer on the ATA to make sure that\n"
+ "respones (ACK etc.) are received in time.\n";
/*
* 80 samples of a single period of the wave. At 8000 Hz, it means these
@@ -105,6 +124,43 @@ static const output_t *wave_out = wave; /* outgoing samples */
#define __OUT_FMT AST_FORMAT_SLINEAR
#endif
+#define OSYNC_BITS 80 /* initial sync bits */
+
+/*!
+ * The SMS spec ETSI ES 201 912 defines two protocols with different message types.
+ * Also note that the high bit is used to indicate whether the message
+ * is complete or not, but in two opposite ways:
+ * for Protocol 1, 0x80 means that the message is complete;
+ * for Protocol 2, 0x00 means that the message is complete;
+ */
+enum message_types {
+ DLL_SMS_MASK = 0x7f, /* mask for the valid bits */
+
+ /* Protocol 1 values */
+ DLL1_SMS_DATA = 0x11, /* data packet */
+ DLL1_SMS_ERROR = 0x12,
+ DLL1_SMS_EST = 0x13, /* start the connection */
+ DLL1_SMS_REL = 0x14, /* end the connection */
+ DLL1_SMS_ACK = 0x15,
+ DLL1_SMS_NACK = 0x16,
+
+ DLL1_SMS_COMPLETE = 0x80, /* packet is complete */
+ DLL1_SMS_MORE = 0x00, /* more data to follow */
+
+ /* Protocol 2 values */
+ DLL2_SMS_EST = 0x7f, /* magic number. No message body */
+ DLL2_SMS_INFO_MO = 0x10,
+ DLL2_SMS_INFO_MT = 0x11,
+ DLL2_SMS_INFO_STA = 0x12,
+ DLL2_SMS_NACK = 0x13,
+ DLL2_SMS_ACK0 = 0x14, /* ack even-numbered frame */
+ DLL2_SMS_ACK1 = 0x15, /* ack odd-numbered frame */
+ DLL2_SMS_ENQ = 0x16,
+ DLL2_SMS_REL = 0x17, /* end the connection */
+
+ DLL2_SMS_COMPLETE = 0x00, /* packet is complete */
+ DLL2_SMS_MORE = 0x80, /* more data to follow */
+};
/* SMS 7 bit character mapping to UCS-2 */
static const unsigned short defaultalphabet[] = {
@@ -186,6 +242,11 @@ typedef struct sms_s
unsigned char ibith; /*!< history of last bits */
unsigned char ibitt; /*!< total of 1's in last 3 bytes */
/* more to go here */
+
+ int protocol; /*!< ETSI SMS protocol to use (passed at app call) */
+ int oseizure; /*!< protocol 2: channel seizure bits to send */
+ int framenumber; /*!< protocol 2: frame number (for sending ACK0 or ACK1) */
+ unsigned char udtxt[SMSLEN]; /*!< user data (message), PLAIN text */
} sms_t;
/* different types of encoding */
@@ -716,6 +777,7 @@ static void sms_readfile (sms_t * h, char *fn)
*p++ = 0;
if (!strcmp (line, "ud")) { /* parse message (UTF-8) */
unsigned char o = 0;
+ memcpy(h->udtxt,p,SMSLEN); /* for protocol 2 */
while (*p && o < SMSLEN)
h->ud[o++] = utf8decode(pp);
h->udl = o;
@@ -1007,6 +1069,216 @@ static unsigned char sms_handleincoming (sms_t * h)
#define NAME_MAX 1024
#endif
+/*!
+ * Add data to a protocol 2 message.
+ * Use the length field (h->omsg[1]) as a pointer to the next free position.
+ */
+static void adddata_proto2 (sms_t *h, unsigned char msg, char *data, int size)
+{
+ int x = h->omsg[1]+2; /* Get current position */
+ if (x==2)
+ x += 2; /* First: skip Payload length (set later) */
+ h->omsg[x++] = msg; /* Message code */
+ h->omsg[x++]=(unsigned char)size; /* Data size Low */
+ h->omsg[x++]=0; /* Data size Hi */
+ for (; size>0 ; size--)
+ h->omsg[x++] = *data++;
+ h->omsg[1] = x-2; /* Frame size */
+ h->omsg[2] = x-4; /* Payload length (Lo) */
+ h->omsg[3] = 0; /* Payload length (Hi) */
+}
+
+static void putdummydata_proto2 (sms_t *h)
+{
+ adddata_proto2 (h, 0x10, "\0", 1); /* Media Identifier > SMS */
+ adddata_proto2 (h, 0x11, "\0\0\0\0\0\0", 6); /* Firmware version */
+ adddata_proto2 (h, 0x12, "\2\0\4", 3); /* SMS provider ID */
+ adddata_proto2 (h, 0x13, h->udtxt, h->udl); /* Body */
+}
+
+static void sms_compose2(sms_t *h, int more)
+{
+ struct tm *tm;
+ char stm[9];
+
+ h->omsg[0] = 0x00; /* set later... */
+ h->omsg[1] = 0;
+ putdummydata_proto2 (h);
+ if (h->smsc) { /* deliver */
+ h->omsg[0] = 0x11; /* SMS_DELIVERY */
+ // Required: 10 11 12 13 14 15 17 (seems they must be ordered!)
+ tm=localtime(&h->scts);
+ sprintf (stm, "%02d%02d%02d%02d", tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min); // Date mmddHHMM
+ adddata_proto2 (h, 0x14, stm, 8); /* Date */
+ if(*h->oa==0)
+ strcpy(h->oa,"00000000");
+ adddata_proto2 (h, 0x15, h->oa, strlen(h->oa)); /* Originator */
+ adddata_proto2 (h, 0x17, "\1", 1); /* Calling Terminal ID */
+ } else { /* submit */
+ h->omsg[0] = 0x10; /* SMS_SUBMIT */
+ // Required: 10 11 12 13 17 18 1B 1C (seems they must be ordered!)
+ adddata_proto2 (h, 0x17, "\1", 1); /* Calling Terminal ID */
+ if(*h->da==0)
+ strcpy(h->da,"00000000");
+ adddata_proto2 (h, 0x18, h->da, strlen(h->da)); /* Originator */
+ adddata_proto2 (h, 0x1B, "\1", 1); /* Called Terminal ID */
+ adddata_proto2 (h, 0x1C, "\0\0\0", 3); /* Notification */
+ }
+}
+
+static void putdummydata_proto2 (sms_t *h);
+
+#if 1 /* XXX debugging */
+static char *sms_hexdump (unsigned char buf[], int size)
+{
+ static char *s=NULL;
+ char *p;
+ int f;
+
+ s=(char *)realloc(s,(size*3)+1);
+ for(p=s,f=0; f<size && f<800/3; f++,p+=3)
+ sprintf(p,"%02X ",(unsigned char)buf[f]);
+ return(s);
+}
+#endif
+
+/*! \brief sms_handleincoming_proto2: handle the incoming message */
+static int sms_handleincoming_proto2 (sms_t * h)
+{
+ int f, i, sz=0;
+ int msg, msgsz;
+ struct tm *tm;
+
+ sz = h->imsg[1]+2;
+ /* ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Frame: %s\n", sms_hexdump(h->imsg,sz)); */
+
+ /* Parse message body (called payload) */
+ h->scts = time (0);
+ for(f=4; f<sz; ) {
+ msg=h->imsg[f++];
+ msgsz=h->imsg[f++];
+ msgsz+=(h->imsg[f++]*256);
+ switch(msg) {
+ case 0x13: /* Body */
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Body#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
+ if (msgsz >= sizeof(h->imsg))
+ msgsz = sizeof(h->imsg)-1;
+ for (i=0; i<msgsz; i++)
+ h->ud[i]=h->imsg[f+i];
+ h->udl = msgsz;
+ break;
+ case 0x14: /* Date SCTS */
+ h->scts = time (0);
+ tm = localtime (&h->scts);
+ tm->tm_mon = ( (h->imsg[f]*10) + h->imsg[f+1] ) - 1;
+ tm->tm_mday = ( (h->imsg[f+2]*10) + h->imsg[f+3] );
+ tm->tm_hour = ( (h->imsg[f+4]*10) + h->imsg[f+5] );
+ tm->tm_min = ( (h->imsg[f+6]*10) + h->imsg[f+7] );
+ tm->tm_sec = 0;
+ h->scts = mktime (tm);
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Date#%02X=%02d/%02d %02d:%02d\n", msg, tm->tm_mday, tm->tm_mon+1, tm->tm_hour, tm->tm_min);
+ break;
+ case 0x15: /* Calling line (from SMSC) */
+ if (msgsz>=20)
+ msgsz=20-1;
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Origin#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
+ ast_copy_string (h->oa, &h->imsg[f], msgsz+1);
+ break;
+ case 0x18: /* Destination (from TE/phone) */
+ if (msgsz>=20)
+ msgsz=20-1;
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Destination#%02X=[%.*s]\n",msg,msgsz,&h->imsg[f]);
+ ast_copy_string (h->da, &h->imsg[f], msgsz+1);
+ break;
+ case 0x1C: /* Notify */
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Notify#%02X=%s\n",msg,sms_hexdump(&h->imsg[f],3));
+ break;
+ default:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS-P2 Par#%02X [%d]: %s\n",msg,msgsz,sms_hexdump(&h->imsg[f],msgsz));
+ break;
+ }
+ f+=msgsz; /* Skip to next */
+ }
+ h->rx = 1; /* received message */
+ sms_writefile (h); /* write the file */
+ return 0; /* no error */
+}
+
+#if 0
+static void smssend(sms_t *h, char *c)
+{
+ int f, x;
+ for(f=0; f<strlen(c); f++) {
+ sscanf(&c[f*3],"%x",&x);
+ h->omsg[f] = x;
+ }
+ sms_messagetx (h);
+}
+#endif
+
+static void sms_nextoutgoing (sms_t *h);
+
+static void sms_messagerx2(sms_t * h)
+{
+ int p = h->imsg[0] & DLL_SMS_MASK ; /* mask the high bit */
+ int cause;
+
+#define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
+ switch (p) {
+ case DLL2_SMS_EST: /* Protocol 2: Connection ready (fake): send message */
+ sms_nextoutgoing (h);
+ //smssend(h,"11 29 27 00 10 01 00 00 11 06 00 00 00 00 00 00 00 12 03 00 02 00 04 13 01 00 41 14 08 00 30 39 31 35 30 02 30 02 15 02 00 39 30 ");
+ break;
+
+ case DLL2_SMS_INFO_MO: /* transport SMS_SUBMIT */
+ case DLL2_SMS_INFO_MT: /* transport SMS_DELIVERY */
+ cause = sms_handleincoming_proto2(h);
+ if (!cause) /* ACK */
+ sms_log (h, 'Y');
+ h->omsg[0] = DLL2_ACK(h);
+ h->omsg[1] = 0x06; /* msg len */
+ h->omsg[2] = 0x04; /* payload len */
+ h->omsg[3] = 0x00; /* payload len */
+ h->omsg[4] = 0x1f; /* Response type */
+ h->omsg[5] = 0x01; /* parameter len */
+ h->omsg[6] = 0x00; /* parameter len */
+ h->omsg[7] = cause; /* CONFIRM or error */
+ sms_messagetx (h);
+ break;
+
+ case DLL2_SMS_NACK: /* Protocol 2: SMS_NAK */
+ h->omsg[0] = DLL2_SMS_REL; /* SMS_REL */
+ h->omsg[1] = 0x00; /* msg len */
+ sms_messagetx (h);
+ break;
+
+ case DLL2_SMS_ACK0:
+ case DLL2_SMS_ACK1:
+ /* SMS_ACK also transport SMS_SUBMIT or SMS_DELIVERY */
+ if( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
+ /* a response to our Release, just hangup */
+ h->hangup = 1; /* hangup */
+ } else {
+ /* XXX depending on what we are.. */
+ ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY");
+ sms_nextoutgoing (h);
+ }
+ break;
+
+ case DLL2_SMS_REL: /* Protocol 2: SMS_REL (hangup req) */
+ h->omsg[0] = DLL2_ACK(h);
+ h->omsg[1] = 0;
+ sms_messagetx (h);
+ break;
+ }
+}
+
/*! \brief compose a message for protocol 1 */
static void sms_compose1(sms_t *h, int more)
{
@@ -1072,20 +1344,31 @@ static void sms_nextoutgoing (sms_t * h)
closedir (d);
}
if (*h->da || *h->oa) { /* message to send */
- sms_compose1(h, more);
- } else { /* no message */
- h->omsg[0] = 0x94; /* SMS_REL */
- h->omsg[1] = 0;
+ if (h->protocol==2)
+ sms_compose2(h, more);
+ else
+ sms_compose1(h,more);
+ } else { /* no message */
+ if (h->protocol==2) {
+ h->omsg[0] = 0x17; /* SMS_REL */
+ h->omsg[1] = 0;
+ } else {
+ h->omsg[0] = 0x94; /* SMS_REL */
+ h->omsg[1] = 0;
+ }
}
sms_messagetx (h);
}
-static void sms_debug (char *dir, unsigned char *msg)
+#define DIR_RX 1
+#define DIR_TX 2
+static void sms_debug (int dir, sms_t *h)
{
- char txt[259 * 3 + 1],
- *p = txt; /* always long enough */
- int n = msg[1] + 3,
- q = 0;
+ char txt[259 * 3 + 1];
+ char *p = txt; /* always long enough */
+ unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
+ int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
+ int q = 0;
while (q < n && q < 30) {
sprintf (p, " %02X", msg[q++]);
p += 3;
@@ -1093,17 +1376,23 @@ static void sms_debug (char *dir, unsigned char *msg)
if (q < n)
sprintf (p, "...");
if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir, txt);
+ ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
}
+
static void sms_messagerx(sms_t * h)
{
- sms_debug ("RX", h->imsg);
- /* testing */
- switch (h->imsg[0]) { /* PROTOCOL version 1 */
+ int cause;
+
+ sms_debug (DIR_RX, h);
+ if (h->protocol == 2) {
+ sms_messagerx2(h);
+ return;
+ }
+ /* parse incoming message for Protocol 1 */
+ switch (h->imsg[0]) {
case 0x91: /* SMS_DATA */
- {
- unsigned char cause = sms_handleincoming (h);
+ cause = sms_handleincoming (h);
if (!cause) {
sms_log (h, 'Y');
h->omsg[0] = 0x95; /* SMS_ACK */
@@ -1119,8 +1408,8 @@ static void sms_messagerx(sms_t * h)
h->omsg[4] = 0; /* no parameters */
}
sms_messagetx (h);
- }
- break;
+ break;
+
case 0x92: /* SMS_ERROR */
h->err = 1;
sms_messagetx (h); /* send whatever we sent again */
@@ -1157,15 +1446,27 @@ static void sms_messagetx(sms_t * h)
for (p = 0; p < len; p++) /* compute checksum */
c += h->omsg[p];
h->omsg[len] = 0 - c; /* actually, (256 - (c & 0fxx)) & 0xff) */
- sms_debug ("TX", h->omsg);
- h->obyte = 1;
+ sms_debug(DIR_TX, h);
+ h->framenumber++; /* Proto 2 */
+ h->obyte = 1; /* send mark ('1') at the beginning */
h->opause = 200;
+ /* Change the initial message delay. BT requires 300ms,
+ * but for others this might be way too much and the phone
+ * could time out. XXX make it configurable.
+ */
if (h->omsg[0] == 0x93)
- h->opause = 2400; /* initial message delay 300ms (for BT) */
+ h->opause = 200; /* XXX initial message delay 300ms (for BT) */
h->obytep = 0;
h->obitp = 0;
+ if (h->protocol == 2) {
+ h->oseizure = 300; /* Proto 2: 300bits (or more ?) */
+ h->obyte = 0; /* Seizure starts with space (0) */
+ h->opause = 400;
+ } else {
+ h->oseizure = 0; /* Proto 1: No seizure */
+ }
/* Note - setting osync triggers the generator */
- h->osync = 80; /* 80 sync bits */
+ h->osync = OSYNC_BITS; /* 80 sync bits */
h->obyten = len + 1; /* bytes to send (including checksum) */
}
@@ -1199,15 +1500,22 @@ static int sms_generate (struct ast_channel *chan, void *data, int len, int samp
if (h->opause)
h->opause--;
- else if (h->obyten || h->osync) { /* sending data */
+ else if (h->obyten || h->osync) { /* sending data */
buf[i] = wave_out[h->ophase];
h->ophase += (h->obyte & 1) ? 13 : 21; /* compute next phase */
if (h->ophase >= 80)
h->ophase -= 80;
if ((h->ophasep += 12) >= 80) { /* time to send the next bit */
h->ophasep -= 80;
- if (h->osync) {
+ if (h->oseizure > 0) { /* sending channel seizure (proto 2) */
+ h->oseizure--;
+ h->obyte ^= 1; /* toggle low bit */
+ } else if (h->osync) {
+ h->obyte = 1; /* send mark as sync bit */
h->osync--; /* sending sync bits */
+ if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
+ h->obytep = h->obyten = 0; /* we are done */
+ }
} else {
h->obitp++;
if (h->obitp == 1)
@@ -1250,8 +1558,13 @@ static int sms_generate (struct ast_channel *chan, void *data, int len, int samp
*/
static void sms_process (sms_t * h, int samples, signed short *data)
{
+#if 1
+ /* Do we really need to remain deaf while a packet is
+ * being transmitted ?
+ */
if (h->obyten || h->osync)
return; /* sending */
+#endif
while (samples--) {
unsigned long long m0, m1;
if (abs (*data) > h->imag)
@@ -1301,27 +1614,43 @@ static void sms_process (sms_t * h, int samples, signed short *data)
h->iphasep = 0;
}
if (bit && h->ibitc == 200) { /* sync, restart message */
+ /* Protocol 2: empty connnection ready (I am master) */
+ if(h->framenumber<0 && h->ibytec>=160 && !memcmp(h->imsg,"UUUUUUUUUUUUUUUUUUUU",20)) {
+ h->framenumber = 1;
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "SMS protocol 2 detected\n");
+ h->protocol = 2;
+ h->imsg[0] = 0xff; /* special message (fake) */
+ h->imsg[1] = h->imsg[2] = 0x00;
+ h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
+ sms_messagerx (h);
+ }
h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
}
if (h->ibitn) {
h->iphasep += 12;
- if (h->iphasep >= 80) { /* next bit */
+ if (h->iphasep >= 80) { /* next bit */
h->iphasep -= 80;
- if (h->ibitn++ == 9) { /* end of byte */
- if (!bit) /* bad stop bit */
+ if (h->ibitn++ == 9) { /* end of byte */
+ if (!bit) { /* bad stop bit */
+ ast_log(LOG_NOTICE, "bad stop bit");
h->ierr = 0xFF; /* unknown error */
- else {
+ } else {
if (h->ibytep < sizeof (h->imsg)) {
h->imsg[h->ibytep] = h->ibytev;
h->ibytec += h->ibytev;
h->ibytep++;
- } else if (h->ibytep == sizeof (h->imsg))
+ } else if (h->ibytep == sizeof (h->imsg)) {
+ ast_log(LOG_NOTICE, "msg too large");
h->ierr = 2; /* bad message length */
+ }
if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
if (!h->ibytec)
sms_messagerx (h);
- else
+ else {
+ ast_log(LOG_NOTICE, "bad checksum");
h->ierr = 1; /* bad checksum */
+ }
}
}
h->ibitn = 0;
@@ -1332,11 +1661,12 @@ static void sms_process (sms_t * h, int samples, signed short *data)
}
} else { /* lost carrier */
if (h->idle++ == 80000) { /* nothing happening */
- ast_log (LOG_EVENT, "No data, hanging up\n");
+ ast_log (LOG_NOTICE, "No data, hanging up\n");
h->hangup = 1;
h->err = 1;
}
if (h->ierr) { /* error */
+ ast_log (LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
/* Protocol 1 */
h->err = 1;
h->omsg[0] = 0x92; /* error */
@@ -1398,6 +1728,7 @@ static int sms_exec (struct ast_channel *chan, void *data)
for (p = (unsigned char *)h.queue; *p; p++)
if (!isalnum (*p))
*p = '-'; /* make very safe for filenames */
+ast_log(LOG_NOTICE, "sms to queue %s\n", h.queue);
while (*d && *d != '|') {
switch (*d) {
case 'a': /* we have to send the initial FSK sequence */
@@ -1406,6 +1737,9 @@ static int sms_exec (struct ast_channel *chan, void *data)
case 's': /* we are acting as a service centre talking to a phone */
h.smsc = 1;
break;
+ case 't': /* use protocol 2 ([t]wo)! couldn't use numbers *!* */
+ h.protocol = 2;
+ break;
/* the following apply if there is an arg3/4 and apply to the created message file */
case 'r':
h.srr = 1;
@@ -1462,9 +1796,15 @@ static int sms_exec (struct ast_channel *chan, void *data)
}
if (answer) {
+ h.framenumber = 1; /* Proto 2 */
/* set up SMS_EST initial message */
- h.omsg[0] = 0x93;
- h.omsg[1] = 0;
+ if (h.protocol == 2) {
+ h.omsg[0] = DLL2_SMS_EST;
+ h.omsg[1] = 0;
+ } else {
+ h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
+ h.omsg[1] = 0;
+ }
sms_messagetx (&h);
}
}