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: 328209 $")
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 sent_rel:1;
00220 unsigned char smsc:1;
00221 unsigned char rx:1;
00222 char queue[30];
00223 char oa[20];
00224 char da[20];
00225 struct timeval scts;
00226 unsigned char pid;
00227 unsigned char dcs;
00228 short mr;
00229 int udl;
00230 int udhl;
00231 unsigned char srr:1;
00232 unsigned char udhi:1;
00233 unsigned char rp:1;
00234 unsigned int vp;
00235 unsigned short ud[SMSLEN];
00236 unsigned char udh[SMSLEN];
00237 char cli[20];
00238 unsigned char ophase;
00239 unsigned char ophasep;
00240 unsigned char obyte;
00241 unsigned int opause;
00242 unsigned char obitp;
00243 unsigned char osync;
00244 unsigned char obytep;
00245 unsigned char obyten;
00246 unsigned char omsg[256];
00247 unsigned char imsg[250];
00248 signed long long ims0,
00249 imc0,
00250 ims1,
00251 imc1;
00252 unsigned int idle;
00253 unsigned short imag;
00254 unsigned char ips0;
00255 unsigned char ips1;
00256 unsigned char ipc0;
00257 unsigned char ipc1;
00258 unsigned char ibitl;
00259 unsigned char ibitc;
00260 unsigned char iphasep;
00261 unsigned char ibitn;
00262 unsigned char ibytev;
00263 unsigned char ibytep;
00264 unsigned char ibytec;
00265 unsigned char ierr;
00266 unsigned char ibith;
00267 unsigned char ibitt;
00268
00269
00270 int opause_0;
00271 int protocol;
00272 int oseizure;
00273 int framenumber;
00274 char udtxt[SMSLEN];
00275 } sms_t;
00276
00277
00278 #define is7bit(dcs) ( ((dcs) & 0xC0) ? (!((dcs) & 4) ) : (((dcs) & 0xc) == 0) )
00279 #define is8bit(dcs) ( ((dcs) & 0xC0) ? ( ((dcs) & 4) ) : (((dcs) & 0xc) == 4) )
00280 #define is16bit(dcs) ( ((dcs) & 0xC0) ? 0 : (((dcs) & 0xc) == 8) )
00281
00282 static void sms_messagetx(sms_t *h);
00283
00284
00285 static void numcpy(char *d, char *s)
00286 {
00287 if (*s == '+') {
00288 *d++ = *s++;
00289 }
00290 while (*s) {
00291 if (isdigit(*s)) {
00292 *d++ = *s;
00293 }
00294 s++;
00295 }
00296 *d = 0;
00297 }
00298
00299
00300 static char *isodate(time_t t, char *buf, int len)
00301 {
00302 struct ast_tm tm;
00303 struct timeval local = { t, 0 };
00304 ast_localtime(&local, &tm, NULL);
00305 ast_strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
00306 return buf;
00307 }
00308
00309
00310
00311
00312 static long utf8decode(unsigned char **pp)
00313 {
00314 unsigned char *p = *pp;
00315 if (!*p) {
00316 return 0;
00317 }
00318 (*pp)++;
00319 if (*p < 0xC0) {
00320 return *p;
00321 }
00322 if (*p < 0xE0) {
00323 if (*p < 0xC2 || (p[1] & 0xC0) != 0x80) {
00324 return *p;
00325 }
00326 (*pp)++;
00327 return ((*p & 0x1F) << 6) + (p[1] & 0x3F);
00328 }
00329 if (*p < 0xF0) {
00330 if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80) {
00331 return *p;
00332 }
00333 (*pp) += 2;
00334 return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F);
00335 }
00336 if (*p < 0xF8) {
00337 if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80) {
00338 return *p;
00339 }
00340 (*pp) += 3;
00341 return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F);
00342 }
00343 if (*p < 0xFC) {
00344 if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
00345 || (p[4] & 0xC0) != 0x80) {
00346 return *p;
00347 }
00348 (*pp) += 4;
00349 return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F);
00350 }
00351 if (*p < 0xFE) {
00352 if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80
00353 || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80) {
00354 return *p;
00355 }
00356 (*pp) += 5;
00357 return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F);
00358 }
00359 return *p;
00360 }
00361
00362
00363
00364
00365
00366 static int packsms7(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00367 {
00368 unsigned char p = 0;
00369 unsigned char b = 0;
00370 unsigned char n = 0;
00371 unsigned char dummy[SMSLEN];
00372
00373 if (o == NULL) {
00374 o = dummy;
00375 }
00376
00377 if (udhl) {
00378 o[p++] = udhl;
00379 b = 1;
00380 n = 1;
00381 while (udhl--) {
00382 o[p++] = *udh++;
00383 b += 8;
00384 while (b >= 7) {
00385 b -= 7;
00386 n++;
00387 }
00388 if (n >= SMSLEN)
00389 return n;
00390 }
00391 if (b) {
00392 b = 7 - b;
00393 if (++n >= SMSLEN)
00394 return n;
00395 }
00396 }
00397 o[p] = 0;
00398
00399 while (udl--) {
00400 long u;
00401 unsigned char v;
00402 u = *ud++;
00403
00404
00405 for (v = 0; v < 128 && defaultalphabet[v] != u; v++);
00406 if (v == 128 && u && n + 1 < SMSLEN) {
00407
00408 for (v = 0; v < 128 && escapes[v] != u; v++);
00409 if (v < 128) {
00410
00411 o[p] |= (27 << b);
00412 b += 7;
00413 if (b >= 8) {
00414 b -= 8;
00415 p++;
00416 o[p] = (27 >> (7 - b));
00417 }
00418 n++;
00419 }
00420 }
00421 if (v == 128)
00422 return -1;
00423
00424 o[p] |= (v << b);
00425 b += 7;
00426 if (b >= 8) {
00427 b -= 8;
00428 p++;
00429 o[p] = (v >> (7 - b));
00430 }
00431 if (++n >= SMSLEN)
00432 return n;
00433 }
00434 return n;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 static int packsms8(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00444 {
00445 unsigned char p = 0;
00446 unsigned char dummy[SMSLEN_8];
00447
00448 if (o == NULL)
00449 o = dummy;
00450
00451 if (udhl) {
00452 o[p++] = udhl;
00453 while (udhl--) {
00454 o[p++] = *udh++;
00455 if (p >= SMSLEN_8) {
00456 return p;
00457 }
00458 }
00459 }
00460 while (udl--) {
00461 long u;
00462 u = *ud++;
00463 if (u < 0 || u > 0xFF) {
00464 return -1;
00465 }
00466 o[p++] = u;
00467 if (p >= SMSLEN_8) {
00468 return p;
00469 }
00470 }
00471 return p;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 static int packsms16(unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud)
00483 {
00484 unsigned char p = 0;
00485 unsigned char dummy[SMSLEN_8];
00486
00487 if (o == NULL) {
00488 o = dummy;
00489 }
00490
00491 if (udhl) {
00492 o[p++] = udhl;
00493 while (udhl--) {
00494 o[p++] = *udh++;
00495 if (p >= SMSLEN_8) {
00496 return p;
00497 }
00498 }
00499 }
00500 while (udl--) {
00501 long u;
00502 u = *ud++;
00503 o[p++] = (u >> 8);
00504 if (p >= SMSLEN_8) {
00505 return p - 1;
00506 }
00507 o[p++] = u;
00508 if (p >= SMSLEN_8) {
00509 return p;
00510 }
00511 }
00512 return p;
00513 }
00514
00515
00516
00517 static int packsms(unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud)
00518 {
00519 unsigned char *p = base;
00520 if (udl == 0) {
00521 *p++ = 0;
00522 } else {
00523
00524 int l = 0;
00525 if (is7bit(dcs)) {
00526 if ((l = packsms7(p + 1, udhl, udh, udl, ud)) < 0) {
00527 l = 0;
00528 }
00529 *p++ = l;
00530 p += (l * 7 + 7) / 8;
00531 } else if (is8bit(dcs)) {
00532 if ((l = packsms8(p + 1, udhl, udh, udl, ud)) < 0) {
00533 l = 0;
00534 }
00535 *p++ = l;
00536 p += l;
00537 } else {
00538 if ((l = packsms16(p + 1, udhl, udh, udl, ud)) < 0) {
00539 l = 0;
00540 }
00541 *p++ = l;
00542 p += l;
00543 }
00544 }
00545 return p - base;
00546 }
00547
00548
00549
00550 static void packdate(unsigned char *o, time_t w)
00551 {
00552 struct ast_tm t;
00553 struct timeval topack = { w, 0 };
00554 int z;
00555
00556 ast_localtime(&topack, &t, NULL);
00557 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
00558 z = -t.tm_gmtoff / 60 / 15;
00559 #else
00560 z = timezone / 60 / 15;
00561 #endif
00562 *o++ = ((t.tm_year % 10) << 4) + (t.tm_year % 100) / 10;
00563 *o++ = (((t.tm_mon + 1) % 10) << 4) + (t.tm_mon + 1) / 10;
00564 *o++ = ((t.tm_mday % 10) << 4) + t.tm_mday / 10;
00565 *o++ = ((t.tm_hour % 10) << 4) + t.tm_hour / 10;
00566 *o++ = ((t.tm_min % 10) << 4) + t.tm_min / 10;
00567 *o++ = ((t.tm_sec % 10) << 4) + t.tm_sec / 10;
00568 if (z < 0) {
00569 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08;
00570 } else {
00571 *o++ = ((z % 10) << 4) + z / 10;
00572 }
00573 }
00574
00575
00576 static struct timeval unpackdate(unsigned char *i)
00577 {
00578 struct ast_tm t;
00579
00580 t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4);
00581 t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1;
00582 t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4);
00583 t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4);
00584 t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4);
00585 t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4);
00586 t.tm_isdst = 0;
00587 if (i[6] & 0x08) {
00588 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
00589 } else {
00590 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4));
00591 }
00592
00593 return ast_mktime(&t, NULL);
00594 }
00595
00596
00597
00598
00599 static void unpacksms7(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00600 {
00601 unsigned char b = 0, p = 0;
00602 unsigned short *o = ud;
00603 *udhl = 0;
00604 if (udhi && l) {
00605 int h = i[p];
00606 *udhl = h;
00607 if (h) {
00608 b = 1;
00609 p++;
00610 l--;
00611 while (h-- && l) {
00612 *udh++ = i[p++];
00613 b += 8;
00614 while (b >= 7) {
00615 b -= 7;
00616 l--;
00617 if (!l) {
00618 break;
00619 }
00620 }
00621 }
00622
00623 if (b) {
00624 b = 7 - b;
00625 l--;
00626 }
00627 }
00628 }
00629 while (l--) {
00630 unsigned char v;
00631 if (b < 2) {
00632 v = ((i[p] >> b) & 0x7F);
00633 } else {
00634 v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F);
00635 }
00636 b += 7;
00637 if (b >= 8) {
00638 b -= 8;
00639 p++;
00640 }
00641
00642 if (o > ud && o[-1] == 0x00A0 && escapes[v]) {
00643 o[-1] = escapes[v];
00644 } else {
00645 *o++ = defaultalphabet[v];
00646 }
00647 }
00648 *udl = (o - ud);
00649 }
00650
00651
00652
00653
00654
00655 static void unpacksms8(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00656 {
00657 unsigned short *o = ud;
00658 *udhl = 0;
00659 if (udhi) {
00660 int n = *i;
00661 *udhl = n;
00662 if (n) {
00663 i++;
00664 l--;
00665 while (l && n) {
00666 l--;
00667 n--;
00668 *udh++ = *i++;
00669 }
00670 }
00671 }
00672 while (l--) {
00673 *o++ = *i++;
00674 }
00675 *udl = (o - ud);
00676 }
00677
00678
00679
00680
00681 static void unpacksms16(unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00682 {
00683 unsigned short *o = ud;
00684 *udhl = 0;
00685 if (udhi) {
00686 int n = *i;
00687 *udhl = n;
00688 if (n) {
00689 i++;
00690 l--;
00691 while (l && n) {
00692 l--;
00693 n--;
00694 *udh++ = *i++;
00695 }
00696 }
00697 }
00698 while (l--) {
00699 int v = *i++;
00700 if (l--) {
00701 v = (v << 8) + *i++;
00702 }
00703 *o++ = v;
00704 }
00705 *udl = (o - ud);
00706 }
00707
00708
00709 static int unpacksms(unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi)
00710 {
00711 int l = *i++;
00712 if (is7bit(dcs)) {
00713 unpacksms7(i, l, udh, udhl, ud, udl, udhi);
00714 l = (l * 7 + 7) / 8;
00715 } else if (is8bit(dcs)) {
00716 unpacksms8(i, l, udh, udhl, ud, udl, udhi);
00717 } else {
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->imsg)) {
01274 msgsz = sizeof(h->imsg) - 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");
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 h->sent_rel = 1;
01469 }
01470 }
01471 sms_messagetx(h);
01472 }
01473
01474 #define DIR_RX 1
01475 #define DIR_TX 2
01476 static void sms_debug (int dir, sms_t *h)
01477 {
01478 char txt[259 * 3 + 1];
01479 char *p = txt;
01480 unsigned char *msg = (dir == DIR_RX) ? h->imsg : h->omsg;
01481 int n = (dir == DIR_RX) ? h->ibytep : msg[1] + 2;
01482 int q = 0;
01483 while (q < n && q < 30) {
01484 sprintf(p, " %02X", msg[q++]);
01485 p += 3;
01486 }
01487 if (q < n) {
01488 sprintf(p, "...");
01489 }
01490 ast_verb(3, "SMS %s%s\n", dir == DIR_RX ? "RX" : "TX", txt);
01491 }
01492
01493
01494 static void sms_messagerx(sms_t * h)
01495 {
01496 int cause;
01497
01498 sms_debug (DIR_RX, h);
01499 if (h->protocol == 2) {
01500 sms_messagerx2(h);
01501 return;
01502 }
01503
01504 switch (h->imsg[0]) {
01505 case 0x91:
01506 cause = sms_handleincoming (h);
01507 if (!cause) {
01508 sms_log(h, 'Y');
01509 h->omsg[0] = 0x95;
01510 h->omsg[1] = 0x02;
01511 h->omsg[2] = 0x00;
01512 h->omsg[3] = 0x00;
01513 } else {
01514 sms_log(h, 'N');
01515 h->omsg[0] = 0x96;
01516 h->omsg[1] = 3;
01517 h->omsg[2] = 0;
01518 h->omsg[3] = cause;
01519 h->omsg[4] = 0;
01520 }
01521 sms_messagetx(h);
01522 break;
01523
01524 case 0x92:
01525 h->err = 1;
01526 sms_messagetx(h);
01527 break;
01528 case 0x93:
01529 sms_nextoutgoing (h);
01530 break;
01531 case 0x94:
01532 h->hangup = 1;
01533 break;
01534 case 0x95:
01535 sms_log(h, 'Y');
01536 sms_nextoutgoing (h);
01537 break;
01538 case 0x96:
01539 h->err = 1;
01540 sms_log(h, 'N');
01541 sms_nextoutgoing (h);
01542 break;
01543 default:
01544 h->omsg[0] = 0x92;
01545 h->omsg[1] = 1;
01546 h->omsg[2] = 3;
01547 sms_messagetx(h);
01548 break;
01549 }
01550 }
01551
01552 static void sms_messagetx(sms_t * h)
01553 {
01554 unsigned char c = 0, p;
01555 int len = h->omsg[1] + 2;
01556
01557 for (p = 0; p < len; p++) {
01558 c += h->omsg[p];
01559 }
01560 h->omsg[len] = 0 - c;
01561 sms_debug(DIR_TX, h);
01562 h->framenumber++;
01563 h->obytep = 0;
01564 h->obitp = 0;
01565 if (h->protocol == 2) {
01566 h->oseizure = 300;
01567 h->obyte = 0;
01568 if (h->omsg[0] == 0x7F) {
01569 h->opause = 8 * h->opause_0;
01570 } else {
01571 h->opause = 400;
01572 }
01573 } else {
01574 h->oseizure = 0;
01575 h->obyte = 1;
01576
01577
01578
01579
01580 if (h->omsg[0] == 0x93) {
01581 h->opause = 8 * h->opause_0;
01582 } else {
01583 h->opause = 200;
01584 }
01585 }
01586
01587 h->osync = OSYNC_BITS;
01588 h->obyten = len + 1;
01589 }
01590
01591
01592
01593
01594
01595 static int sms_generate(struct ast_channel *chan, void *data, int len, int samples)
01596 {
01597 struct ast_frame f = { 0 };
01598 #define MAXSAMPLES (800)
01599 output_t *buf;
01600 sms_t *h = data;
01601 int i;
01602
01603 if (samples > MAXSAMPLES) {
01604 ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n",
01605 MAXSAMPLES, samples);
01606 samples = MAXSAMPLES;
01607 }
01608 len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
01609 buf = alloca(len);
01610
01611 f.frametype = AST_FRAME_VOICE;
01612 f.subclass.codec = __OUT_FMT;
01613 f.datalen = samples * sizeof(*buf);
01614 f.offset = AST_FRIENDLY_OFFSET;
01615 f.mallocd = 0;
01616 f.data.ptr = buf;
01617 f.samples = samples;
01618 f.src = "app_sms";
01619
01620 for (i = 0; i < samples; i++) {
01621 buf[i] = wave_out[0];
01622
01623 if (h->opause) {
01624 h->opause--;
01625 } else if (h->obyten || h->osync) {
01626 buf[i] = wave_out[h->ophase];
01627 h->ophase += (h->obyte & 1) ? 13 : 21;
01628 if (h->ophase >= 80)
01629 h->ophase -= 80;
01630 if ((h->ophasep += 12) >= 80) {
01631 h->ophasep -= 80;
01632 if (h->oseizure > 0) {
01633 h->oseizure--;
01634 h->obyte ^= 1;
01635 } else if (h->osync) {
01636 h->obyte = 1;
01637 h->osync--;
01638 if (h->osync == 0 && h->protocol == 2 && h->omsg[0] == DLL2_SMS_EST) {
01639 h->obytep = h->obyten = 0;
01640 }
01641 } else {
01642 h->obitp++;
01643 if (h->obitp == 1) {
01644 h->obyte = 0;
01645 } else if (h->obitp == 2) {
01646 h->obyte = h->omsg[h->obytep];
01647 } else if (h->obitp == 10) {
01648 h->obyte = 1;
01649 h->obitp = 0;
01650 h->obytep++;
01651 if (h->obytep == h->obyten) {
01652 h->obytep = h->obyten = 0;
01653 h->osync = 10;
01654 }
01655 } else {
01656 h->obyte >>= 1;
01657 }
01658 }
01659 }
01660 }
01661 }
01662 if (ast_write(chan, &f) < 0) {
01663 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
01664 return -1;
01665 }
01666 return 0;
01667 #undef MAXSAMPLES
01668 }
01669
01670
01671
01672
01673 static void *sms_alloc(struct ast_channel *chan, void *sms_t_ptr)
01674 {
01675 return sms_t_ptr;
01676 }
01677
01678 static void sms_release(struct ast_channel *chan, void *data)
01679 {
01680 return;
01681 }
01682
01683 static struct ast_generator smsgen = {
01684 .alloc = sms_alloc,
01685 .release = sms_release,
01686 .generate = sms_generate,
01687 };
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 static void sms_process(sms_t * h, int samples, signed short *data)
01702 {
01703 int bit;
01704
01705
01706
01707
01708
01709
01710
01711
01712 if (h->obyten || h->osync) {
01713 return;
01714 }
01715 for ( ; samples-- ; data++) {
01716 unsigned long long m0, m1;
01717 if (abs(*data) > h->imag) {
01718 h->imag = abs(*data);
01719 } else {
01720 h->imag = h->imag * 7 / 8;
01721 }
01722 if (h->imag <= 500) {
01723 if (h->idle++ == 80000) {
01724 ast_log(LOG_NOTICE, "No data, hanging up\n");
01725 h->hangup = 1;
01726 h->err = 1;
01727 }
01728 if (h->ierr) {
01729 ast_log(LOG_NOTICE, "Error %d, hanging up\n", h->ierr);
01730
01731 h->err = 1;
01732 h->omsg[0] = 0x92;
01733 h->omsg[1] = 1;
01734 h->omsg[2] = h->ierr;
01735 sms_messagetx(h);
01736 }
01737 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01738 continue;
01739 }
01740 h->idle = 0;
01741
01742
01743 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
01744 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
01745 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
01746 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
01747
01748 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
01749 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
01750
01751
01752 if ((h->ips0 += 21) >= 80) {
01753 h->ips0 -= 80;
01754 }
01755 if ((h->ipc0 += 21) >= 80) {
01756 h->ipc0 -= 80;
01757 }
01758 if ((h->ips1 += 13) >= 80) {
01759 h->ips1 -= 80;
01760 }
01761 if ((h->ipc1 += 13) >= 80) {
01762 h->ipc1 -= 80;
01763 }
01764
01765
01766 h->ibith <<= 1;
01767 if (m1 > m0) {
01768 h->ibith |= 1;
01769 }
01770 if (h->ibith & 8) {
01771 h->ibitt--;
01772 }
01773 if (h->ibith & 1) {
01774 h->ibitt++;
01775 }
01776 bit = ((h->ibitt > 1) ? 1 : 0);
01777 if (bit != h->ibitl) {
01778 h->ibitc = 1;
01779 } else {
01780 h->ibitc++;
01781 }
01782 h->ibitl = bit;
01783 if (!h->ibitn && h->ibitc == 4 && !bit) {
01784 h->ibitn = 1;
01785 h->iphasep = 0;
01786 }
01787 if (bit && h->ibitc == 200) {
01788
01789 if (h->framenumber < 0 && h->ibytec >= 160 && !memcmp(h->imsg, "UUUUUUUUUUUUUUUUUUUU", 20)) {
01790 h->framenumber = 1;
01791 ast_verb(3, "SMS protocol 2 detected\n");
01792 h->protocol = 2;
01793 h->imsg[0] = 0xff;
01794 h->imsg[1] = h->imsg[2] = 0x00;
01795 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01796 sms_messagerx(h);
01797 }
01798 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0;
01799 }
01800 if (h->ibitn) {
01801 h->iphasep += 12;
01802 if (h->iphasep >= 80) {
01803 h->iphasep -= 80;
01804 if (h->ibitn++ == 9) {
01805 if (!bit) {
01806 if (h->sent_rel) {
01807 h->hangup = 1;
01808 } else {
01809 ast_log(LOG_NOTICE, "bad stop bit\n");
01810 h->ierr = 0xFF;
01811 }
01812 } else {
01813 if (h->ibytep < sizeof(h->imsg)) {
01814 h->imsg[h->ibytep] = h->ibytev;
01815 h->ibytec += h->ibytev;
01816 h->ibytep++;
01817 } else if (h->ibytep == sizeof(h->imsg)) {
01818 ast_log(LOG_NOTICE, "msg too large");
01819 h->ierr = 2;
01820 }
01821 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) {
01822 if (!h->ibytec) {
01823 sms_messagerx(h);
01824 } else {
01825 ast_log(LOG_NOTICE, "bad checksum");
01826 h->ierr = 1;
01827 }
01828 }
01829 }
01830 h->ibitn = 0;
01831 }
01832 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0);
01833 }
01834 }
01835 }
01836 }
01837
01838
01839
01840
01841
01842
01843
01844
01845 enum sms_flags {
01846 OPTION_BE_SMSC = (1 << 0),
01847 OPTION_ANSWER = (1 << 1),
01848 OPTION_TWO = (1 << 2),
01849 OPTION_PAUSE = (1 << 3),
01850 OPTION_SRR = (1 << 4),
01851 OPTION_DCS = (1 << 5),
01852 };
01853
01854 enum sms_opt_args {
01855 OPTION_ARG_PAUSE = 0,
01856 OPTION_ARG_ARRAY_SIZE
01857 };
01858
01859 AST_APP_OPTIONS(sms_options, {
01860 AST_APP_OPTION('s', OPTION_BE_SMSC),
01861 AST_APP_OPTION('a', OPTION_ANSWER),
01862 AST_APP_OPTION('t', OPTION_TWO),
01863 AST_APP_OPTION('r', OPTION_SRR),
01864 AST_APP_OPTION('o', OPTION_DCS),
01865 AST_APP_OPTION_ARG('p', OPTION_PAUSE, OPTION_ARG_PAUSE),
01866 } );
01867
01868 static int sms_exec(struct ast_channel *chan, const char *data)
01869 {
01870 int res = -1;
01871 sms_t h = { 0 };
01872
01873 struct ast_flags flags = { 0 };
01874 char *parse, *sms_opts[OPTION_ARG_ARRAY_SIZE] = { 0, };
01875 char *p;
01876 AST_DECLARE_APP_ARGS(sms_args,
01877 AST_APP_ARG(queue);
01878 AST_APP_ARG(options);
01879 AST_APP_ARG(addr);
01880 AST_APP_ARG(body);
01881 );
01882
01883 if (!data) {
01884 ast_log(LOG_ERROR, "Requires queue name at least\n");
01885 return -1;
01886 }
01887
01888 parse = ast_strdupa(data);
01889 AST_STANDARD_APP_ARGS(sms_args, parse);
01890 if (sms_args.argc > 1) {
01891 ast_app_parse_options(sms_options, &flags, sms_opts, sms_args.options);
01892 }
01893
01894 ast_verb(1, "sms argc %d queue <%s> opts <%s> addr <%s> body <%s>\n",
01895 sms_args.argc, S_OR(sms_args.queue, ""),
01896 S_OR(sms_args.options, ""),
01897 S_OR(sms_args.addr, ""),
01898 S_OR(sms_args.body, "") );
01899
01900 h.ipc0 = h.ipc1 = 20;
01901 h.dcs = 0xF1;
01902
01903 ast_copy_string(h.cli,
01904 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
01905 sizeof(h.cli));
01906
01907 if (ast_strlen_zero(sms_args.queue)) {
01908 ast_log(LOG_ERROR, "Requires queue name\n");
01909 goto done;
01910 }
01911 if (strlen(sms_args.queue) >= sizeof(h.queue)) {
01912 ast_log(LOG_ERROR, "Queue name too long\n");
01913 goto done;
01914 }
01915 ast_copy_string(h.queue, sms_args.queue, sizeof(h.queue));
01916
01917 for (p = h.queue; *p; p++) {
01918 if (!isalnum(*p)) {
01919 *p = '-';
01920 }
01921 }
01922
01923 h.smsc = ast_test_flag(&flags, OPTION_BE_SMSC);
01924 h.protocol = ast_test_flag(&flags, OPTION_TWO) ? 2 : 1;
01925 if (!ast_strlen_zero(sms_opts[OPTION_ARG_PAUSE])) {
01926 h.opause_0 = atoi(sms_opts[OPTION_ARG_PAUSE]);
01927 }
01928 if (h.opause_0 < 25 || h.opause_0 > 2000) {
01929 h.opause_0 = 300;
01930 }
01931 ast_verb(1, "initial delay %dms\n", h.opause_0);
01932
01933
01934
01935 if (ast_test_flag(&flags, OPTION_SRR)) {
01936 h.srr = 1;
01937 }
01938 if (ast_test_flag(&flags, OPTION_DCS)) {
01939 h.dcs = 1;
01940 }
01941 #if 0
01942 case '1':
01943 case '2':
01944 case '3':
01945 case '4':
01946 case '5':
01947 case '6':
01948 case '7':
01949 h.pid = 0x40 + (*d & 0xF);
01950 break;
01951 }
01952 #endif
01953 if (sms_args.argc > 2) {
01954 unsigned char *up;
01955
01956
01957
01958 h.scts = ast_tvnow();
01959 if (ast_strlen_zero(sms_args.addr) || strlen(sms_args.addr) >= sizeof(h.oa)) {
01960 ast_log(LOG_ERROR, "Address too long %s\n", sms_args.addr);
01961 goto done;
01962 }
01963 if (h.smsc) {
01964 ast_copy_string(h.oa, sms_args.addr, sizeof(h.oa));
01965 } else {
01966 ast_copy_string(h.da, sms_args.addr, sizeof(h.da));
01967 ast_copy_string(h.oa, h.cli, sizeof(h.oa));
01968 }
01969 h.udl = 0;
01970 if (ast_strlen_zero(sms_args.body)) {
01971 ast_log(LOG_ERROR, "Missing body for %s\n", sms_args.addr);
01972 goto done;
01973 }
01974 up = (unsigned char *)sms_args.body;
01975 while (*up && h.udl < SMSLEN) {
01976 h.ud[h.udl++] = utf8decode(&up);
01977 }
01978 if (is7bit(h.dcs) && packsms7(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01979 ast_log(LOG_WARNING, "Invalid 7 bit GSM data\n");
01980 goto done;
01981 }
01982 if (is8bit(h.dcs) && packsms8(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01983 ast_log(LOG_WARNING, "Invalid 8 bit data\n");
01984 goto done;
01985 }
01986 if (is16bit(h.dcs) && packsms16(0, h.udhl, h.udh, h.udl, h.ud) < 0) {
01987 ast_log(LOG_WARNING, "Invalid 16 bit data\n");
01988 goto done;
01989 }
01990 h.rx = 0;
01991 h.mr = -1;
01992 sms_writefile(&h);
01993 res = h.err;
01994 goto done;
01995 }
01996
01997 if (chan->_state != AST_STATE_UP) {
01998 ast_answer(chan);
01999 }
02000
02001 if (ast_test_flag(&flags, OPTION_ANSWER)) {
02002 h.framenumber = 1;
02003
02004 if (h.protocol == 2) {
02005 h.omsg[0] = DLL2_SMS_EST;
02006 h.omsg[1] = 0;
02007 } else {
02008 h.omsg[0] = DLL1_SMS_EST | DLL1_SMS_COMPLETE;
02009 h.omsg[1] = 0;
02010 }
02011 sms_messagetx(&h);
02012 }
02013
02014 res = ast_set_write_format(chan, __OUT_FMT);
02015 if (res >= 0) {
02016 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
02017 }
02018 if (res < 0) {
02019 ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");
02020 goto done;
02021 }
02022
02023 if ( (res = ast_activate_generator(chan, &smsgen, &h)) < 0) {
02024 ast_log(LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name);
02025 goto done;
02026 }
02027
02028
02029 for (;;) {
02030 struct ast_frame *f;
02031 int i = ast_waitfor(chan, -1);
02032 if (i < 0) {
02033 ast_log(LOG_NOTICE, "waitfor failed\n");
02034 break;
02035 }
02036 if (h.hangup) {
02037 ast_log(LOG_NOTICE, "channel hangup\n");
02038 break;
02039 }
02040 f = ast_read(chan);
02041 if (!f) {
02042 ast_log(LOG_NOTICE, "ast_read failed\n");
02043 break;
02044 }
02045 if (f->frametype == AST_FRAME_VOICE) {
02046 sms_process(&h, f->samples, f->data.ptr);
02047 }
02048
02049 ast_frfree(f);
02050 }
02051 res = h.err;
02052
02053
02054
02055
02056
02057 ast_deactivate_generator(chan);
02058
02059 sms_log(&h, '?');
02060 done:
02061 return (res);
02062 }
02063
02064 static int unload_module(void)
02065 {
02066 return ast_unregister_application(app);
02067 }
02068
02069 static int load_module(void)
02070 {
02071 #ifdef OUTALAW
02072 int p;
02073 for (p = 0; p < 80; p++) {
02074 wavea[p] = AST_LIN2A(wave[p]);
02075 }
02076 #endif
02077 snprintf(log_file, sizeof(log_file), "%s/sms", ast_config_AST_LOG_DIR);
02078 return ast_register_application_xml(app, sms_exec);
02079 }
02080
02081 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SMS/PSTN handler");