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