00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "asterisk.h"
00042
00043 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 370642 $")
00044
00045 #include <dirent.h>
00046 #include <ctype.h>
00047 #include <sys/stat.h>
00048
00049 #include "asterisk/paths.h"
00050 #include "asterisk/lock.h"
00051 #include "asterisk/file.h"
00052 #include "asterisk/channel.h"
00053 #include "asterisk/pbx.h"
00054 #include "asterisk/module.h"
00055 #include "asterisk/alaw.h"
00056 #include "asterisk/callerid.h"
00057 #include "asterisk/utils.h"
00058 #include "asterisk/app.h"
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 static volatile unsigned char message_ref;
00118 static volatile unsigned int seq;
00119
00120 static char log_file[255];
00121
00122 static char *app = "SMS";
00123
00124
00125
00126
00127
00128
00129
00130 static const signed short wave[] = {
00131 0, 392, 782, 1167, 1545, 1913, 2270, 2612, 2939, 3247, 3536, 3802, 4045, 4263, 4455, 4619, 4755, 4862, 4938, 4985,
00132 5000, 4985, 4938, 4862, 4755, 4619, 4455, 4263, 4045, 3802, 3536, 3247, 2939, 2612, 2270, 1913, 1545, 1167, 782, 392,
00133 0, -392, -782, -1167,
00134 -1545, -1913, -2270, -2612, -2939, -3247, -3536, -3802, -4045, -4263, -4455, -4619, -4755, -4862, -4938, -4985, -5000,
00135 -4985, -4938, -4862,
00136 -4755, -4619, -4455, -4263, -4045, -3802, -3536, -3247, -2939, -2612, -2270, -1913, -1545, -1167, -782, -392
00137 };
00138
00139 #ifdef OUTALAW
00140 static unsigned char wavea[80];
00141 typedef unsigned char output_t;
00142 static const output_t *wave_out = wavea;
00143 #define __OUT_FMT AST_FORMAT_ALAW;
00144 #else
00145 typedef signed short output_t;
00146 static const output_t *wave_out = wave;
00147 #define __OUT_FMT AST_FORMAT_SLINEAR
00148 #endif
00149
00150 #define OSYNC_BITS 80
00151
00152
00153
00154
00155
00156
00157
00158
00159 enum message_types {
00160 DLL_SMS_MASK = 0x7f,
00161
00162
00163 DLL1_SMS_DATA = 0x11,
00164 DLL1_SMS_ERROR = 0x12,
00165 DLL1_SMS_EST = 0x13,
00166 DLL1_SMS_REL = 0x14,
00167 DLL1_SMS_ACK = 0x15,
00168 DLL1_SMS_NACK = 0x16,
00169
00170 DLL1_SMS_COMPLETE = 0x80,
00171 DLL1_SMS_MORE = 0x00,
00172
00173
00174 DLL2_SMS_EST = 0x7f,
00175 DLL2_SMS_INFO_MO = 0x10,
00176 DLL2_SMS_INFO_MT = 0x11,
00177 DLL2_SMS_INFO_STA = 0x12,
00178 DLL2_SMS_NACK = 0x13,
00179 DLL2_SMS_ACK0 = 0x14,
00180 DLL2_SMS_ACK1 = 0x15,
00181 DLL2_SMS_ENQ = 0x16,
00182 DLL2_SMS_REL = 0x17,
00183
00184 DLL2_SMS_COMPLETE = 0x00,
00185 DLL2_SMS_MORE = 0x80,
00186 };
00187
00188
00189 static const unsigned short defaultalphabet[] = {
00190 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC,
00191 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5,
00192 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8,
00193 0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9,
00194 ' ', '!', '"', '#', 164, '%', '&', 39, '(', ')', '*', '+', ',', '-', '.', '/',
00195 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
00196 161, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
00197 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
00198 191, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
00199 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 228, 246, 241, 252, 224,
00200 };
00201
00202 static const unsigned short escapes[] = {
00203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000C, 0, 0, 0, 0, 0,
00204 0, 0, 0, 0, 0x005E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00205 0, 0, 0, 0, 0, 0, 0, 0, 0x007B, 0x007D, 0, 0, 0, 0, 0, 0x005C,
00206 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x005B, 0x007E, 0x005D, 0,
00207 0x007C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00209 0, 0, 0, 0, 0, 0x20AC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00211 };
00212
00213 #define SMSLEN 160
00214 #define SMSLEN_8 140
00215
00216 typedef struct sms_s {
00217 unsigned char hangup;
00218 unsigned char err;
00219 unsigned char smsc:1;
00220 unsigned char rx:1;
00221 char queue[30];
00222 char oa[20];
00223 char da[20];
00224 struct timeval scts;
00225 unsigned char pid;
00226 unsigned char dcs;
00227 short mr;
00228 int udl;
00229 int udhl;
00230 unsigned char srr:1;
00231 unsigned char udhi:1;
00232 unsigned char rp:1;
00233 unsigned int vp;
00234 unsigned short ud[SMSLEN];
00235 unsigned char udh[SMSLEN];
00236 char cli[20];
00237 unsigned char ophase;
00238 unsigned char ophasep;
00239 unsigned char obyte;
00240 unsigned int opause;
00241 unsigned char obitp;
00242 unsigned char osync;
00243 unsigned char obytep;
00244 unsigned char obyten;
00245 unsigned char omsg[256];
00246 unsigned char imsg[250];
00247 signed long long ims0,
00248 imc0,
00249 ims1,
00250 imc1;
00251 unsigned int idle;
00252 unsigned short imag;
00253 unsigned char ips0;
00254 unsigned char ips1;
00255 unsigned char ipc0;
00256 unsigned char ipc1;
00257 unsigned char ibitl;
00258 unsigned char ibitc;
00259 unsigned char iphasep;
00260 unsigned char ibitn;
00261 unsigned char ibytev;
00262 unsigned char ibytep;
00263 unsigned char ibytec;
00264 unsigned char ierr;
00265 unsigned char ibith;
00266 unsigned char ibitt;
00267
00268
00269 int opause_0;
00270 int protocol;
00271 int oseizure;
00272 int framenumber;
00273 char udtxt[SMSLEN];
00274 } sms_t;
00275
00276
00277 #define is7bit(dcs) ( ((dcs) & 0xC0) ? (!((dcs) & 4) ) : (((dcs) & 0xc) == 0) )
00278 #define is8bit(dcs) ( ((dcs) & 0xC0) ? ( ((dcs) & 4) ) : (((dcs) & 0xc) == 4) )
00279 #define is16bit(dcs) ( ((dcs) & 0xC0) ? 0 : (((dcs) & 0xc) == 8) )
00280
00281 static void sms_messagetx(sms_t *h);
00282
00283
00284 static void numcpy(char *d, char *s)
00285 {
00286 if (*s == '+') {
00287 *d++ = *s++;
00288 }
00289 while (*s) {
00290 if (isdigit(*s)) {
00291 *d++ = *s;
00292 }
00293 s++;
00294 }
00295 *d = 0;
00296 }
00297
00298
00299 static char *isodate(time_t t, char *buf, int len)
00300 {
00301 struct ast_tm tm;
00302 struct timeval local = { t, 0 };
00303 ast_localtime(&local, &tm, NULL);
00304 ast_strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
00305 return buf;
00306 }
00307
00308
00309
00310
00311 static long utf8decode(unsigned char **pp)
00312 {
00313 unsigned char *p = *pp;
00314 if (!*p) {
00315 return 0;
00316 }
00317 (*pp)++;
00318 if (*p < 0xC0) {
00319 return *p;
00320 }
00321 if (*p < 0xE0) {
00322 if (*p < 0xC2 || (p[1] & 0xC0) != 0x80) {
00323 return *p;
00324 }
00325 (*pp)++;
00326 return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
00327 }
00328 if (*p < 0xF0) {
00329 if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80) {
00330 return *p;
00331 }
00332 (*pp) += 2;
00333 return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
00334 }
00335 if (*p < 0xF8) {
00336 if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80) {
00337 return *p;
00338 }
00339 (*pp) += 3;
00340 return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
00341 }
00342 if (*p < 0xFC) {
00343 if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
00344 || (p[4] & 0xC0) != 0x80) {
00345 return *p;
00346 }
00347 (*pp) += 4;
00348 return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
00349 }
00350 if (*p < 0xFE) {
00351 if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
00352 || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80) {
00353 return *p;
00354 }
00355 (*pp) += 5;
00356 return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F);
00357 }
00358 return *p;
00359 }
00360
00361
00362
00363
00364
00365 static int packsms7(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00366 {
00367 unsigned char p = 0;
00368 unsigned char b = 0;
00369 unsigned char n = 0;
00370 unsigned char dummy[SMSLEN];
00371
00372 if (o == NULL) {
00373 o = dummy;
00374 }
00375
00376 if (udhl) {
00377 o[p++] = udhl;
00378 b = 1;
00379 n = 1;
00380 while (udhl--) {
00381 o[p++] = *udh++;
00382 b += 8;
00383 while (b >= 7) {
00384 b -= 7;
00385 n++;
00386 }
00387 if (n >= SMSLEN)
00388 return n;
00389 }
00390 if (b) {
00391 b = 7 - b;
00392 if (++n >= SMSLEN)
00393 return n;
00394 }
00395 }
00396 o[p] = 0;
00397
00398 while (udl--) {
00399 long u;
00400 unsigned char v;
00401 u = *ud++;
00402
00403
00404 for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
00405 if (v == 128 && u && n + 1 < SMSLEN) {
00406
00407 for (v = 0; v < 128 && escapes[v] != u; v++);
00408 if (v < 128) {
00409
00410 o[p] |= (27 << b);
00411 b += 7;
00412 if (b >= 8) {
00413 b -= 8;
00414 p++;
00415 o[p] = (27 >> (7 - b));
00416 }
00417 n++;
00418 }
00419 }
00420 if (v == 128)
00421 return -1;
00422
00423 o[p] |= (v << b);
00424 b += 7;
00425 if (b >= 8) {
00426 b -= 8;
00427 p++;
00428 o[p] = (v >> (7 - b));
00429 }
00430 if (++n >= SMSLEN)
00431 return n;
00432 }
00433 return n;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442 static int packsms8(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00443 {
00444 unsigned char p = 0;
00445 unsigned char dummy[SMSLEN_8];
00446
00447 if (o == NULL)
00448 o = dummy;
00449
00450 if (udhl) {
00451 o[p++] = udhl;
00452 while (udhl--) {
00453 o[p++] = *udh++;
00454 if (p >= SMSLEN_8) {
00455 return p;
00456 }
00457 }
00458 }
00459 while (udl--) {
00460 long u;
00461 u = *ud++;
00462 if (u < 0 || u > 0xFF) {
00463 return -1;
00464 }
00465 o[p++] = u;
00466 if (p >= SMSLEN_8) {
00467 return p;
00468 }
00469 }
00470 return p;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 static int packsms16(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00482 {
00483 unsigned char p = 0;
00484 unsigned char dummy[SMSLEN_8];
00485
00486 if (o == NULL) {
00487 o = dummy;
00488 }
00489
00490 if (udhl) {
00491 o[p++] = udhl;
00492 while (udhl--) {
00493 o[p++] = *udh++;
00494 if (p >= SMSLEN_8) {
00495 return p;
00496 }
00497 }
00498 }
00499 while (udl--) {
00500 long u;
00501 u = *ud++;
00502 o[p++] = (u >> 8);
00503 if (p >= SMSLEN_8) {
00504 return p - 1;
00505 }
00506 o[p++] = u;
00507 if (p >= SMSLEN_8) {
00508 return p;
00509 }
00510 }
00511 return p;
00512 }
00513
00514
00515
00516 static int packsms(unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
00517 {
00518 unsigned char *p = base;
00519 if (udl == 0) {
00520 *p++ = 0;
00521 } else {
00522
00523 int l = 0;
00524 if (is7bit(dcs)) {
00525 if ((l = packsms7(p + 1, udhl, udh, udl, ud)) < 0) {
00526 l = 0;
00527 }
00528 *p++ = l;
00529 p += (l * 7 + 7) / 8;
00530 } else if (is8bit(dcs)) {
00531 if ((l = packsms8(p + 1, udhl, udh, udl, ud)) < 0) {
00532 l = 0;
00533 }
00534 *p++ = l;
00535 p += l;
00536 } else {
00537 if ((l = packsms16(p + 1, udhl, udh, udl, ud)) < 0) {
00538 l = 0;
00539 }
00540 *p++ = l;
00541 p += l;
00542 }
00543 }
00544 return p - base;
00545 }
00546
00547
00548
00549 static void packdate(unsigned char *o, time_t w)
00550 {
00551 struct ast_tm t;
00552 struct timeval topack = { w, 0 };
00553 int z;
00554
00555 ast_localtime(&topack, &t, NULL);
00556 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
00557 z = -t.tm_gmtoff / 60 / 15;
00558 #else
00559 z = timezone / 60 / 15;
00560 #endif
00561 *o++ = ((t.tm_year % 10) << 4) + (t.tm_year % 100) / 10;
00562 *o++ = (((t.tm_mon + 1) % 10) << 4) + (t.tm_mon + 1) / 10;
00563 *o++ = ((t.tm_mday % 10) << 4) + t.tm_mday / 10;
00564 *o++ = ((t.tm_hour % 10) << 4) + t.tm_hour / 10;
00565 *o++ = ((t.tm_min % 10) << 4) + t.tm_min / 10;
00566 *o++ = ((t.tm_sec % 10) << 4) + t.tm_sec / 10;
00567 if (z < 0) {
00568 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
00569 } else {
00570 *o++ = ((z % 10) << 4) + z / 10;
00571 }
00572 }
00573
00574
00575 static struct timeval unpackdate(unsigned char *i)
00576 {
00577 struct ast_tm t;
00578
00579 t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
00580 t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
00581 t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
00582 t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
00583 t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
00584 t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
00585 t.tm_isdst = 0;
00586 if (i[6] & 0x08) {
00587 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
00588 } else {
00589 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
00590 }
00591
00592 return ast_mktime(&t, NULL);
00593 }
00594
00595
00596
00597
00598 static void unpacksms7(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00599 {
00600 unsigned char b = 0, p = 0;
00601 unsigned short *o = ud;
00602 *udhl = 0;
00603 if (udhi && l) {
00604 int h = i[p];
00605 *udhl = h;
00606 if (h) {
00607 b = 1;
00608 p++;
00609 l--;
00610 while (h-- && l) {
00611 *udh++ = i[p++];
00612 b += 8;
00613 while (b >= 7) {
00614 b -= 7;
00615 l--;
00616 if (!l) {
00617 break;
00618 }
00619 }
00620 }
00621
00622 if (b) {
00623 b = 7 - b;
00624 l--;
00625 }
00626 }
00627 }
00628 while (l--) {
00629 unsigned char v;
00630 if (b < 2) {
00631 v = ((i[p] >> b) & 0x7F);
00632 } else {
00633 v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
00634 }
00635 b += 7;
00636 if (b >= 8) {
00637 b -= 8;
00638 p++;
00639 }
00640
00641 if (o > ud && o[-1] == 0x00A0 && escapes[v]) {
00642 o[-1] = escapes[v];
00643 } else {
00644 *o++ = defaultalphabet[v];
00645 }
00646 }
00647 *udl = (o - ud);
00648 }
00649
00650
00651
00652
00653
00654 static void unpacksms8(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00655 {
00656 unsigned short *o = ud;
00657 *udhl = 0;
00658 if (udhi) {
00659 int n = *i;
00660 *udhl = n;
00661 if (n) {
00662 i++;
00663 l--;
00664 while (l && n) {
00665 l--;
00666 n--;
00667 *udh++ = *i++;
00668 }
00669 }
00670 }
00671 while (l--) {
00672 *o++ = *i++;
00673 }
00674 *udl = (o - ud);
00675 }
00676
00677
00678
00679
00680 static void unpacksms16(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00681 {
00682 unsigned short *o = ud;
00683 *udhl = 0;
00684 if (udhi) {
00685 int n = *i;
00686 *udhl = n;
00687 if (n) {
00688 i++;
00689 l--;
00690 while (l && n) {
00691 l--;
00692 n--;
00693 *udh++ = *i++;
00694 }
00695 }
00696 }
00697 while (l--) {
00698 int v = *i++;
00699 if (l--) {
00700 v = (v << 8) + *i++;
00701 }
00702 *o++ = v;
00703 }
00704 *udl = (o - ud);
00705 }
00706
00707
00708 static int unpacksms(unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00709 {
00710 int l = *i++;
00711 if (is7bit(dcs)) {
00712 unpacksms7(i, l, udh, udhl, ud, udl, udhi);
00713 l = (l * 7 + 7) / 8;
00714 } else if (is8bit(dcs)) {
00715 unpacksms8(i, l, udh, udhl, ud, udl, udhi);
00716 } else {
00717 unpacksms16(i, l, udh, udhl, ud, udl, udhi);
00718 }
00719 return l + 1;
00720 }
00721
00722
00723 static unsigned char unpackaddress(char *o, unsigned char *i)
00724 {
00725 unsigned char l = i[0], p;
00726 if (i[1] == 0x91) {
00727 *o++ = '+';
00728 }
00729 for (p = 0; p < l; p++) {
00730 if (p & 1) {
00731 *o++ = (i[2 + p / 2] >> 4) + '0';
00732 } else {
00733 *o++ = (i[2 + p / 2] & 0xF) + '0';
00734 }
00735 }
00736 *o = 0;
00737 return (l + 5) / 2;
00738 }
00739
00740
00741 static unsigned char packaddress(unsigned char *o, char *i)
00742 {
00743 unsigned char p = 2;
00744 o[0] = 0;
00745 if (*i == '+') {
00746 i++;
00747 o[1] = 0x91;
00748 } else {
00749 o[1] = 0x81;
00750 }
00751 for ( ; *i ; i++) {
00752 if (!isdigit(*i)) {
00753 continue;
00754 }
00755 if (o[0] & 1) {
00756 o[p++] |= ((*i & 0xF) << 4);
00757 } else {
00758 o[p] = (*i & 0xF);
00759 }
00760 o[0]++;
00761 }
00762 if (o[0] & 1) {
00763 o[p++] |= 0xF0;
00764 }
00765 return p;
00766 }
00767
00768
00769 static void sms_log(sms_t * h, char status)
00770 {
00771 int o;
00772
00773 if (*h->oa == '\0' && *h->da == '\0') {
00774 return;
00775 }
00776 o = open(log_file, O_CREAT | O_APPEND | O_WRONLY, AST_FILE_MODE);
00777 if (o >= 0) {
00778 char line[1000], mrs[3] = "", *p;
00779 char buf[30];
00780 unsigned char n;
00781
00782 if (h->mr >= 0) {
00783 snprintf(mrs, sizeof(mrs), "%02X", h->mr);
00784 }
00785 snprintf(line, sizeof(line), "%s %c%c%c%s %s %s %s ",
00786 isodate(time(NULL), buf, sizeof(buf)),
00787 status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue,
00788 S_OR(h->oa, "-"), S_OR(h->da, "-") );
00789 p = line + strlen(line);
00790 for (n = 0; n < h->udl; n++) {
00791 if (h->ud[n] == '\\') {
00792 *p++ = '\\';
00793 *p++ = '\\';
00794 } else if (h->ud[n] == '\n') {
00795 *p++ = '\\';
00796 *p++ = 'n';
00797 } else if (h->ud[n] == '\r') {
00798 *p++ = '\\';
00799 *p++ = 'r';
00800 } else if (h->ud[n] < 32 || h->ud[n] == 127) {
00801 *p++ = 191;
00802 } else {
00803 *p++ = h->ud[n];
00804 }
00805 }
00806 *p++ = '\n';
00807 *p = 0;
00808 if (write(o, line, strlen(line)) < 0) {
00809 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
00810 }
00811 close(o);
00812 }
00813 *h->oa = *h->da = h->udl = 0;
00814 }
00815
00816
00817 static void sms_readfile(sms_t * h, char *fn)
00818 {
00819 char line[1000];
00820 FILE *s;
00821 char dcsset = 0;
00822 ast_log(LOG_NOTICE, "Sending %s\n", fn);
00823 h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
00824 h->mr = -1;
00825 h->dcs = 0xF1;
00826 h->scts = ast_tvnow();
00827 s = fopen(fn, "r");
00828 if (s) {
00829 if (unlink(fn)) {
00830 fclose(s);
00831 return;
00832 }
00833 while (fgets (line, sizeof(line), s)) {
00834 char *p;
00835 void *pp = &p;
00836 for (p = line; *p && *p != '\n' && *p != '\r'; p++);
00837 *p = 0;
00838 p = line;
00839 if (!*p || *p == ';') {
00840 continue;
00841 }
00842 while (isalnum(*p)) {
00843 *p = tolower (*p);
00844 p++;
00845 }
00846 while (isspace (*p)) {
00847 *p++ = 0;
00848 }
00849 if (*p == '=') {
00850 *p++ = 0;
00851 if (!strcmp(line, "ud")) {
00852 unsigned char o = 0;
00853 memcpy(h->udtxt, p, SMSLEN);
00854 while (*p && o < SMSLEN) {
00855 h->ud[o++] = utf8decode(pp);
00856 }
00857 h->udl = o;
00858 if (*p) {
00859 ast_log(LOG_WARNING, "UD too long in %s\n", fn);
00860 }
00861 } else {
00862 while (isspace (*p)) {
00863 p++;
00864 }
00865 if (!strcmp(line, "oa") && strlen(p) < sizeof(h->oa)) {
00866 numcpy (h->oa, p);
00867 } else if (!strcmp(line, "da") && strlen(p) < sizeof(h->oa)) {
00868 numcpy (h->da, p);
00869 } else if (!strcmp(line, "pid")) {
00870 h->pid = atoi(p);
00871 } else if (!strcmp(line, "dcs")) {
00872 h->dcs = atoi(p);
00873 dcsset = 1;
00874 } else if (!strcmp(line, "mr")) {
00875 h->mr = atoi(p);
00876 } else if (!strcmp(line, "srr")) {
00877 h->srr = (atoi(p) ? 1 : 0);
00878 } else if (!strcmp(line, "vp")) {
00879 h->vp = atoi(p);
00880 } else if (!strcmp(line, "rp")) {
00881 h->rp = (atoi(p) ? 1 : 0);
00882 } else if (!strcmp(line, "scts")) {
00883 int Y, m, d, H, M, S;
00884
00885 if (sscanf(p, "%4d-%2d-%2dT%2d:%2d:%2d", &Y, &m, &d, &H, &M, &S) == 6) {
00886 struct ast_tm t = { 0, };
00887 t.tm_year = Y - 1900;
00888 t.tm_mon = m - 1;
00889 t.tm_mday = d;
00890 t.tm_hour = H;
00891 t.tm_min = M;
00892 t.tm_sec = S;
00893 t.tm_isdst = -1;
00894 h->scts = ast_mktime(&t, NULL);
00895 if (h->scts.tv_sec == 0) {
00896 ast_log(LOG_WARNING, "Bad date/timein %s: %s", fn, p);
00897 }
00898 }
00899 } else {
00900 ast_log(LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
00901 }
00902 }
00903 } else if (*p == '#') {
00904 *p++ = 0;
00905 if (*p == '#') {
00906 p++;
00907 if (!strcmp(line, "ud")) {
00908 int o = 0;
00909 while (*p && o < SMSLEN) {
00910 if (isxdigit(*p) && isxdigit(p[1]) && isxdigit(p[2]) && isxdigit(p[3])) {
00911 h->ud[o++] =
00912 (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 12) +
00913 (((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
00914 (((isalpha(p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha(p[3]) ? 9 : 0) + (p[3] & 0xF));
00915 p += 4;
00916 } else
00917 break;
00918 }
00919 h->udl = o;
00920 if (*p)
00921 ast_log(LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
00922 } else
00923 ast_log(LOG_WARNING, "Only ud can use ## format, %s\n", fn);
00924 } else if (!strcmp(line, "ud")) {
00925 int o = 0;
00926 while (*p && o < SMSLEN) {
00927 if (isxdigit(*p) && isxdigit(p[1])) {
00928 h->ud[o++] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
00929 p += 2;
00930 } else {
00931 break;
00932 }
00933 }
00934 h->udl = o;
00935 if (*p) {
00936 ast_log(LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
00937 }
00938 } else if (!strcmp(line, "udh")) {
00939 unsigned char o = 0;
00940 h->udhi = 1;
00941 while (*p && o < SMSLEN) {
00942 if (isxdigit(*p) && isxdigit(p[1])) {
00943 h->udh[o] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
00944 o++;
00945 p += 2;
00946 } else {
00947 break;
00948 }
00949 }
00950 h->udhl = o;
00951 if (*p) {
00952 ast_log(LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
00953 }
00954 } else {
00955 ast_log(LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
00956 }
00957 } else {
00958 ast_log(LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
00959 }
00960 }
00961 fclose(s);
00962 if (!dcsset && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00963 if (packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00964 if (packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00965 ast_log(LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
00966 } else {
00967 h->dcs = 0x08;
00968 ast_log(LOG_WARNING, "Sending in 16 bit format(%s)\n", fn);
00969 }
00970 } else {
00971 h->dcs = 0xF5;
00972 ast_log(LOG_WARNING, "Sending in 8 bit format(%s)\n", fn);
00973 }
00974 }
00975 if (is7bit(h->dcs) && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00976 ast_log(LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
00977 }
00978 if (is8bit(h->dcs) && packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00979 ast_log(LOG_WARNING, "Invalid 8 bit data %s\n", fn);
00980 }
00981 if (is16bit(h->dcs) && packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00982 ast_log(LOG_WARNING, "Invalid 16 bit data %s\n", fn);
00983 }
00984 }
00985 }
00986
00987
00988 static void sms_writefile(sms_t * h)
00989 {
00990 char fn[200] = "", fn2[200] = "";
00991 char buf[30];
00992 FILE *o;
00993
00994 if (ast_tvzero(h->scts)) {
00995 h->scts = ast_tvnow();
00996 }
00997 snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
00998 ast_mkdir(fn, 0777);
00999 ast_copy_string(fn2, fn, sizeof(fn2));
01000 snprintf(fn2 + strlen(fn2), sizeof(fn2) - strlen(fn2), "/%s.%s-%d", h->queue, isodate(h->scts.tv_sec, buf, sizeof(buf)), seq++);
01001 snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/.%s", fn2 + strlen(fn) + 1);
01002 if ((o = fopen(fn, "w")) == NULL) {
01003 return;
01004 }
01005
01006 if (*h->oa) {
01007 fprintf(o, "oa=%s\n", h->oa);
01008 }
01009 if (*h->da) {
01010 fprintf(o, "da=%s\n", h->da);
01011 }
01012 if (h->udhi) {
01013 unsigned int p;
01014 fprintf(o, "udh#");
01015 for (p = 0; p < h->udhl; p++) {
01016 fprintf(o, "%02X", h->udh[p]);
01017 }
01018 fprintf(o, "\n");
01019 }
01020 if (h->udl) {
01021 unsigned int p;
01022 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
01023 if (p < h->udl) {
01024 fputc(';', o);
01025 }
01026 fprintf(o, "ud=");
01027 for (p = 0; p < h->udl; p++) {
01028 unsigned short v = h->ud[p];
01029 if (v < 32) {
01030 fputc(191, o);
01031 } else if (v < 0x80) {
01032 fputc(v, o);
01033 } else if (v < 0x800) {
01034 fputc(0xC0 + (v >> 6), o);
01035 fputc(0x80 + (v & 0x3F), o);
01036 } else {
01037 fputc(0xE0 + (v >> 12), o);
01038 fputc(0x80 + ((v >> 6) & 0x3F), o);
01039 fputc(0x80 + (v & 0x3F), o);
01040 }
01041 }
01042 fprintf(o, "\n");
01043 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
01044 if (p < h->udl) {
01045 for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
01046 if (p == h->udl) {
01047 fprintf(o, "ud#");
01048 for (p = 0; p < h->udl; p++) {
01049 fprintf(o, "%02X", h->ud[p]);
01050 }
01051 fprintf(o, "\n");
01052 } else {
01053 fprintf(o, "ud##");
01054 for (p = 0; p < h->udl; p++) {
01055 fprintf(o, "%04X", h->ud[p]);
01056 }
01057 fprintf(o, "\n");
01058 }
01059 }
01060 }
01061 if (h->scts.tv_sec) {
01062 char datebuf[30];
01063 fprintf(o, "scts=%s\n", isodate(h->scts.tv_sec, datebuf, sizeof(datebuf)));
01064 }
01065 if (h->pid) {
01066 fprintf(o, "pid=%d\n", h->pid);
01067 }
01068 if (h->dcs != 0xF1) {
01069 fprintf(o, "dcs=%d\n", h->dcs);
01070 }
01071 if (h->vp) {
01072 fprintf(o, "vp=%d\n", h->vp);
01073 }
01074 if (h->srr) {
01075 fprintf(o, "srr=1\n");
01076 }
01077 if (h->mr >= 0) {
01078 fprintf(o, "mr=%d\n", h->mr);
01079 }
01080 if (h->rp) {
01081 fprintf(o, "rp=1\n");
01082 }
01083 fclose(o);
01084 if (rename(fn, fn2)) {
01085 unlink(fn);
01086 } else {
01087 ast_log(LOG_NOTICE, "Received to %s\n", fn2);
01088 }
01089 }
01090
01091
01092 static struct dirent *readdirqueue(DIR *d, char *queue)
01093 {
01094 struct dirent *f;
01095 do {
01096 f = readdir(d);
01097 } while (f && (*f->d_name == '.' || strncmp(f->d_name, queue, strlen(queue)) || f->d_name[strlen(queue)] != '.'));
01098 return f;
01099 }
01100
01101
01102 static unsigned char sms_handleincoming (sms_t * h)
01103 {
01104 unsigned char p = 3;
01105 if (h->smsc) {
01106 if ((h->imsg[2] & 3) == 1) {
01107 h->udhl = h->udl = 0;
01108 h->vp = 0;
01109 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
01110 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
01111 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
01112 ast_copy_string(h->oa, h->cli, sizeof(h->oa));
01113 h->scts = ast_tvnow();
01114 h->mr = h->imsg[p++];
01115 p += unpackaddress(h->da, h->imsg + p);
01116 h->pid = h->imsg[p++];
01117 h->dcs = h->imsg[p++];
01118 if ((h->imsg[2] & 0x18) == 0x10) {
01119 if (h->imsg[p] < 144) {
01120 h->vp = (h->imsg[p] + 1) * 5;
01121 } else if (h->imsg[p] < 168) {
01122 h->vp = 720 + (h->imsg[p] - 143) * 30;
01123 } else if (h->imsg[p] < 197) {
01124 h->vp = (h->imsg[p] - 166) * 1440;
01125 } else {
01126 h->vp = (h->imsg[p] - 192) * 10080;
01127 }
01128 p++;
01129 } else if (h->imsg[2] & 0x18) {
01130 p += 7;
01131 }
01132 p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
01133 h->rx = 1;
01134 sms_writefile(h);
01135 if (p != h->imsg[1] + 2) {
01136 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
01137 return 0xFF;
01138 }
01139 } else {
01140 ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
01141 return 0xFF;
01142 }
01143 } else {
01144 if (!(h->imsg[2] & 3)) {
01145 *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
01146 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
01147 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
01148 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
01149 h->mr = -1;
01150 p += unpackaddress(h->oa, h->imsg + p);
01151 h->pid = h->imsg[p++];
01152 h->dcs = h->imsg[p++];
01153 h->scts = unpackdate(h->imsg + p);
01154 p += 7;
01155 p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
01156 h->rx = 1;
01157 sms_writefile(h);
01158 if (p != h->imsg[1] + 2) {
01159 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
01160 return 0xFF;
01161 }
01162 } else {
01163 ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
01164 return 0xFF;
01165 }
01166 }
01167 return 0;
01168 }
01169
01170 #ifdef SOLARIS
01171 #define NAME_MAX 1024
01172 #endif
01173
01174
01175
01176
01177
01178 static void adddata_proto2(sms_t *h, unsigned char msg, char *data, int size)
01179 {
01180 int x = h->omsg[1] + 2;
01181 if (x == 2) {
01182 x += 2;
01183 }
01184 h->omsg[x++] = msg;
01185 h->omsg[x++] = (unsigned char)size;
01186 h->omsg[x++] = 0;
01187 for (; size > 0 ; size--) {
01188 h->omsg[x++] = *data++;
01189 }
01190 h->omsg[1] = x - 2;
01191 h->omsg[2] = x - 4;
01192 h->omsg[3] = 0;
01193 }
01194
01195 static void putdummydata_proto2(sms_t *h)
01196 {
01197 adddata_proto2(h, 0x10, "\0", 1);
01198 adddata_proto2(h, 0x11, "\0\0\0\0\0\0", 6);
01199 adddata_proto2(h, 0x12, "\2\0\4", 3);
01200 adddata_proto2(h, 0x13, h->udtxt, h->udl);
01201 }
01202
01203 static void sms_compose2(sms_t *h, int more)
01204 {
01205 struct ast_tm tm;
01206 struct timeval now = h->scts;
01207 char stm[9];
01208
01209 h->omsg[0] = 0x00;
01210 h->omsg[1] = 0;
01211 putdummydata_proto2(h);
01212 if (h->smsc) {
01213 h->omsg[0] = 0x11;
01214
01215 ast_localtime(&now, &tm, NULL);
01216 sprintf(stm, "%02d%02d%02d%02d", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min);
01217 adddata_proto2(h, 0x14, stm, 8);
01218 if (*h->oa == 0) {
01219 strcpy(h->oa, "00000000");
01220 }
01221 adddata_proto2(h, 0x15, h->oa, strlen(h->oa));
01222 adddata_proto2(h, 0x17, "\1", 1);
01223 } else {
01224 h->omsg[0] = 0x10;
01225
01226 adddata_proto2(h, 0x17, "\1", 1);
01227 if (*h->da == 0) {
01228 strcpy(h->da, "00000000");
01229 }
01230 adddata_proto2(h, 0x18, h->da, strlen(h->da));
01231 adddata_proto2(h, 0x1B, "\1", 1);
01232 adddata_proto2(h, 0x1C, "\0\0\0", 3);
01233 }
01234 }
01235
01236 static void putdummydata_proto2(sms_t *h);
01237
01238 #define MAX_DEBUG_LEN 300
01239 static char *sms_hexdump(unsigned char buf[], int size, char *s )
01240 {
01241 char *p;
01242 int f;
01243
01244 for (p = s, f = 0; f < size && f < MAX_DEBUG_LEN; f++, p += 3) {
01245 sprintf(p, "%02X ", (unsigned char)buf[f]);
01246 }
01247 return(s);
01248 }
01249
01250
01251
01252 static int sms_handleincoming_proto2(sms_t *h)
01253 {
01254 int f, i, sz = 0;
01255 int msg, msgsz;
01256 struct ast_tm tm;
01257 struct timeval now = { 0, 0 };
01258 char debug_buf[MAX_DEBUG_LEN * 3 + 1];
01259
01260 sz = h->imsg[1] + 2;
01261
01262
01263
01264 now = h->scts = ast_tvnow();
01265 for (f = 4; f < sz; ) {
01266 msg = h->imsg[f++];
01267 msgsz = h->imsg[f++];
01268 msgsz += (h->imsg[f++] * 256);
01269 switch (msg) {
01270 case 0x13:
01271 ast_verb(3, "SMS-P2 Body#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01272 if (msgsz >= sizeof(h->ud)) {
01273 msgsz = sizeof(h->ud) - 1;
01274 }
01275 for (i = 0; i < msgsz; i++) {
01276 h->ud[i] = h->imsg[f + i];
01277 }
01278 h->udl = msgsz;
01279 break;
01280 case 0x14:
01281 now = h->scts = ast_tvnow();
01282 ast_localtime(&now, &tm, NULL);
01283 tm.tm_mon = ( (h->imsg[f] * 10) + h->imsg[f + 1] ) - 1;
01284 tm.tm_mday = ( (h->imsg[f + 2] * 10) + h->imsg[f + 3] );
01285 tm.tm_hour = ( (h->imsg[f + 4] * 10) + h->imsg[f + 5] );
01286 tm.tm_min = ( (h->imsg[f + 6] * 10) + h->imsg[f + 7] );
01287 tm.tm_sec = 0;
01288 h->scts = ast_mktime(&tm, NULL);
01289 ast_verb(3, "SMS-P2 Date#%02X=%02d/%02d %02d:%02d\n", msg, tm.tm_mday, tm.tm_mon + 1, tm.tm_hour, tm.tm_min);
01290 break;
01291 case 0x15:
01292 if (msgsz >= 20) {
01293 msgsz = 20 - 1;
01294 }
01295 ast_verb(3, "SMS-P2 Origin#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01296 ast_copy_string(h->oa, (char *)(&h->imsg[f]), msgsz + 1);
01297 break;
01298 case 0x18:
01299 if (msgsz >= 20) {
01300 msgsz = 20 - 1;
01301 }
01302 ast_verb(3, "SMS-P2 Destination#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01303 ast_copy_string(h->da, (char *)(&h->imsg[f]), msgsz + 1);
01304 break;
01305 case 0x1C:
01306 ast_verb(3, "SMS-P2 Notify#%02X=%s\n", msg, sms_hexdump(&h->imsg[f], 3, debug_buf));
01307 break;
01308 default:
01309 ast_verb(3, "SMS-P2 Par#%02X [%d]: %s\n", msg, msgsz, sms_hexdump(&h->imsg[f], msgsz, debug_buf));
01310 break;
01311 }
01312 f+=msgsz;
01313 }
01314 h->rx = 1;
01315 sms_writefile(h);
01316 return 0;
01317 }
01318
01319 #if 0
01320 static void smssend(sms_t *h, char *c)
01321 {
01322 int f, x;
01323 for (f = 0; f < strlen(c); f++) {
01324 sscanf(&c[f*3], "%x", &x);
01325 h->omsg[f] = x;
01326 }
01327 sms_messagetx(h);
01328 }
01329 #endif
01330
01331 static void sms_nextoutgoing (sms_t *h);
01332
01333 static void sms_messagerx2(sms_t * h)
01334 {
01335 int p = h->imsg[0] & DLL_SMS_MASK ;
01336 int cause;
01337
01338 #define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
01339 switch (p) {
01340 case DLL2_SMS_EST:
01341 sms_nextoutgoing (h);
01342
01343 break;
01344
01345 case DLL2_SMS_INFO_MO:
01346 case DLL2_SMS_INFO_MT:
01347 cause = sms_handleincoming_proto2(h);
01348 if (!cause) {
01349 sms_log(h, 'Y');
01350 }
01351 h->omsg[0] = DLL2_ACK(h);
01352 h->omsg[1] = 0x06;
01353 h->omsg[2] = 0x04;
01354 h->omsg[3] = 0x00;
01355 h->omsg[4] = 0x1f;
01356 h->omsg[5] = 0x01;
01357 h->omsg[6] = 0x00;
01358 h->omsg[7] = cause;
01359 sms_messagetx(h);
01360 break;
01361
01362 case DLL2_SMS_NACK:
01363 h->omsg[0] = DLL2_SMS_REL;
01364 h->omsg[1] = 0x00;
01365 sms_messagetx(h);
01366 break;
01367
01368 case DLL2_SMS_ACK0:
01369 case DLL2_SMS_ACK1:
01370
01371 if ( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
01372
01373 h->hangup = 1;
01374 } else {
01375
01376 ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY\n");
01377 sms_nextoutgoing (h);
01378 }
01379 break;
01380
01381 case DLL2_SMS_REL:
01382 h->omsg[0] = DLL2_ACK(h);
01383 h->omsg[1] = 0;
01384 sms_messagetx(h);
01385 break;
01386 }
01387 }
01388
01389
01390 static void sms_compose1(sms_t *h, int more)
01391 {
01392 unsigned int p = 2;
01393
01394 h->omsg[0] = 0x91;
01395 if (h->smsc) {
01396 h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
01397 p += packaddress(h->omsg + p, h->oa);
01398 h->omsg[p++] = h->pid;
01399 h->omsg[p++] = h->dcs;
01400 packdate(h->omsg + p, h->scts.tv_sec);
01401 p += 7;
01402 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
01403 } else {
01404 h->omsg[p++] =
01405 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
01406 if (h->mr < 0) {
01407 h->mr = message_ref++;
01408 }
01409 h->omsg[p++] = h->mr;
01410 p += packaddress(h->omsg + p, h->da);
01411 h->omsg[p++] = h->pid;
01412 h->omsg[p++] = h->dcs;
01413 if (h->vp) {
01414 if (h->vp < 720) {
01415 h->omsg[p++] = (h->vp + 4) / 5 - 1;
01416 } else if (h->vp < 1440) {
01417 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
01418 } else if (h->vp < 43200) {
01419 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
01420 } else if (h->vp < 635040) {
01421 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
01422 } else {
01423 h->omsg[p++] = 255;
01424 }
01425 }
01426 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
01427 }
01428 h->omsg[1] = p - 2;
01429 }
01430
01431
01432 static void sms_nextoutgoing (sms_t * h)
01433 {
01434 char fn[100 + NAME_MAX] = "";
01435 DIR *d;
01436 char more = 0;
01437
01438 *h->da = *h->oa = '\0';
01439 h->rx = 0;
01440 snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? "mttx" : "motx");
01441 ast_mkdir(fn, 0777);
01442 d = opendir(fn);
01443 if (d) {
01444 struct dirent *f = readdirqueue(d, h->queue);
01445 if (f) {
01446 snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/%s", f->d_name);
01447 sms_readfile(h, fn);
01448 if (readdirqueue(d, h->queue)) {
01449 more = 1;
01450 }
01451 }
01452 closedir(d);
01453 }
01454 if (*h->da || *h->oa) {
01455 if (h->protocol == 2) {
01456 sms_compose2(h, more);
01457 } else {
01458 sms_compose1(h, more);
01459 }
01460 } else {
01461 if (h->protocol == 2) {
01462 h->omsg[0] = 0x17;
01463 h->omsg[1] = 0;
01464 } else {
01465 h->omsg[0] = 0x94;
01466 h->omsg[1] = 0;
01467 }
01468 }
01469 sms_messagetx(h);
01470 }
01471
01472 #define DIR_RX 1
01473 #define DIR_TX 2
01474 static void sms_debug (int dir, sms_t *h)
01475 {
01476 char txt[259 * 3 + 1];
01477 char *p = txt;
01478 unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
01479 int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
01480 int q = 0;
01481 while (q < n && q < 30) {
01482 sprintf(p, " %02X", msg[q++]);
01483 p += 3;
01484 }
01485 if (q < n) {
01486 sprintf(p, "...");
01487 }
01488 ast_verb(3, "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
01489 }
01490
01491
01492 static void sms_messagerx(sms_t * h)
01493 {
01494 int cause;
01495
01496 sms_debug (DIR_RX, h);
01497 if (h->protocol == 2) {
01498 sms_messagerx2(h);
01499 return;
01500 }
01501
01502 switch (h->imsg[0]) {
01503 case 0x91:
01504 cause = sms_handleincoming (h);
01505 if (!cause) {
01506 sms_log(h, 'Y');
01507 h->omsg[0] = 0x95;
01508 h->omsg[1] = 0x02;
01509 h->omsg[2] = 0x00;
01510 h->omsg[3] = 0x00;
01511 } else {
01512 sms_log(h, 'N');
01513 h->omsg[0] = 0x96;
01514 h->omsg[1] = 3;
01515 h->omsg[2] = 0;
01516 h->omsg[3] = cause;
01517 h->omsg[4] = 0;
01518 }
01519 sms_messagetx(h);
01520 break;
01521
01522 case 0x92:
01523 h->err = 1;
01524 sms_messagetx(h);
01525 break;
01526 case 0x93:
01527 sms_nextoutgoing (h);
01528 break;
01529 case 0x94:
01530 h->hangup = 1;
01531 break;
01532 case 0x95:
01533 sms_log(h, 'Y');
01534 sms_nextoutgoing (h);
01535 break;
01536 case 0x96:
01537 h->err = 1;
01538 sms_log(h, 'N');
01539 sms_nextoutgoing (h);
01540 break;
01541 default:
01542 h->omsg[0] = 0x92;
01543 h->omsg[1] = 1;
01544 h->omsg[2] = 3;
01545 sms_messagetx(h);
01546 break;
01547 }
01548 }
01549
01550 static void sms_messagetx(sms_t * h)
01551 {
01552 unsigned char c = 0, p;
01553 int len = h->omsg[1] + 2;
01554
01555 for (p = 0; p < len; p++) {
01556 c += h->omsg[p];
01557 }
01558 h->omsg[len] = 0 - c;
01559 sms_debug(DIR_TX, h);
01560 h->framenumber++;
01561 h->obytep = 0;
01562 h->obitp = 0;
01563 if (h->protocol == 2) {
01564 h->oseizure = 300;
01565 h->obyte = 0;
01566 if (h->omsg[0] == 0x7F) {
01567 h->opause = 8 * h->opause_0;
01568 } else {
01569 h->opause = 400;
01570 }
01571 } else {
01572 h->oseizure = 0;
01573 h->obyte = 1;
01574
01575
01576
01577
01578 if (h->omsg[0] == 0x93) {
01579 h->opause = 8 * h->opause_0;
01580 } else {
01581 h->opause = 200;
01582 }
01583 }
01584
01585 h->osync = OSYNC_BITS;
01586 h->obyten = len + 1;
01587 }
01588
01589
01590
01591
01592
01593 static int sms_generate(struct ast_channel *chan, void *data, int len, int samples)
01594 {
01595 struct ast_frame f = { 0 };
01596 #define MAXSAMPLES (800)
01597 output_t *buf;
01598 sms_t *h = data;
01599 int i;
01600
01601 if (samples > MAXSAMPLES) {
01602 ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n",
01603 MAXSAMPLES, samples);
01604 samples = MAXSAMPLES;
01605 }
01606 len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
01607 buf = ast_alloca(len);
01608
01609 f.frametype = AST_FRAME_VOICE;
01610 f.subclass.codec = __OUT_FMT;
01611 f.datalen = samples * sizeof(*buf);
01612 f.offset = AST_FRIENDLY_OFFSET;
01613 f.mallocd = 0;
01614 f.data.ptr = buf;
01615 f.samples = samples;
01616 f.src = "app_sms";
01617
01618 for (i = 0; i < samples; i++) {
01619 buf[i] = wave_out[0];
01620
01621 if (h->opause) {
01622 h->opause--;
01623 } else if (h->obyten || h->osync) {
01624 buf[i] = wave_out[h->ophase];
01625 h->ophase += (h->obyte & 1) ? 13 : 21;
01626 if (h->ophase >= 80)
01627 h->ophase -= 80;
01628 if ((h->ophasep += 12) >= 80) {
01629 h->ophasep -= 80;
01630 if (h->oseizure > 0) {
01631 h->oseizure--;
01632 h->obyte ^= 1;
01633 } else if (h->osync) {
01634 h->obyte = 1;
01635 h->osync--;
01636 if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
01637 h->obytep = h->obyten = 0;
01638 }
01639 } else {
01640 h->obitp++;
01641 if (h->obitp == 1) {
01642 h->obyte = 0;
01643 } else if (h->obitp == 2) {
01644 h->obyte = h->omsg[h->obytep];
01645 } else if (h->obitp == 10) {
01646 h->obyte = 1;
01647 h->obitp = 0;
01648 h->obytep++;
01649 if (h->obytep == h->obyten) {
01650 h->obytep = h->obyten = 0;
01651 h->osync = 10;
01652 }
01653 } else {
01654 h->obyte >>= 1;
01655 }
01656 }
01657 }
01658 }
01659 }
01660 if (ast_write(chan, &f) < 0) {
01661 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
01662 return -1;
01663 }
01664 return 0;
01665 #undef MAXSAMPLES
01666 }
01667
01668
01669
01670
01671 static void *sms_alloc(struct ast_channel *chan, void *sms_t_ptr)
01672 {
01673 return sms_t_ptr;
01674 }
01675
01676 static void sms_release(struct ast_channel *chan, void *data)
01677 {
01678 return;
01679 }
01680
01681 static struct ast_generator smsgen = {
01682 .alloc = sms_alloc,
01683 .release = sms_release,
01684 .generate = sms_generate,
01685 };
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699 static void sms_process(sms_t * h, int samples, signed short *data)
01700 {
01701 int bit;
01702
01703
01704
01705
01706
01707
01708
01709
01710 if (h->obyten || h->osync) {
01711 return;
01712 }
01713 for ( ; samples-- ; data++) {
01714 unsigned long long m0, m1;
01715 if (abs(*data) > h->imag) {
01716 h->imag = abs(*data);
01717 } else {
01718 h->imag = h->imag * 7 / 8;
01719 }
01720 if (h->imag <= 500) {
01721 if (h->idle++ == 80000) {
01722 ast_log(LOG_NOTICE, "No data, hanging up\n");
01723 h->hangup = 1;
01724 h->err = 1;
01725 }
01726 if (h->ierr) {
01727 ast_log(LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
01728
01729 h->err = 1;
01730 h->omsg[0] = 0x92;
01731 h->omsg[1] = 1;
01732 h->omsg[2] = h->ierr;
01733 sms_messagetx(h);
01734 }
01735 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01736 continue;
01737 }
01738 h->idle = 0;
01739
01740
01741 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
01742 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
01743 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
01744 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
01745
01746 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
01747 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
01748
01749
01750 if ((h->ips0 += 21) >= 80) {
01751 h->ips0 -= 80;
01752 }
01753 if ((h->ipc0 += 21) >= 80) {
01754 h->ipc0 -= 80;
01755 }
01756 if ((h->ips1 += 13) >= 80) {
01757 h->ips1 -= 80;
01758 }
01759 if ((h->ipc1 += 13) >= 80) {
01760 h->ipc1 -= 80;
01761 }
01762
01763
01764 h->ibith <<= 1;
01765 if (m1 > m0) {
01766 h->ibith |= 1;
01767 }
01768 if (h->ibith & 8) {
01769 h->ibitt--;
01770 }
01771 if (h->ibith & 1) {
01772 h->ibitt++;
01773 }
01774 bit = ((h->ibitt > 1) ? 1 : 0);
01775 if (bit != h->ibitl) {
01776 h->ibitc = 1;
01777 } else {
01778 h->ibitc++;
01779 }
01780 h->ibitl = bit;
01781 if (!h->ibitn && h->ibitc == 4 && !bit) {
01782 h->ibitn = 1;
01783 h->iphasep = 0;
01784 }
01785 if (bit && h->ibitc == 200) {
01786
01787 if (h->framenumber < 0 && h->ibytec >= 160 && !memcmp(h->imsg, "UUUUUUUUUUUUUUUUUUUU", 20)) {
01788 h->framenumber = 1;
01789 ast_verb(3, "SMS protocol 2 detected\n");
01790 h->protocol = 2;
01791 h->imsg[0] = 0xff;
01792 h->imsg[1] = h->imsg[2] = 0x00;
01793 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01794 sms_messagerx(h);
01795 }
01796 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01797 }
01798 if (h->ibitn) {
01799 h->iphasep += 12;
01800 if (h->iphasep >= 80) {
01801 h->iphasep -= 80;
01802 if (h->ibitn++ == 9) {
01803 if (!bit) {
01804 ast_log(LOG_NOTICE, "bad stop bit\n");
01805 h->ierr = 0xFF;
01806 } else {
01807 if (h->ibytep < sizeof(h->imsg)) {
01808 h->imsg[h->ibytep] = h->ibytev;
01809 h->ibytec += h->ibytev;
01810 h->ibytep++;
01811 } else if (h->ibytep == sizeof(h->imsg)) {
01812 ast_log(LOG_NOTICE, "msg too large\n");
01813 h->ierr = 2;
01814 }
01815 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
01816 if (!h->ibytec) {
01817 sms_messagerx(h);
01818 } else {
01819 ast_log(LOG_NOTICE, "bad checksum\n");
01820 h->ierr = 1;
01821 }
01822 }
01823 }
01824 h->ibitn = 0;
01825 }
01826 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
01827 }
01828 }
01829 }
01830 }
01831
01832
01833
01834
01835
01836
01837
01838
01839 enum sms_flags {
01840 OPTION_BE_SMSC = (1 << 0),
01841 OPTION_ANSWER = (1 << 1),
01842 OPTION_TWO = (1 << 2),
01843 OPTION_PAUSE = (1 << 3),
01844 OPTION_SRR = (1 << 4),
01845 OPTION_DCS = (1 << 5),
01846 };
01847
01848 enum sms_opt_args {
01849 OPTION_ARG_PAUSE = 0,
01850 OPTION_ARG_ARRAY_SIZE
01851 };
01852
01853 AST_APP_OPTIONS(sms_options, {
01854 AST_APP_OPTION('s', OPTION_BE_SMSC),
01855 AST_APP_OPTION('a', OPTION_ANSWER),
01856 AST_APP_OPTION('t', OPTION_TWO),
01857 AST_APP_OPTION('r', OPTION_SRR),
01858 AST_APP_OPTION('o', OPTION_DCS),
01859 AST_APP_OPTION_ARG('p', OPTION_PAUSE, OPTION_ARG_PAUSE),
01860 } );
01861
01862 static int sms_exec(struct ast_channel *chan, const char *data)
01863 {
01864 int res = -1;
01865 sms_t h = { 0 };
01866
01867 struct ast_flags flags;
01868 char *parse, *sms_opts[OPTION_ARG_ARRAY_SIZE] = { 0, };
01869 char *p;
01870 AST_DECLARE_APP_ARGS(sms_args,
01871 AST_APP_ARG(queue);
01872 AST_APP_ARG(options);
01873 AST_APP_ARG(addr);
01874 AST_APP_ARG(body);
01875 );
01876
01877 if (!data) {
01878 ast_log(LOG_ERROR, "Requires queue name at least\n");
01879 return -1;
01880 }
01881
01882 parse = ast_strdupa(data);
01883 AST_STANDARD_APP_ARGS(sms_args, parse);
01884 if (sms_args.argc > 1) {
01885 ast_app_parse_options(sms_options, &flags, sms_opts, sms_args.options);
01886 }
01887
01888 ast_verb(1, "sms argc %d queue <%s> opts <%s> addr <%s> body <%s>\n",
01889 sms_args.argc, S_OR(sms_args.queue, ""),
01890 S_OR(sms_args.options, ""),
01891 S_OR(sms_args.addr, ""),
01892 S_OR(sms_args.body, "") );
01893
01894 h.ipc0 = h.ipc1 = 20;
01895 h.dcs = 0xF1;
01896
01897 ast_copy_string(h.cli,
01898 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
01899 sizeof(h.cli));
01900
01901 if (ast_strlen_zero(sms_args.queue)) {
01902 ast_log(LOG_ERROR, "Requires queue name\n");
01903 goto done;
01904 }
01905 if (strlen(sms_args.queue) >= sizeof(h.queue)) {
01906 ast_log(LOG_ERROR, "Queue name too long\n");
01907 goto done;
01908 }
01909 ast_copy_string(h.queue, sms_args.queue, sizeof(h.queue));
01910
01911 for (p = h.queue; *p; p++) {
01912 if (!isalnum(*p)) {
01913 *p = '-';
01914 }
01915 }
01916
01917 h.smsc = ast_test_flag(&flags, OPTION_BE_SMSC);
01918 h.protocol = ast_test_flag(&flags, OPTION_TWO) ? 2 : 1;
01919 if (!ast_strlen_zero(sms_opts[OPTION_ARG_PAUSE])) {
01920 h.opause_0 = atoi(sms_opts[OPTION_ARG_PAUSE]);
01921 }
01922 if (h.opause_0 < 25 || h.opause_0 > 2000) {
01923 h.opause_0 = 300;
01924 }
01925 ast_verb(1, "initial delay %dms\n", h.opause_0);
01926
01927
01928
01929 if (ast_test_flag(&flags, OPTION_SRR)) {
01930 h.srr = 1;
01931 }
01932 if (ast_test_flag(&flags, OPTION_DCS)) {
01933 h.dcs = 1;
01934 }
01935 #if 0
01936 case '1':
01937 case '2':
01938 case '3':
01939 case '4':
01940 case '5':
01941 case '6':
01942 case '7':
01943 h.pid = 0x40 + (*d & 0xF);
01944 break;
01945 }
01946 #endif
01947 if (sms_args.argc > 2) {
01948 unsigned char *up;
01949
01950
01951
01952 h.scts = ast_tvnow();
01953 if (ast_strlen_zero(sms_args.addr) || strlen(sms_args.addr) >= sizeof(h.oa)) {
01954 ast_log(LOG_ERROR, "Address too long %s\n", sms_args.addr);
01955 goto done;
01956 }
01957 if (h.smsc) {
01958 ast_copy_string(h.oa, sms_args.addr, sizeof(h.oa));
01959 } else {
01960 ast_copy_string(h.da, sms_args.addr, sizeof(h.da));
01961 ast_copy_string(h.oa, h.cli, sizeof(h.oa));
01962 }
01963 h.udl = 0;
01964 if (ast_strlen_zero(sms_args.body)) {
01965 ast_log(LOG_ERROR, "Missing body for %s\n", sms_args.addr);
01966 goto done;
01967 }
01968 up = (unsigned char *)sms_args.body;
01969 while (*up && h.udl < SMSLEN) {
01970 h.ud[h.udl++] = utf8decode(&up);
01971 }
01972 if (is7bit(h.dcs) && packsms7(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01973 ast_log(LOG_WARNING, "Invalid 7 bit GSM data\n");
01974 goto done;
01975 }
01976 if (is8bit(h.dcs) && packsms8(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01977 ast_log(LOG_WARNING, "Invalid 8 bit data\n");
01978 goto done;
01979 }
01980 if (is16bit(h.dcs) && packsms16(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01981 ast_log(LOG_WARNING, "Invalid 16 bit data\n");
01982 goto done;
01983 }
01984 h.rx = 0;
01985 h.mr = -1;
01986 sms_writefile(&h);
01987 res = h.err;
01988 goto done;
01989 }
01990
01991 if (chan->_state != AST_STATE_UP) {
01992 ast_answer(chan);
01993 }
01994
01995 if (ast_test_flag(&flags, OPTION_ANSWER)) {
01996 h.framenumber = 1;
01997
01998 if (h.protocol == 2) {
01999 h.omsg[0] = DLL2_SMS_EST;
02000 h.omsg[1] = 0;
02001 } else {
02002 h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
02003 h.omsg[1] = 0;
02004 }
02005 sms_messagetx(&h);
02006 }
02007
02008 res = ast_set_write_format(chan, __OUT_FMT);
02009 if (res >= 0) {
02010 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
02011 }
02012 if (res < 0) {
02013 ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");
02014 goto done;
02015 }
02016
02017 if ( (res = ast_activate_generator(chan, &smsgen, &h)) < 0) {
02018 ast_log(LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
02019 goto done;
02020 }
02021
02022
02023 for (;;) {
02024 struct ast_frame *f;
02025 int i = ast_waitfor(chan, -1);
02026 if (i < 0) {
02027 ast_log(LOG_NOTICE, "waitfor failed\n");
02028 break;
02029 }
02030 if (h.hangup) {
02031 ast_log(LOG_NOTICE, "channel hangup\n");
02032 break;
02033 }
02034 f = ast_read(chan);
02035 if (!f) {
02036 ast_log(LOG_NOTICE, "ast_read failed\n");
02037 break;
02038 }
02039 if (f->frametype == AST_FRAME_VOICE) {
02040 sms_process(&h, f->samples, f->data.ptr);
02041 }
02042
02043 ast_frfree(f);
02044 }
02045 res = h.err;
02046
02047
02048
02049
02050
02051 ast_deactivate_generator(chan);
02052
02053 sms_log(&h, '?');
02054 done:
02055 return (res);
02056 }
02057
02058 static int unload_module(void)
02059 {
02060 return ast_unregister_application(app);
02061 }
02062
02063 static int load_module(void)
02064 {
02065 #ifdef OUTALAW
02066 int p;
02067 for (p = 0; p < 80; p++) {
02068 wavea[p] = AST_LIN2A(wave[p]);
02069 }
02070 #endif
02071 snprintf(log_file, sizeof(log_file), "%s/sms", ast_config_AST_LOG_DIR);
02072 return ast_register_application_xml(app, sms_exec);
02073 }
02074
02075 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");