Index: apps/app_sms.c =================================================================== --- apps/app_sms.c (revision 48463) +++ apps/app_sms.c (working copy) @@ -17,6 +17,13 @@ /*! \file * * \brief SMS application - ETSI ES 201 912 protocol 1 implimentation + * + * \par Development notes + * \note 2006-09-19: ETSI ES 201 912 protocol 2 used in Italy and Spain + * support added by Filippo Grassilli (Hyppo) + * + * Working, but not fully tested, under development + * * \ingroup applications * */ @@ -67,9 +74,10 @@ 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" @@ -77,6 +85,7 @@ "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 (two), default 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"; @@ -144,6 +153,7 @@ unsigned char udhi:1; /* User Data Header required, even if length 0 */ unsigned char rp:1; /* Reply Path */ unsigned int vp; /* validity period in minutes, 0 for not set */ + unsigned char udtxt[SMSLEN]; /* user data (message), PLAIN text */ unsigned short ud[SMSLEN]; /* user data (message), UCS-2 coded */ unsigned char udh[SMSLEN]; /* user data header */ char cli[20]; /* caller ID */ @@ -152,11 +162,14 @@ unsigned char obyte; /* byte being sent */ unsigned int opause; /* silent pause before sending (in sample periods) */ unsigned char obitp; /* bit in byte */ + unsigned char protocol; /* ETSI SMS protocol to use (passed at app call) */ + short oseizure; /* protocol 2: channel seizure bits to send */ + short framenumber; /* protocol 2: frame number (for sending ACK0 or ACK1) */ unsigned char osync; /* sync bits to send */ unsigned char obytep; /* byte in data */ unsigned char obyten; /* bytes in data */ unsigned char omsg[256]; /* data buffer (out) */ - unsigned char imsg[200]; /* data buffer (in) */ + unsigned char imsg[250]; /* data buffer (in) */ signed long long ims0, imc0, ims1, @@ -172,11 +185,11 @@ unsigned char iphasep; /* bit phase (0-79) for 1200 bps */ unsigned char ibitn; /* bit number in byte being received */ unsigned char ibytev; /* byte value being received */ - unsigned char ibytep; /* byte pointer in messafe */ + unsigned char ibytep; /* byte pointer in message */ unsigned char ibytec; /* byte checksum for message */ unsigned char ierr; /* error flag */ unsigned char ibith; /* history of last bits */ - unsigned char ibitt; /* total of 1's in last 3 bites */ + unsigned char ibitt; /* total of 1's in last 3 bytes */ /* more to go here */ } sms_t; @@ -195,7 +208,12 @@ return; } +static char *sms_hexdump (unsigned char buf[], int size); +static void sms_connectionready_proto2 (sms_t * h); static void sms_messagetx (sms_t * h); +void adddata_proto2 (sms_t *h, unsigned char msg, char *data, int size); +void putdummydata_proto2 (sms_t *h); +void smssend(sms_t *h, char *c); /*--- numcpy: copy number, skipping non digits apart from leading + */ static void numcpy (char *d, char *s) @@ -713,6 +731,7 @@ if (!strcmp (line, "ud")) { /* parse message (UTF-8) */ unsigned char o = 0; + memcpy(h->udtxt,p,SMSLEN); while (*p && o < SMSLEN) h->ud[o++] = utf8decode((unsigned char **)&p); h->udl = o; @@ -867,6 +886,8 @@ ast_copy_string (fn2, fn, sizeof (fn2)); snprintf (fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate (h->scts), seq++); snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1); + if (option_verbose > 1) + ast_verbose (VERBOSE_PREFIX_2 "SMS-sms_writefile(%s)\n",fn); o = fopen (fn, "w"); if (o) { if (*h->oa) @@ -952,6 +973,82 @@ return f; } +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; fimsg[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; fimsg[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; iud[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 */ +} + /*--- sms_handleincoming: handle the incoming message */ static unsigned char sms_handleincoming (sms_t * h) { @@ -1023,6 +1120,8 @@ #define NAME_MAX 1024 #endif +int sms_compose(sms_t * h, char more); +int sms_compose_proto2(sms_t * h); /*--- sms_nextoutgoing: find and fill in next message, or send a REL if none waiting */ static void sms_nextoutgoing (sms_t * h) @@ -1032,24 +1131,47 @@ char more = 0; ast_copy_string (fn, spool_dir, sizeof (fn)); mkdir (fn, 0777); /* ensure it exists */ - h->rx = 0; /* outgoing message */ + h->rx = 0; /* outgoing message */ + *h->da=*h->oa=0; /* Zero dests */ snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx"); mkdir (fn, 0777); /* ensure it exists */ + if (option_verbose > 4) + ast_verbose (VERBOSE_PREFIX_4 "SMS-sms_nextoutgoing(SPOOL=%s,QUEUE=%s)\n",fn,h->queue); d = opendir (fn); if (d) { struct dirent *f = readdirqueue (d, h->queue); if (f) { snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", f->d_name); + if (option_verbose > 4) + ast_verbose (VERBOSE_PREFIX_4 "SMS-sms_nextoutgoing(%s)\n",fn); sms_readfile (h, fn); if (readdirqueue (d, h->queue)) more = 1; /* more to send */ } closedir (d); } - if (*h->da || *h->oa) { /* message to send */ - unsigned char p = 2; - h->omsg[0] = 0x91; /* SMS_DATA */ - if (h->smsc) { /* deliver */ + if (*h->da || *h->oa) { /* message to send */ + if (h->protocol==2) + sms_compose_proto2(h); + else + sms_compose(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); +} + +int sms_compose(sms_t * h, char more) +{ + unsigned char p = 2; + h->omsg[0] = 0x91; /* SMS_DATA */ + if (h->smsc) { /* deliver */ h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0); p += packaddress (h->omsg + p, h->oa); h->omsg[p++] = h->pid; @@ -1057,7 +1179,7 @@ packdate (h->omsg + p, h->scts); p += 7; p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud); - } else { /* submit */ + } else { /* submit */ h->omsg[p++] = 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0); if (h->mr < 0) @@ -1079,37 +1201,179 @@ h->omsg[p++] = 255; /* max */ } p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud); - } - h->omsg[1] = p - 2; - sms_messagetx (h); - } else { /* no message */ - h->omsg[0] = 0x94; /* SMS_REL */ - h->omsg[1] = 0; - sms_messagetx (h); } + h->omsg[1] = p - 2; + return(1); } -static void sms_debug (char *dir, unsigned char *msg) +void adddata_proto2 (sms_t *h, unsigned char msg, char *data, int size) { + int x; + 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 */ + while(size>0) { + h->omsg[x++]=*data; + data++; + size--; + } + h->omsg[1]=x-2; /* Frame size */ + h->omsg[2]=x-4; /* Payload length (Lo) */ + h->omsg[3]=0; /* Payload length (Hi) */ +} + +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 */ +} + +int sms_compose_proto2(sms_t * h) +{ + 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 */ + } + return(1); +} + +static void sms_debug (char *dir, short frmnum, unsigned char *msg) +{ char txt[259 * 3 + 1], *p = txt; /* always long enough */ int n = msg[1] + 3, q = 0; - while (q < n && q < 30) { + while (q < n && q < 280) { sprintf (p, " %02X", msg[q++]); p += 3; } 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[%d] %s%s\n", frmnum, dir, txt); } +void smssend(sms_t *h, char *c) +{ +int f, x; + for(f=0; fomsg[f] = x; + } + sms_messagetx (h); +} + static void sms_messagerx(sms_t * h) { - sms_debug ("RX", h->imsg); - /* testing */ + sms_debug ("RX", h->framenumber, h->imsg); switch (h->imsg[0]) { + /* *** PROTOCOL 1 */ + case 0xff: /* 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 0x10: /* Protocol 2: SMS_SUBMIT */ + case 0x11: /* Protocol 2: SMS_DELIVERY */ + { + unsigned char cause = sms_handleincoming_proto2(h); + if (!cause) { /* ACK */ + sms_log (h, 'Y'); + h->omsg[0] = (h->framenumber%2==0)?0x14:0x15; /* SMS_ACKx */ + 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] = 0x00; /* CONFIRM */ + } else { /* ACK with error */ + h->omsg[0] = (h->framenumber%2==0)?0x14:0x15; /* SMS_ACKx */ + 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; /* cause */ + } + sms_messagetx (h); + } + break; + case 0x13: /* Protocol 2: SMS_NAK */ + { + h->omsg[0] = 0x17; /* SMS_REL */ + h->omsg[1] = 0x00; /* msg len */ + sms_messagetx (h); + } + break; + case 0x14: /* Protocol 2: SMS_ACK0 */ + case 0x15: /* Protocol 2: SMS_ACK1 */ + { + if(h->omsg[0] == 0x17) { /* Before we asked disconnection */ + h->hangup = 1; /* hangup */ + } else { + // If we're sending: more to send out? + //if () { + sms_nextoutgoing (h); + //} else { + //h->omsg[0] = 0x17; /* SMS_REL */ + //h->omsg[1] = 0x00; /* msg len */ + //sms_messagetx (h); + //} + } + } + break; + case 0x16: /* Protocol 2: DLL_SMS_INFO-MT */ + { + h->omsg[0] = (h->framenumber%2==0)?0x14:0x15; /* SMS_ACKx */ + 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] = 0x00; /* CONFIRM */ + sms_messagetx (h); + } + break; + case 0x17: /* Protocol 2: SMS_REL (hangup req) */ + { + // if(h->smsc) { + h->omsg[0] = (h->framenumber%2==0)?0x14:0x15; /* SMS_ACKx */ + h->omsg[1] = 0; + sms_messagetx (h); + // } else { + // h->hangup=1; + // } + } + break; + /* *** PROTOCOL 1 */ case 0x91: /* SMS_DATA */ { unsigned char cause = sms_handleincoming (h); @@ -1150,6 +1414,7 @@ sms_nextoutgoing (h); break; default: /* Unknown */ + ast_verbose (VERBOSE_PREFIX_2 "SMS Proto#%d: Unknown message %s\n", h->protocol, sms_hexdump(h->imsg, h->imsg[1])); h->omsg[0] = 0x92; /* SMS_ERROR */ h->omsg[1] = 1; h->omsg[2] = 3; /* unknown message type; */ @@ -1158,13 +1423,27 @@ } } +static void sms_connectionready_proto2(sms_t * h) +{ + h->opause = 400; + h->obytep = 0; + h->obitp = 0; + h->osync = 80; + h->obyten = 0; + h->obyte = 0; + h->oseizure = 300; /* Proto 2: 300bits */ + h->framenumber = 1; /* Proto 2 */ + sms_debug ("TX", h->framenumber, h->omsg); +} + static void sms_messagetx(sms_t * h) { unsigned char c = 0, p; for (p = 0; p < h->omsg[1] + 2; p++) c += h->omsg[p]; h->omsg[h->omsg[1] + 2] = 0 - c; - sms_debug ("TX", h->omsg); + h->framenumber++; /* Proto 2 */ + sms_debug ("TX", h->framenumber, h->omsg); h->obyte = 1; h->opause = 200; if (h->omsg[0] == 0x93) @@ -1173,6 +1452,12 @@ h->obitp = 0; h->osync = 80; h->obyten = h->omsg[1] + 3; + if (h->protocol == 2) { + h->oseizure = 300; /* Proto 2: 300bits */ + h->obyte = 0; /* Seizure starts with 0 */ + } else { + h->oseizure = 0; /* Proto 1: No seizure */ + } } static int sms_generate (struct ast_channel *chan, void *data, int len, int samples) @@ -1218,7 +1503,7 @@ #endif if (h->opause) h->opause--; - else if (h->obyten || h->osync) { /* sending data */ + else if (h->obyten || h->osync || h->oseizure>=0) { /* sending data/sync or seizure for proto 2 */ #ifdef OUTALAW buf[i] = wavea[h->ophase]; #else @@ -1226,11 +1511,15 @@ #endif if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80) h->ophase -= 80; - if ((h->ophasep += 12) >= 80) { /* next bit */ + if ((h->ophasep += 12) >= 80) { /* next bit */ h->ophasep -= 80; - if (h->osync) + if (h->oseizure>=0) { /* sending channel seizure (proto 2) */ + h->oseizure--; + if(h->obyte==0) h->obyte=1; + else h->obyte=0; + } else if (h->osync) { h->osync--; /* sending sync bits */ - else { + } else { /* sending data */ h->obyte >>= 1; h->obitp++; if (h->obitp == 1) @@ -1257,10 +1546,29 @@ return 0; } +static void sms_bitsdebug (char value) +{ + char bits[1024]; + static int nbits=0; + if(value==9) { + if(nbits>0) { + ast_verbose (VERBOSE_PREFIX_3 "DEBUG %ld: BITS RECV(%d): %s\n",time(NULL),nbits,bits); + } + } + if(value>1) { + memset(bits,0,sizeof(bits)); + nbits=0; + return; + } + bits[nbits++]='0'+value; +} + static void sms_process (sms_t * h, int samples, signed short *data) { if (h->obyten || h->osync) return; /* sending */ + // BIT DEBUG + sms_bitsdebug(2); while (samples--) { unsigned long long m0, m1; if (abs (*data) > h->imag) @@ -1303,13 +1611,26 @@ 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 */ + // BIT DEBUG + // sms_bitsdebug(bit); h->iphasep -= 80; - if (h->ibitn++ == 9) { /* end of byte */ + if (h->ibitn++ == 9) { /* end of byte */ if (!bit) /* bad stop bit */ h->ierr = 0xFF; /* unknown error */ else { @@ -1317,13 +1638,17 @@ 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_verbose (VERBOSE_PREFIX_1 "DEBUG ERROR1: %d %s\n", h->ibytep, sms_hexdump(h->imsg,h->ibytep)); + ast_verbose (VERBOSE_PREFIX_3 "SMS: bad message length %d\n",h->ibytep); h->ierr = 2; /* bad message length */ + } if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) { - if (!h->ibytec) + if (!h->ibytec) { sms_messagerx (h); - else + } else { h->ierr = 1; /* bad checksum */ + } } } h->ibitn = 0; @@ -1340,6 +1665,7 @@ } if (h->ierr) { /* error */ h->err = 1; + /* WARN! Protocol 1 */ h->omsg[0] = 0x92; /* error */ h->omsg[1] = 1; h->omsg[2] = h->ierr; @@ -1349,6 +1675,16 @@ } data++; } + // BIT DEBUG + sms_bitsdebug(9); + if(h->idle>50000) { + if (option_verbose > 3) + ast_verbose (VERBOSE_PREFIX_4 "DBG_IDLE: sms_process(%d) h->idle=%d h->ibitc=%d h->iphasep=%d\n",__LINE__,h->idle,h->ibitc,h->iphasep); + h->idle=0; + h->omsg[0] = 0x16; /* error */ + h->omsg[1] = 0; + // sms_messagetx (h); /* send error */ + } } static struct ast_generator smsgen = { @@ -1366,8 +1702,10 @@ LOCAL_USER_ADD(u); - h.ipc0 = h.ipc1 = 20; /* phase for cosine */ - h.dcs = 0xF1; /* default */ + h.ipc0 = h.ipc1 = 20; /* phase for cosine */ + h.dcs = 0xF1; /* default */ + h.protocol = 1; /* SMS protocol 1 */ + h.framenumber = -1; if (!data) { ast_log (LOG_ERROR, "Requires queue name at least\n"); LOCAL_USER_REMOVE(u); @@ -1407,6 +1745,9 @@ 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; @@ -1464,9 +1805,15 @@ if (answer) { /* set up SMS_EST initial message */ - h.omsg[0] = 0x93; - h.omsg[1] = 0; - sms_messagetx (&h); + if (option_verbose > 2) + ast_verbose (VERBOSE_PREFIX_3 "SMS answer protocol %d\n", h.protocol); + if (h.protocol == 2) { + sms_connectionready_proto2 (&h); + } else { + h.omsg[0] = 0x93; + h.omsg[1] = 0; + sms_messagetx (&h); + } } }