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: 403855 $")
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 && 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 l += l % 2;
00718 unpacksms16(i, l, udh, udhl, ud, udl, udhi);
00719 }
00720 return l + 1;
00721 }
00722
00723
00724 static unsigned char unpackaddress(char *o, unsigned char *i)
00725 {
00726 unsigned char l = i[0], p;
00727 if (i[1] == 0x91) {
00728 *o++ = '+';
00729 }
00730 for (p = 0; p < l; p++) {
00731 if (p & 1) {
00732 *o++ = (i[2 + p / 2] >> 4) + '0';
00733 } else {
00734 *o++ = (i[2 + p / 2] & 0xF) + '0';
00735 }
00736 }
00737 *o = 0;
00738 return (l + 5) / 2;
00739 }
00740
00741
00742 static unsigned char packaddress(unsigned char *o, char *i)
00743 {
00744 unsigned char p = 2;
00745 o[0] = 0;
00746 if (*i == '+') {
00747 i++;
00748 o[1] = 0x91;
00749 } else {
00750 o[1] = 0x81;
00751 }
00752 for ( ; *i ; i++) {
00753 if (!isdigit(*i)) {
00754 continue;
00755 }
00756 if (o[0] & 1) {
00757 o[p++] |= ((*i & 0xF) << 4);
00758 } else {
00759 o[p] = (*i & 0xF);
00760 }
00761 o[0]++;
00762 }
00763 if (o[0] & 1) {
00764 o[p++] |= 0xF0;
00765 }
00766 return p;
00767 }
00768
00769
00770 static void sms_log(sms_t * h, char status)
00771 {
00772 int o;
00773
00774 if (*h->oa == '\0' && *h->da == '\0') {
00775 return;
00776 }
00777 o = open(log_file, O_CREAT | O_APPEND | O_WRONLY, AST_FILE_MODE);
00778 if (o >= 0) {
00779 char line[1000], mrs[3] = "", *p;
00780 char buf[30];
00781 unsigned char n;
00782
00783 if (h->mr >= 0) {
00784 snprintf(mrs, sizeof(mrs), "%02X", h->mr);
00785 }
00786 snprintf(line, sizeof(line), "%s %c%c%c%s %s %s %s ",
00787 isodate(time(NULL), buf, sizeof(buf)),
00788 status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue,
00789 S_OR(h->oa, "-"), S_OR(h->da, "-") );
00790 p = line + strlen(line);
00791 for (n = 0; n < h->udl; n++) {
00792 if (h->ud[n] == '\\') {
00793 *p++ = '\\';
00794 *p++ = '\\';
00795 } else if (h->ud[n] == '\n') {
00796 *p++ = '\\';
00797 *p++ = 'n';
00798 } else if (h->ud[n] == '\r') {
00799 *p++ = '\\';
00800 *p++ = 'r';
00801 } else if (h->ud[n] < 32 || h->ud[n] == 127) {
00802 *p++ = 191;
00803 } else {
00804 *p++ = h->ud[n];
00805 }
00806 }
00807 *p++ = '\n';
00808 *p = 0;
00809 if (write(o, line, strlen(line)) < 0) {
00810 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
00811 }
00812 close(o);
00813 }
00814 *h->oa = *h->da = h->udl = 0;
00815 }
00816
00817
00818 static void sms_readfile(sms_t * h, char *fn)
00819 {
00820 char line[1000];
00821 FILE *s;
00822 char dcsset = 0;
00823 ast_log(LOG_NOTICE, "Sending %s\n", fn);
00824 h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
00825 h->mr = -1;
00826 h->dcs = 0xF1;
00827 h->scts = ast_tvnow();
00828 s = fopen(fn, "r");
00829 if (s) {
00830 if (unlink(fn)) {
00831 fclose(s);
00832 return;
00833 }
00834 while (fgets (line, sizeof(line), s)) {
00835 char *p;
00836 void *pp = &p;
00837 for (p = line; *p && *p != '\n' && *p != '\r'; p++);
00838 *p = 0;
00839 p = line;
00840 if (!*p || *p == ';') {
00841 continue;
00842 }
00843 while (isalnum(*p)) {
00844 *p = tolower (*p);
00845 p++;
00846 }
00847 while (isspace (*p)) {
00848 *p++ = 0;
00849 }
00850 if (*p == '=') {
00851 *p++ = 0;
00852 if (!strcmp(line, "ud")) {
00853 unsigned char o = 0;
00854 memcpy(h->udtxt, p, SMSLEN);
00855 while (*p && o < SMSLEN) {
00856 h->ud[o++] = utf8decode(pp);
00857 }
00858 h->udl = o;
00859 if (*p) {
00860 ast_log(LOG_WARNING, "UD too long in %s\n", fn);
00861 }
00862 } else {
00863 while (isspace (*p)) {
00864 p++;
00865 }
00866 if (!strcmp(line, "oa") && strlen(p) < sizeof(h->oa)) {
00867 numcpy (h->oa, p);
00868 } else if (!strcmp(line, "da") && strlen(p) < sizeof(h->oa)) {
00869 numcpy (h->da, p);
00870 } else if (!strcmp(line, "pid")) {
00871 h->pid = atoi(p);
00872 } else if (!strcmp(line, "dcs")) {
00873 h->dcs = atoi(p);
00874 dcsset = 1;
00875 } else if (!strcmp(line, "mr")) {
00876 h->mr = atoi(p);
00877 } else if (!strcmp(line, "srr")) {
00878 h->srr = (atoi(p) ? 1 : 0);
00879 } else if (!strcmp(line, "vp")) {
00880 h->vp = atoi(p);
00881 } else if (!strcmp(line, "rp")) {
00882 h->rp = (atoi(p) ? 1 : 0);
00883 } else if (!strcmp(line, "scts")) {
00884 int Y, m, d, H, M, S;
00885
00886 if (sscanf(p, "%4d-%2d-%2dT%2d:%2d:%2d", &Y, &m, &d, &H, &M, &S) == 6) {
00887 struct ast_tm t = { 0, };
00888 t.tm_year = Y - 1900;
00889 t.tm_mon = m - 1;
00890 t.tm_mday = d;
00891 t.tm_hour = H;
00892 t.tm_min = M;
00893 t.tm_sec = S;
00894 t.tm_isdst = -1;
00895 h->scts = ast_mktime(&t, NULL);
00896 if (h->scts.tv_sec == 0) {
00897 ast_log(LOG_WARNING, "Bad date/timein %s: %s", fn, p);
00898 }
00899 }
00900 } else {
00901 ast_log(LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
00902 }
00903 }
00904 } else if (*p == '#') {
00905 *p++ = 0;
00906 if (*p == '#') {
00907 p++;
00908 if (!strcmp(line, "ud")) {
00909 int o = 0;
00910 while (*p && o < SMSLEN) {
00911 if (isxdigit(*p) && isxdigit(p[1]) && isxdigit(p[2]) && isxdigit(p[3])) {
00912 h->ud[o++] =
00913 (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 12) +
00914 (((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
00915 (((isalpha(p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha(p[3]) ? 9 : 0) + (p[3] & 0xF));
00916 p += 4;
00917 } else
00918 break;
00919 }
00920 h->udl = o;
00921 if (*p)
00922 ast_log(LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
00923 } else
00924 ast_log(LOG_WARNING, "Only ud can use ## format, %s\n", fn);
00925 } else if (!strcmp(line, "ud")) {
00926 int o = 0;
00927 while (*p && o < SMSLEN) {
00928 if (isxdigit(*p) && isxdigit(p[1])) {
00929 h->ud[o++] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
00930 p += 2;
00931 } else {
00932 break;
00933 }
00934 }
00935 h->udl = o;
00936 if (*p) {
00937 ast_log(LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
00938 }
00939 } else if (!strcmp(line, "udh")) {
00940 unsigned char o = 0;
00941 h->udhi = 1;
00942 while (*p && o < SMSLEN) {
00943 if (isxdigit(*p) && isxdigit(p[1])) {
00944 h->udh[o] = (((isalpha(*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha(p[1]) ? 9 : 0) + (p[1] & 0xF));
00945 o++;
00946 p += 2;
00947 } else {
00948 break;
00949 }
00950 }
00951 h->udhl = o;
00952 if (*p) {
00953 ast_log(LOG_WARNING, "UDH too long / invalid hex in %s\n", fn);
00954 }
00955 } else {
00956 ast_log(LOG_WARNING, "Only ud and udh can use # format, %s\n", fn);
00957 }
00958 } else {
00959 ast_log(LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
00960 }
00961 }
00962 fclose(s);
00963 if (!dcsset && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00964 if (packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00965 if (packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00966 ast_log(LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
00967 } else {
00968 h->dcs = 0x08;
00969 ast_log(LOG_WARNING, "Sending in 16 bit format(%s)\n", fn);
00970 }
00971 } else {
00972 h->dcs = 0xF5;
00973 ast_log(LOG_WARNING, "Sending in 8 bit format(%s)\n", fn);
00974 }
00975 }
00976 if (is7bit(h->dcs) && packsms7(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00977 ast_log(LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn);
00978 }
00979 if (is8bit(h->dcs) && packsms8(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00980 ast_log(LOG_WARNING, "Invalid 8 bit data %s\n", fn);
00981 }
00982 if (is16bit(h->dcs) && packsms16(0, h->udhl, h->udh, h->udl, h->ud) < 0) {
00983 ast_log(LOG_WARNING, "Invalid 16 bit data %s\n", fn);
00984 }
00985 }
00986 }
00987
00988
00989 static void sms_writefile(sms_t * h)
00990 {
00991 char fn[200] = "", fn2[200] = "";
00992 char buf[30];
00993 FILE *o;
00994
00995 if (ast_tvzero(h->scts)) {
00996 h->scts = ast_tvnow();
00997 }
00998 snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx");
00999 ast_mkdir(fn, 0777);
01000 ast_copy_string(fn2, fn, sizeof(fn2));
01001 snprintf(fn2 + strlen(fn2), sizeof(fn2) - strlen(fn2), "/%s.%s-%d", h->queue, isodate(h->scts.tv_sec, buf, sizeof(buf)), seq++);
01002 snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/.%s", fn2 + strlen(fn) + 1);
01003 if ((o = fopen(fn, "w")) == NULL) {
01004 return;
01005 }
01006
01007 if (*h->oa) {
01008 fprintf(o, "oa=%s\n", h->oa);
01009 }
01010 if (*h->da) {
01011 fprintf(o, "da=%s\n", h->da);
01012 }
01013 if (h->udhi) {
01014 unsigned int p;
01015 fprintf(o, "udh#");
01016 for (p = 0; p < h->udhl; p++) {
01017 fprintf(o, "%02X", h->udh[p]);
01018 }
01019 fprintf(o, "\n");
01020 }
01021 if (h->udl) {
01022 unsigned int p;
01023 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
01024 if (p < h->udl) {
01025 fputc(';', o);
01026 }
01027 fprintf(o, "ud=");
01028 for (p = 0; p < h->udl; p++) {
01029 unsigned short v = h->ud[p];
01030 if (v < 32) {
01031 fputc(191, o);
01032 } else if (v < 0x80) {
01033 fputc(v, o);
01034 } else if (v < 0x800) {
01035 fputc(0xC0 + (v >> 6), o);
01036 fputc(0x80 + (v & 0x3F), o);
01037 } else {
01038 fputc(0xE0 + (v >> 12), o);
01039 fputc(0x80 + ((v >> 6) & 0x3F), o);
01040 fputc(0x80 + (v & 0x3F), o);
01041 }
01042 }
01043 fprintf(o, "\n");
01044 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++);
01045 if (p < h->udl) {
01046 for (p = 0; p < h->udl && h->ud[p] < 0x100; p++);
01047 if (p == h->udl) {
01048 fprintf(o, "ud#");
01049 for (p = 0; p < h->udl; p++) {
01050 fprintf(o, "%02X", h->ud[p]);
01051 }
01052 fprintf(o, "\n");
01053 } else {
01054 fprintf(o, "ud##");
01055 for (p = 0; p < h->udl; p++) {
01056 fprintf(o, "%04X", h->ud[p]);
01057 }
01058 fprintf(o, "\n");
01059 }
01060 }
01061 }
01062 if (h->scts.tv_sec) {
01063 char datebuf[30];
01064 fprintf(o, "scts=%s\n", isodate(h->scts.tv_sec, datebuf, sizeof(datebuf)));
01065 }
01066 if (h->pid) {
01067 fprintf(o, "pid=%d\n", h->pid);
01068 }
01069 if (h->dcs != 0xF1) {
01070 fprintf(o, "dcs=%d\n", h->dcs);
01071 }
01072 if (h->vp) {
01073 fprintf(o, "vp=%d\n", h->vp);
01074 }
01075 if (h->srr) {
01076 fprintf(o, "srr=1\n");
01077 }
01078 if (h->mr >= 0) {
01079 fprintf(o, "mr=%d\n", h->mr);
01080 }
01081 if (h->rp) {
01082 fprintf(o, "rp=1\n");
01083 }
01084 fclose(o);
01085 if (rename(fn, fn2)) {
01086 unlink(fn);
01087 } else {
01088 ast_log(LOG_NOTICE, "Received to %s\n", fn2);
01089 }
01090 }
01091
01092
01093 static struct dirent *readdirqueue(DIR *d, char *queue)
01094 {
01095 struct dirent *f;
01096 do {
01097 f = readdir(d);
01098 } while (f && (*f->d_name == '.' || strncmp(f->d_name, queue, strlen(queue)) || f->d_name[strlen(queue)] != '.'));
01099 return f;
01100 }
01101
01102
01103 static unsigned char sms_handleincoming (sms_t * h)
01104 {
01105 unsigned char p = 3;
01106 if (h->smsc) {
01107 if ((h->imsg[2] & 3) == 1) {
01108 h->udhl = h->udl = 0;
01109 h->vp = 0;
01110 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
01111 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
01112 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
01113 ast_copy_string(h->oa, h->cli, sizeof(h->oa));
01114 h->scts = ast_tvnow();
01115 h->mr = h->imsg[p++];
01116 p += unpackaddress(h->da, h->imsg + p);
01117 h->pid = h->imsg[p++];
01118 h->dcs = h->imsg[p++];
01119 if ((h->imsg[2] & 0x18) == 0x10) {
01120 if (h->imsg[p] < 144) {
01121 h->vp = (h->imsg[p] + 1) * 5;
01122 } else if (h->imsg[p] < 168) {
01123 h->vp = 720 + (h->imsg[p] - 143) * 30;
01124 } else if (h->imsg[p] < 197) {
01125 h->vp = (h->imsg[p] - 166) * 1440;
01126 } else {
01127 h->vp = (h->imsg[p] - 192) * 10080;
01128 }
01129 p++;
01130 } else if (h->imsg[2] & 0x18) {
01131 p += 7;
01132 }
01133 p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
01134 h->rx = 1;
01135 sms_writefile(h);
01136 if (p != h->imsg[1] + 2) {
01137 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
01138 return 0xFF;
01139 }
01140 } else {
01141 ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
01142 return 0xFF;
01143 }
01144 } else {
01145 if (!(h->imsg[2] & 3)) {
01146 *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0;
01147 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0);
01148 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0);
01149 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0);
01150 h->mr = -1;
01151 p += unpackaddress(h->oa, h->imsg + p);
01152 h->pid = h->imsg[p++];
01153 h->dcs = h->imsg[p++];
01154 h->scts = unpackdate(h->imsg + p);
01155 p += 7;
01156 p += unpacksms(h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi);
01157 h->rx = 1;
01158 sms_writefile(h);
01159 if (p != h->imsg[1] + 2) {
01160 ast_log(LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2);
01161 return 0xFF;
01162 }
01163 } else {
01164 ast_log(LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]);
01165 return 0xFF;
01166 }
01167 }
01168 return 0;
01169 }
01170
01171 #ifdef SOLARIS
01172 #define NAME_MAX 1024
01173 #endif
01174
01175
01176
01177
01178
01179 static void adddata_proto2(sms_t *h, unsigned char msg, char *data, int size)
01180 {
01181 int x = h->omsg[1] + 2;
01182 if (x == 2) {
01183 x += 2;
01184 }
01185 h->omsg[x++] = msg;
01186 h->omsg[x++] = (unsigned char)size;
01187 h->omsg[x++] = 0;
01188 for (; size > 0 ; size--) {
01189 h->omsg[x++] = *data++;
01190 }
01191 h->omsg[1] = x - 2;
01192 h->omsg[2] = x - 4;
01193 h->omsg[3] = 0;
01194 }
01195
01196 static void putdummydata_proto2(sms_t *h)
01197 {
01198 adddata_proto2(h, 0x10, "\0", 1);
01199 adddata_proto2(h, 0x11, "\0\0\0\0\0\0", 6);
01200 adddata_proto2(h, 0x12, "\2\0\4", 3);
01201 adddata_proto2(h, 0x13, h->udtxt, h->udl);
01202 }
01203
01204 static void sms_compose2(sms_t *h, int more)
01205 {
01206 struct ast_tm tm;
01207 struct timeval now = h->scts;
01208 char stm[9];
01209
01210 h->omsg[0] = 0x00;
01211 h->omsg[1] = 0;
01212 putdummydata_proto2(h);
01213 if (h->smsc) {
01214 h->omsg[0] = 0x11;
01215
01216 ast_localtime(&now, &tm, NULL);
01217 sprintf(stm, "%02d%02d%02d%02d", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min);
01218 adddata_proto2(h, 0x14, stm, 8);
01219 if (*h->oa == 0) {
01220 strcpy(h->oa, "00000000");
01221 }
01222 adddata_proto2(h, 0x15, h->oa, strlen(h->oa));
01223 adddata_proto2(h, 0x17, "\1", 1);
01224 } else {
01225 h->omsg[0] = 0x10;
01226
01227 adddata_proto2(h, 0x17, "\1", 1);
01228 if (*h->da == 0) {
01229 strcpy(h->da, "00000000");
01230 }
01231 adddata_proto2(h, 0x18, h->da, strlen(h->da));
01232 adddata_proto2(h, 0x1B, "\1", 1);
01233 adddata_proto2(h, 0x1C, "\0\0\0", 3);
01234 }
01235 }
01236
01237 static void putdummydata_proto2(sms_t *h);
01238
01239 #define MAX_DEBUG_LEN 300
01240 static char *sms_hexdump(unsigned char buf[], int size, char *s )
01241 {
01242 char *p;
01243 int f;
01244
01245 for (p = s, f = 0; f < size && f < MAX_DEBUG_LEN; f++, p += 3) {
01246 sprintf(p, "%02X ", (unsigned char)buf[f]);
01247 }
01248 return(s);
01249 }
01250
01251
01252
01253 static int sms_handleincoming_proto2(sms_t *h)
01254 {
01255 int f, i, sz = 0;
01256 int msg, msgsz;
01257 struct ast_tm tm;
01258 struct timeval now = { 0, 0 };
01259 char debug_buf[MAX_DEBUG_LEN * 3 + 1];
01260
01261 sz = h->imsg[1] + 2;
01262
01263
01264
01265 now = h->scts = ast_tvnow();
01266 for (f = 4; f < sz; ) {
01267 msg = h->imsg[f++];
01268 msgsz = h->imsg[f++];
01269 msgsz += (h->imsg[f++] * 256);
01270 switch (msg) {
01271 case 0x13:
01272 ast_verb(3, "SMS-P2 Body#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01273 if (msgsz >= sizeof(h->ud)) {
01274 msgsz = sizeof(h->ud) - 1;
01275 }
01276 for (i = 0; i < msgsz; i++) {
01277 h->ud[i] = h->imsg[f + i];
01278 }
01279 h->udl = msgsz;
01280 break;
01281 case 0x14:
01282 now = h->scts = ast_tvnow();
01283 ast_localtime(&now, &tm, NULL);
01284 tm.tm_mon = ( (h->imsg[f] * 10) + h->imsg[f + 1] ) - 1;
01285 tm.tm_mday = ( (h->imsg[f + 2] * 10) + h->imsg[f + 3] );
01286 tm.tm_hour = ( (h->imsg[f + 4] * 10) + h->imsg[f + 5] );
01287 tm.tm_min = ( (h->imsg[f + 6] * 10) + h->imsg[f + 7] );
01288 tm.tm_sec = 0;
01289 h->scts = ast_mktime(&tm, NULL);
01290 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);
01291 break;
01292 case 0x15:
01293 if (msgsz >= 20) {
01294 msgsz = 20 - 1;
01295 }
01296 ast_verb(3, "SMS-P2 Origin#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01297 ast_copy_string(h->oa, (char *)(&h->imsg[f]), msgsz + 1);
01298 break;
01299 case 0x18:
01300 if (msgsz >= 20) {
01301 msgsz = 20 - 1;
01302 }
01303 ast_verb(3, "SMS-P2 Destination#%02X=[%.*s]\n", msg, msgsz, &h->imsg[f]);
01304 ast_copy_string(h->da, (char *)(&h->imsg[f]), msgsz + 1);
01305 break;
01306 case 0x1C:
01307 ast_verb(3, "SMS-P2 Notify#%02X=%s\n", msg, sms_hexdump(&h->imsg[f], 3, debug_buf));
01308 break;
01309 default:
01310 ast_verb(3, "SMS-P2 Par#%02X [%d]: %s\n", msg, msgsz, sms_hexdump(&h->imsg[f], msgsz, debug_buf));
01311 break;
01312 }
01313 f+=msgsz;
01314 }
01315 h->rx = 1;
01316 sms_writefile(h);
01317 return 0;
01318 }
01319
01320 #if 0
01321 static void smssend(sms_t *h, char *c)
01322 {
01323 int f, x;
01324 for (f = 0; f < strlen(c); f++) {
01325 sscanf(&c[f*3], "%x", &x);
01326 h->omsg[f] = x;
01327 }
01328 sms_messagetx(h);
01329 }
01330 #endif
01331
01332 static void sms_nextoutgoing (sms_t *h);
01333
01334 static void sms_messagerx2(sms_t * h)
01335 {
01336 int p = h->imsg[0] & DLL_SMS_MASK ;
01337 int cause;
01338
01339 #define DLL2_ACK(h) ((h->framenumber & 1) ? DLL2_SMS_ACK1: DLL2_SMS_ACK1)
01340 switch (p) {
01341 case DLL2_SMS_EST:
01342 sms_nextoutgoing (h);
01343
01344 break;
01345
01346 case DLL2_SMS_INFO_MO:
01347 case DLL2_SMS_INFO_MT:
01348 cause = sms_handleincoming_proto2(h);
01349 if (!cause) {
01350 sms_log(h, 'Y');
01351 }
01352 h->omsg[0] = DLL2_ACK(h);
01353 h->omsg[1] = 0x06;
01354 h->omsg[2] = 0x04;
01355 h->omsg[3] = 0x00;
01356 h->omsg[4] = 0x1f;
01357 h->omsg[5] = 0x01;
01358 h->omsg[6] = 0x00;
01359 h->omsg[7] = cause;
01360 sms_messagetx(h);
01361 break;
01362
01363 case DLL2_SMS_NACK:
01364 h->omsg[0] = DLL2_SMS_REL;
01365 h->omsg[1] = 0x00;
01366 sms_messagetx(h);
01367 break;
01368
01369 case DLL2_SMS_ACK0:
01370 case DLL2_SMS_ACK1:
01371
01372 if ( (h->omsg[0] & DLL_SMS_MASK) == DLL2_SMS_REL) {
01373
01374 h->hangup = 1;
01375 } else {
01376
01377 ast_log(LOG_NOTICE, "SMS_SUBMIT or SMS_DELIVERY\n");
01378 sms_nextoutgoing (h);
01379 }
01380 break;
01381
01382 case DLL2_SMS_REL:
01383 h->omsg[0] = DLL2_ACK(h);
01384 h->omsg[1] = 0;
01385 sms_messagetx(h);
01386 break;
01387 }
01388 }
01389
01390
01391 static void sms_compose1(sms_t *h, int more)
01392 {
01393 unsigned int p = 2;
01394
01395 h->omsg[0] = 0x91;
01396 if (h->smsc) {
01397 h->omsg[p++] = (more ? 4 : 0) + ((h->udhl > 0) ? 0x40 : 0);
01398 p += packaddress(h->omsg + p, h->oa);
01399 h->omsg[p++] = h->pid;
01400 h->omsg[p++] = h->dcs;
01401 packdate(h->omsg + p, h->scts.tv_sec);
01402 p += 7;
01403 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
01404 } else {
01405 h->omsg[p++] =
01406 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0);
01407 if (h->mr < 0) {
01408 h->mr = message_ref++;
01409 }
01410 h->omsg[p++] = h->mr;
01411 p += packaddress(h->omsg + p, h->da);
01412 h->omsg[p++] = h->pid;
01413 h->omsg[p++] = h->dcs;
01414 if (h->vp) {
01415 if (h->vp < 720) {
01416 h->omsg[p++] = (h->vp + 4) / 5 - 1;
01417 } else if (h->vp < 1440) {
01418 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143;
01419 } else if (h->vp < 43200) {
01420 h->omsg[p++] = (h->vp + 1439) / 1440 + 166;
01421 } else if (h->vp < 635040) {
01422 h->omsg[p++] = (h->vp + 10079) / 10080 + 192;
01423 } else {
01424 h->omsg[p++] = 255;
01425 }
01426 }
01427 p += packsms(h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud);
01428 }
01429 h->omsg[1] = p - 2;
01430 }
01431
01432
01433 static void sms_nextoutgoing (sms_t * h)
01434 {
01435 char fn[100 + NAME_MAX] = "";
01436 DIR *d;
01437 char more = 0;
01438
01439 *h->da = *h->oa = '\0';
01440 h->rx = 0;
01441 snprintf(fn, sizeof(fn), "%s/sms/%s", ast_config_AST_SPOOL_DIR, h->smsc ? "mttx" : "motx");
01442 ast_mkdir(fn, 0777);
01443 d = opendir(fn);
01444 if (d) {
01445 struct dirent *f = readdirqueue(d, h->queue);
01446 if (f) {
01447 snprintf(fn + strlen(fn), sizeof(fn) - strlen(fn), "/%s", f->d_name);
01448 sms_readfile(h, fn);
01449 if (readdirqueue(d, h->queue)) {
01450 more = 1;
01451 }
01452 }
01453 closedir(d);
01454 }
01455 if (*h->da || *h->oa) {
01456 if (h->protocol == 2) {
01457 sms_compose2(h, more);
01458 } else {
01459 sms_compose1(h, more);
01460 }
01461 } else {
01462 if (h->protocol == 2) {
01463 h->omsg[0] = 0x17;
01464 h->omsg[1] = 0;
01465 } else {
01466 h->omsg[0] = 0x94;
01467 h->omsg[1] = 0;
01468 }
01469 }
01470 sms_messagetx(h);
01471 }
01472
01473 #define DIR_RX 1
01474 #define DIR_TX 2
01475 static void sms_debug (int dir, sms_t *h)
01476 {
01477 char txt[259 * 3 + 1];
01478 char *p = txt;
01479 unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
01480 int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
01481 int q = 0;
01482 while (q < n && q < 30) {
01483 sprintf(p, " %02X", msg[q++]);
01484 p += 3;
01485 }
01486 if (q < n) {
01487 sprintf(p, "...");
01488 }
01489 ast_verb(3, "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
01490 }
01491
01492
01493 static void sms_messagerx(sms_t * h)
01494 {
01495 int cause;
01496
01497 sms_debug (DIR_RX, h);
01498 if (h->protocol == 2) {
01499 sms_messagerx2(h);
01500 return;
01501 }
01502
01503 switch (h->imsg[0]) {
01504 case 0x91:
01505 cause = sms_handleincoming (h);
01506 if (!cause) {
01507 sms_log(h, 'Y');
01508 h->omsg[0] = 0x95;
01509 h->omsg[1] = 0x02;
01510 h->omsg[2] = 0x00;
01511 h->omsg[3] = 0x00;
01512 } else {
01513 sms_log(h, 'N');
01514 h->omsg[0] = 0x96;
01515 h->omsg[1] = 3;
01516 h->omsg[2] = 0;
01517 h->omsg[3] = cause;
01518 h->omsg[4] = 0;
01519 }
01520 sms_messagetx(h);
01521 break;
01522
01523 case 0x92:
01524 h->err = 1;
01525 sms_messagetx(h);
01526 break;
01527 case 0x93:
01528 sms_nextoutgoing (h);
01529 break;
01530 case 0x94:
01531 h->hangup = 1;
01532 break;
01533 case 0x95:
01534 sms_log(h, 'Y');
01535 sms_nextoutgoing (h);
01536 break;
01537 case 0x96:
01538 h->err = 1;
01539 sms_log(h, 'N');
01540 sms_nextoutgoing (h);
01541 break;
01542 default:
01543 h->omsg[0] = 0x92;
01544 h->omsg[1] = 1;
01545 h->omsg[2] = 3;
01546 sms_messagetx(h);
01547 break;
01548 }
01549 }
01550
01551 static void sms_messagetx(sms_t * h)
01552 {
01553 unsigned char c = 0, p;
01554 int len = h->omsg[1] + 2;
01555
01556 for (p = 0; p < len; p++) {
01557 c += h->omsg[p];
01558 }
01559 h->omsg[len] = 0 - c;
01560 sms_debug(DIR_TX, h);
01561 h->framenumber++;
01562 h->obytep = 0;
01563 h->obitp = 0;
01564 if (h->protocol == 2) {
01565 h->oseizure = 300;
01566 h->obyte = 0;
01567 if (h->omsg[0] == 0x7F) {
01568 h->opause = 8 * h->opause_0;
01569 } else {
01570 h->opause = 400;
01571 }
01572 } else {
01573 h->oseizure = 0;
01574 h->obyte = 1;
01575
01576
01577
01578
01579 if (h->omsg[0] == 0x93) {
01580 h->opause = 8 * h->opause_0;
01581 } else {
01582 h->opause = 200;
01583 }
01584 }
01585
01586 h->osync = OSYNC_BITS;
01587 h->obyten = len + 1;
01588 }
01589
01590
01591
01592
01593
01594 static int sms_generate(struct ast_channel *chan, void *data, int len, int samples)
01595 {
01596 struct ast_frame f = { 0 };
01597 #define MAXSAMPLES (800)
01598 output_t *buf;
01599 sms_t *h = data;
01600 int i;
01601
01602 if (samples > MAXSAMPLES) {
01603 ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n",
01604 MAXSAMPLES, samples);
01605 samples = MAXSAMPLES;
01606 }
01607 len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
01608 buf = ast_alloca(len);
01609
01610 f.frametype = AST_FRAME_VOICE;
01611 ast_format_set(&f.subclass.format, __OUT_FMT, 0);
01612 f.datalen = samples * sizeof(*buf);
01613 f.offset = AST_FRIENDLY_OFFSET;
01614 f.mallocd = 0;
01615 f.data.ptr = buf;
01616 f.samples = samples;
01617 f.src = "app_sms";
01618
01619 for (i = 0; i < samples; i++) {
01620 buf[i] = wave_out[0];
01621
01622 if (h->opause) {
01623 h->opause--;
01624 } else if (h->obyten || h->osync) {
01625 buf[i] = wave_out[h->ophase];
01626 h->ophase += (h->obyte & 1) ? 13 : 21;
01627 if (h->ophase >= 80)
01628 h->ophase -= 80;
01629 if ((h->ophasep += 12) >= 80) {
01630 h->ophasep -= 80;
01631 if (h->oseizure > 0) {
01632 h->oseizure--;
01633 h->obyte ^= 1;
01634 } else if (h->osync) {
01635 h->obyte = 1;
01636 h->osync--;
01637 if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
01638 h->obytep = h->obyten = 0;
01639 }
01640 } else {
01641 h->obitp++;
01642 if (h->obitp == 1) {
01643 h->obyte = 0;
01644 } else if (h->obitp == 2) {
01645 h->obyte = h->omsg[h->obytep];
01646 } else if (h->obitp == 10) {
01647 h->obyte = 1;
01648 h->obitp = 0;
01649 h->obytep++;
01650 if (h->obytep == h->obyten) {
01651 h->obytep = h->obyten = 0;
01652 h->osync = 10;
01653 }
01654 } else {
01655 h->obyte >>= 1;
01656 }
01657 }
01658 }
01659 }
01660 }
01661 if (ast_write(chan, &f) < 0) {
01662 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", ast_channel_name(chan), strerror(errno));
01663 return -1;
01664 }
01665 return 0;
01666 #undef MAXSAMPLES
01667 }
01668
01669
01670
01671
01672 static void *sms_alloc(struct ast_channel *chan, void *sms_t_ptr)
01673 {
01674 return sms_t_ptr;
01675 }
01676
01677 static void sms_release(struct ast_channel *chan, void *data)
01678 {
01679 return;
01680 }
01681
01682 static struct ast_generator smsgen = {
01683 .alloc = sms_alloc,
01684 .release = sms_release,
01685 .generate = sms_generate,
01686 };
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700 static void sms_process(sms_t * h, int samples, signed short *data)
01701 {
01702 int bit;
01703
01704
01705
01706
01707
01708
01709
01710
01711 if (h->obyten || h->osync) {
01712 return;
01713 }
01714 for ( ; samples-- ; data++) {
01715 unsigned long long m0, m1;
01716 if (abs(*data) > h->imag) {
01717 h->imag = abs(*data);
01718 } else {
01719 h->imag = h->imag * 7 / 8;
01720 }
01721 if (h->imag <= 500) {
01722 if (h->idle++ == 80000) {
01723 ast_log(LOG_NOTICE, "No data, hanging up\n");
01724 h->hangup = 1;
01725 h->err = 1;
01726 }
01727 if (h->ierr) {
01728 ast_log(LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
01729
01730 h->err = 1;
01731 h->omsg[0] = 0x92;
01732 h->omsg[1] = 1;
01733 h->omsg[2] = h->ierr;
01734 sms_messagetx(h);
01735 }
01736 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01737 continue;
01738 }
01739 h->idle = 0;
01740
01741
01742 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
01743 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
01744 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
01745 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
01746
01747 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
01748 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
01749
01750
01751 if ((h->ips0 += 21) >= 80) {
01752 h->ips0 -= 80;
01753 }
01754 if ((h->ipc0 += 21) >= 80) {
01755 h->ipc0 -= 80;
01756 }
01757 if ((h->ips1 += 13) >= 80) {
01758 h->ips1 -= 80;
01759 }
01760 if ((h->ipc1 += 13) >= 80) {
01761 h->ipc1 -= 80;
01762 }
01763
01764
01765 h->ibith <<= 1;
01766 if (m1 > m0) {
01767 h->ibith |= 1;
01768 }
01769 if (h->ibith & 8) {
01770 h->ibitt--;
01771 }
01772 if (h->ibith & 1) {
01773 h->ibitt++;
01774 }
01775 bit = ((h->ibitt > 1) ? 1 : 0);
01776 if (bit != h->ibitl) {
01777 h->ibitc = 1;
01778 } else {
01779 h->ibitc++;
01780 }
01781 h->ibitl = bit;
01782 if (!h->ibitn && h->ibitc == 4 && !bit) {
01783 h->ibitn = 1;
01784 h->iphasep = 0;
01785 }
01786 if (bit && h->ibitc == 200) {
01787
01788 if (h->framenumber < 0 && h->ibytec >= 160 && !memcmp(h->imsg, "UUUUUUUUUUUUUUUUUUUU", 20)) {
01789 h->framenumber = 1;
01790 ast_verb(3, "SMS protocol 2 detected\n");
01791 h->protocol = 2;
01792 h->imsg[0] = 0xff;
01793 h->imsg[1] = h->imsg[2] = 0x00;
01794 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01795 sms_messagerx(h);
01796 }
01797 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01798 }
01799 if (h->ibitn) {
01800 h->iphasep += 12;
01801 if (h->iphasep >= 80) {
01802 h->iphasep -= 80;
01803 if (h->ibitn++ == 9) {
01804 if (!bit) {
01805 ast_log(LOG_NOTICE, "bad stop bit\n");
01806 h->ierr = 0xFF;
01807 } else {
01808 if (h->ibytep < sizeof(h->imsg)) {
01809 h->imsg[h->ibytep] = h->ibytev;
01810 h->ibytec += h->ibytev;
01811 h->ibytep++;
01812 } else if (h->ibytep == sizeof(h->imsg)) {
01813 ast_log(LOG_NOTICE, "msg too large\n");
01814 h->ierr = 2;
01815 }
01816 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
01817 if (!h->ibytec) {
01818 sms_messagerx(h);
01819 } else {
01820 ast_log(LOG_NOTICE, "bad checksum\n");
01821 h->ierr = 1;
01822 }
01823 }
01824 }
01825 h->ibitn = 0;
01826 }
01827 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
01828 }
01829 }
01830 }
01831 }
01832
01833
01834
01835
01836
01837
01838
01839
01840 enum sms_flags {
01841 OPTION_BE_SMSC = (1 << 0),
01842 OPTION_ANSWER = (1 << 1),
01843 OPTION_TWO = (1 << 2),
01844 OPTION_PAUSE = (1 << 3),
01845 OPTION_SRR = (1 << 4),
01846 OPTION_DCS = (1 << 5),
01847 };
01848
01849 enum sms_opt_args {
01850 OPTION_ARG_PAUSE = 0,
01851 OPTION_ARG_ARRAY_SIZE
01852 };
01853
01854 AST_APP_OPTIONS(sms_options, {
01855 AST_APP_OPTION('s', OPTION_BE_SMSC),
01856 AST_APP_OPTION('a', OPTION_ANSWER),
01857 AST_APP_OPTION('t', OPTION_TWO),
01858 AST_APP_OPTION('r', OPTION_SRR),
01859 AST_APP_OPTION('o', OPTION_DCS),
01860 AST_APP_OPTION_ARG('p', OPTION_PAUSE, OPTION_ARG_PAUSE),
01861 } );
01862
01863 static int sms_exec(struct ast_channel *chan, const char *data)
01864 {
01865 int res = -1;
01866 sms_t h = { 0 };
01867
01868 struct ast_flags flags;
01869 char *parse, *sms_opts[OPTION_ARG_ARRAY_SIZE] = { 0, };
01870 char *p;
01871 AST_DECLARE_APP_ARGS(sms_args,
01872 AST_APP_ARG(queue);
01873 AST_APP_ARG(options);
01874 AST_APP_ARG(addr);
01875 AST_APP_ARG(body);
01876 );
01877
01878 if (!data) {
01879 ast_log(LOG_ERROR, "Requires queue name at least\n");
01880 return -1;
01881 }
01882
01883 parse = ast_strdupa(data);
01884 AST_STANDARD_APP_ARGS(sms_args, parse);
01885 if (sms_args.argc > 1) {
01886 ast_app_parse_options(sms_options, &flags, sms_opts, sms_args.options);
01887 }
01888
01889 ast_verb(1, "sms argc %d queue <%s> opts <%s> addr <%s> body <%s>\n",
01890 sms_args.argc, S_OR(sms_args.queue, ""),
01891 S_OR(sms_args.options, ""),
01892 S_OR(sms_args.addr, ""),
01893 S_OR(sms_args.body, "") );
01894
01895 h.ipc0 = h.ipc1 = 20;
01896 h.dcs = 0xF1;
01897
01898 ast_copy_string(h.cli,
01899 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""),
01900 sizeof(h.cli));
01901
01902 if (ast_strlen_zero(sms_args.queue)) {
01903 ast_log(LOG_ERROR, "Requires queue name\n");
01904 goto done;
01905 }
01906 if (strlen(sms_args.queue) >= sizeof(h.queue)) {
01907 ast_log(LOG_ERROR, "Queue name too long\n");
01908 goto done;
01909 }
01910 ast_copy_string(h.queue, sms_args.queue, sizeof(h.queue));
01911
01912 for (p = h.queue; *p; p++) {
01913 if (!isalnum(*p)) {
01914 *p = '-';
01915 }
01916 }
01917
01918 h.smsc = ast_test_flag(&flags, OPTION_BE_SMSC);
01919 h.protocol = ast_test_flag(&flags, OPTION_TWO) ? 2 : 1;
01920 if (!ast_strlen_zero(sms_opts[OPTION_ARG_PAUSE])) {
01921 h.opause_0 = atoi(sms_opts[OPTION_ARG_PAUSE]);
01922 }
01923 if (h.opause_0 < 25 || h.opause_0 > 2000) {
01924 h.opause_0 = 300;
01925 }
01926 ast_verb(1, "initial delay %dms\n", h.opause_0);
01927
01928
01929
01930 if (ast_test_flag(&flags, OPTION_SRR)) {
01931 h.srr = 1;
01932 }
01933 if (ast_test_flag(&flags, OPTION_DCS)) {
01934 h.dcs = 1;
01935 }
01936 #if 0
01937 case '1':
01938 case '2':
01939 case '3':
01940 case '4':
01941 case '5':
01942 case '6':
01943 case '7':
01944 h.pid = 0x40 + (*d & 0xF);
01945 break;
01946 }
01947 #endif
01948 if (sms_args.argc > 2) {
01949 unsigned char *up;
01950
01951
01952
01953 h.scts = ast_tvnow();
01954 if (ast_strlen_zero(sms_args.addr) || strlen(sms_args.addr) >= sizeof(h.oa)) {
01955 ast_log(LOG_ERROR, "Address too long %s\n", sms_args.addr);
01956 goto done;
01957 }
01958 if (h.smsc) {
01959 ast_copy_string(h.oa, sms_args.addr, sizeof(h.oa));
01960 } else {
01961 ast_copy_string(h.da, sms_args.addr, sizeof(h.da));
01962 ast_copy_string(h.oa, h.cli, sizeof(h.oa));
01963 }
01964 h.udl = 0;
01965 if (ast_strlen_zero(sms_args.body)) {
01966 ast_log(LOG_ERROR, "Missing body for %s\n", sms_args.addr);
01967 goto done;
01968 }
01969 up = (unsigned char *)sms_args.body;
01970 while (*up && h.udl < SMSLEN) {
01971 h.ud[h.udl++] = utf8decode(&up);
01972 }
01973 if (is7bit(h.dcs) && packsms7(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01974 ast_log(LOG_WARNING, "Invalid 7 bit GSM data\n");
01975 goto done;
01976 }
01977 if (is8bit(h.dcs) && packsms8(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01978 ast_log(LOG_WARNING, "Invalid 8 bit data\n");
01979 goto done;
01980 }
01981 if (is16bit(h.dcs) && packsms16(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01982 ast_log(LOG_WARNING, "Invalid 16 bit data\n");
01983 goto done;
01984 }
01985 h.rx = 0;
01986 h.mr = -1;
01987 sms_writefile(&h);
01988 res = h.err;
01989 goto done;
01990 }
01991
01992 if (ast_channel_state(chan) != AST_STATE_UP) {
01993 ast_answer(chan);
01994 }
01995
01996 if (ast_test_flag(&flags, OPTION_ANSWER)) {
01997 h.framenumber = 1;
01998
01999 if (h.protocol == 2) {
02000 h.omsg[0] = DLL2_SMS_EST;
02001 h.omsg[1] = 0;
02002 } else {
02003 h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
02004 h.omsg[1] = 0;
02005 }
02006 sms_messagetx(&h);
02007 }
02008
02009 res = ast_set_write_format_by_id(chan, __OUT_FMT);
02010 if (res >= 0) {
02011 res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
02012 }
02013 if (res < 0) {
02014 ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");
02015 goto done;
02016 }
02017
02018 if ( (res = ast_activate_generator(chan, &smsgen, &h)) < 0) {
02019 ast_log(LOG_ERROR, "Failed to activate generator on '%s'\n", ast_channel_name(chan));
02020 goto done;
02021 }
02022
02023
02024 for (;;) {
02025 struct ast_frame *f;
02026 int i = ast_waitfor(chan, -1);
02027 if (i < 0) {
02028 ast_log(LOG_NOTICE, "waitfor failed\n");
02029 break;
02030 }
02031 if (h.hangup) {
02032 ast_log(LOG_NOTICE, "channel hangup\n");
02033 break;
02034 }
02035 f = ast_read(chan);
02036 if (!f) {
02037 ast_log(LOG_NOTICE, "ast_read failed\n");
02038 break;
02039 }
02040 if (f->frametype == AST_FRAME_VOICE) {
02041 sms_process(&h, f->samples, f->data.ptr);
02042 }
02043
02044 ast_frfree(f);
02045 }
02046 res = h.err;
02047
02048
02049
02050
02051
02052 ast_deactivate_generator(chan);
02053
02054 sms_log(&h, '?');
02055 done:
02056 return (res);
02057 }
02058
02059 static int unload_module(void)
02060 {
02061 return ast_unregister_application(app);
02062 }
02063
02064 static int load_module(void)
02065 {
02066 #ifdef OUTALAW
02067 int p;
02068 for (p = 0; p < 80; p++) {
02069 wavea[p] = AST_LIN2A(wave[p]);
02070 }
02071 #endif
02072 snprintf(log_file, sizeof(log_file), "%s/sms", ast_config_AST_LOG_DIR);
02073 return ast_register_application_xml(app, sms_exec);
02074 }
02075
02076 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");