#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
Include dependency graph for app_sms.c:
Go to the source code of this file.
Data Structures | |
struct | sms_s |
Defines | |
#define | is16bit(dcs) (((dcs)&0xC0)?0:(((dcs)&12)==8)) |
#define | is7bit(dcs) (((dcs)&0xC0)?(!((dcs)&4)):(!((dcs)&12))) |
#define | is8bit(dcs) (((dcs)&0xC0)?(((dcs)&4)):(((dcs)&12)==4)) |
#define | SMSLEN 160 |
Typedefs | |
typedef sms_s | sms_t |
Functions | |
char * | description (void) |
Provides a description of the module. | |
static char * | isodate (time_t t) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static void | numcpy (char *d, char *s) |
static unsigned char | packaddress (unsigned char *o, char *i) |
static void | packdate (unsigned char *o, time_t w) |
static int | packsms (unsigned char dcs, unsigned char *base, unsigned int udhl, unsigned char *udh, int udl, unsigned short *ud) |
static int | packsms16 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud) |
static int | packsms7 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud) |
static int | packsms8 (unsigned char *o, int udhl, unsigned char *udh, int udl, unsigned short *ud) |
static struct dirent * | readdirqueue (DIR *d, char *queue) |
static void * | sms_alloc (struct ast_channel *chan, void *params) |
static void | sms_debug (char *dir, unsigned char *msg) |
static int | sms_exec (struct ast_channel *chan, void *data) |
static int | sms_generate (struct ast_channel *chan, void *data, int len, int samples) |
static unsigned char | sms_handleincoming (sms_t *h) |
static void | sms_log (sms_t *h, char status) |
static void | sms_messagerx (sms_t *h) |
static void | sms_messagetx (sms_t *h) |
static void | sms_nextoutgoing (sms_t *h) |
static void | sms_process (sms_t *h, int samples, signed short *data) |
static void | sms_readfile (sms_t *h, char *fn) |
static void | sms_release (struct ast_channel *chan, void *data) |
static void | sms_writefile (sms_t *h) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
static unsigned char | unpackaddress (char *o, unsigned char *i) |
static time_t | unpackdate (unsigned char *i) |
static int | unpacksms (unsigned char dcs, unsigned char *i, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi) |
static void | unpacksms16 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi) |
static void | unpacksms7 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi) |
static void | unpacksms8 (unsigned char *i, unsigned char l, unsigned char *udh, int *udhl, unsigned short *ud, int *udl, char udhi) |
int | usecount (void) |
Provides a usecount. | |
static long | utf8decode (unsigned char **pp) |
Variables | |
static char * | app = "SMS" |
static const unsigned short | defaultalphabet [] |
static char * | descrip |
static const unsigned short | escapes [] |
LOCAL_USER_DECL | |
static char | log_file [255] |
static volatile unsigned char | message_ref |
static volatile unsigned int | seq |
static struct ast_generator | smsgen |
static char | spool_dir [255] |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Communicates with SMS service centres and SMS capable analogue phones" |
static char * | tdesc = "SMS/PSTN handler" |
static signed short | wave [] |
Definition in file app_sms.c.
|
|
|
Definition at line 184 of file app_sms.c. Referenced by packsms(), and unpacksms(). |
|
Definition at line 185 of file app_sms.c. Referenced by packsms(), and unpacksms(). |
|
Definition at line 126 of file app_sms.c. Referenced by packsms7(), and sms_readfile(). |
|
|
|
Provides a description of the module.
Definition at line 1540 of file app_sms.c. References tdesc. 01541 { 01542 return tdesc; 01543 }
|
|
Definition at line 214 of file app_sms.c. Referenced by sms_log(), and sms_writefile(). 00215 { 00216 static char date[20]; 00217 strftime (date, sizeof (date), "%Y-%m-%dT%H:%M:%S", localtime (&t)); 00218 return date; 00219 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 1552 of file app_sms.c. References ASTERISK_GPL_KEY. 01553 { 01554 return ASTERISK_GPL_KEY; 01555 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 1526 of file app_sms.c. References app, ast_config_AST_LOG_DIR, ast_config_AST_SPOOL_DIR, AST_LIN2A, ast_register_application(), descrip, log_file, sms_exec(), spool_dir, synopsis, and wave. 01527 { 01528 #ifdef OUTALAW 01529 { 01530 int p; 01531 for (p = 0; p < 80; p++) 01532 wavea[p] = AST_LIN2A (wave[p]); 01533 } 01534 #endif 01535 snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR); 01536 snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR); 01537 return ast_register_application (app, sms_exec, synopsis, descrip); 01538 }
|
|
Definition at line 201 of file app_sms.c. Referenced by sms_readfile(). 00202 { 00203 if (*s == '+') 00204 *d++ = *s++; 00205 while (*s) { 00206 if (isdigit (*s)) 00207 *d++ = *s; 00208 s++; 00209 } 00210 *d = 0; 00211 }
|
|
Definition at line 614 of file app_sms.c. Referenced by sms_nextoutgoing(). 00615 { 00616 unsigned char p = 2; 00617 o[0] = 0; 00618 if (*i == '+') { 00619 i++; 00620 o[1] = 0x91; 00621 } else 00622 o[1] = 0x81; 00623 while (*i) 00624 if (isdigit (*i)) { 00625 if (o[0] & 1) 00626 o[p++] |= ((*i & 0xF) << 4); 00627 else 00628 o[p] = (*i & 0xF); 00629 o[0]++; 00630 i++; 00631 } else 00632 i++; 00633 if (o[0] & 1) 00634 o[p++] |= 0xF0; /* pad */ 00635 return p; 00636 }
|
|
Definition at line 439 of file app_sms.c. References t. Referenced by sms_nextoutgoing(). 00440 { 00441 struct tm *t = localtime (&w); 00442 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) 00443 int z = -t->tm_gmtoff / 60 / 15; 00444 #else 00445 int z = timezone / 60 / 15; 00446 #endif 00447 *o++ = ((t->tm_year % 10) << 4) + (t->tm_year % 100) / 10; 00448 *o++ = (((t->tm_mon + 1) % 10) << 4) + (t->tm_mon + 1) / 10; 00449 *o++ = ((t->tm_mday % 10) << 4) + t->tm_mday / 10; 00450 *o++ = ((t->tm_hour % 10) << 4) + t->tm_hour / 10; 00451 *o++ = ((t->tm_min % 10) << 4) + t->tm_min / 10; 00452 *o++ = ((t->tm_sec % 10) << 4) + t->tm_sec / 10; 00453 if (z < 0) 00454 *o++ = (((-z) % 10) << 4) + (-z) / 10 + 0x08; 00455 else 00456 *o++ = ((z % 10) << 4) + z / 10; 00457 }
|
|
Definition at line 408 of file app_sms.c. References is7bit, is8bit, packsms16(), packsms7(), and packsms8(). Referenced by sms_nextoutgoing(). 00409 { 00410 unsigned char *p = base; 00411 if (udl) { 00412 int l = 0; 00413 if (is7bit (dcs)) { /* 7 bit */ 00414 l = packsms7 (p + 1, udhl, udh, udl, ud); 00415 if (l < 0) 00416 l = 0; 00417 *p++ = l; 00418 p += (l * 7 + 7) / 8; 00419 } else if (is8bit (dcs)) { /* 8 bit */ 00420 l = packsms8 (p + 1, udhl, udh, udl, ud); 00421 if (l < 0) 00422 l = 0; 00423 *p++ = l; 00424 p += l; 00425 } else { /* UCS-2 */ 00426 l = packsms16 (p + 1, udhl, udh, udl, ud); 00427 if (l < 0) 00428 l = 0; 00429 *p++ = l; 00430 p += l; 00431 } 00432 } else 00433 *p++ = 0; /* no user data */ 00434 return p - base; 00435 }
|
|
Definition at line 377 of file app_sms.c. Referenced by packsms(). 00378 { 00379 unsigned char p = 0; 00380 /* header - no encoding */ 00381 if (udhl) { 00382 if (o) 00383 o[p++] = udhl; 00384 while (udhl--) { 00385 if (o) 00386 o[p++] = *udh++; 00387 if (p >= 140) 00388 return p; 00389 } 00390 } 00391 while (udl--) { 00392 long u; 00393 u = *ud++; 00394 if (o) 00395 o[p++] = (u >> 8); 00396 if (p >= 140) 00397 return p - 1; /* could not fit last character */ 00398 if (o) 00399 o[p++] = u; 00400 if (p >= 140) 00401 return p; 00402 } 00403 return p; 00404 }
|
|
Definition at line 271 of file app_sms.c. Referenced by packsms(). 00272 { 00273 unsigned char p = 0, b = 0, n = 0; 00274 00275 if (udhl) { /* header */ 00276 if (o) 00277 o[p++] = udhl; 00278 b = 1; 00279 n = 1; 00280 while (udhl--) { 00281 if (o) 00282 o[p++] = *udh++; 00283 b += 8; 00284 while (b >= 7) { 00285 b -= 7; 00286 n++; 00287 } 00288 if (n >= SMSLEN) 00289 return n; 00290 } 00291 if (b) { 00292 b = 7 - b; 00293 if (++n >= SMSLEN) 00294 return n; 00295 }; /* filling to septet boundary */ 00296 } 00297 if (o) 00298 o[p] = 0; 00299 /* message */ 00300 while (udl--) { 00301 long u; 00302 unsigned char v; 00303 u = *ud++; 00304 for (v = 0; v < 128 && defaultalphabet[v] != u; v++); 00305 if (v == 128 && u && n + 1 < SMSLEN) { 00306 for (v = 0; v < 128 && escapes[v] != u; v++); 00307 if (v < 128) { /* escaped sequence */ 00308 if (o) 00309 o[p] |= (27 << b); 00310 b += 7; 00311 if (b >= 8) { 00312 b -= 8; 00313 p++; 00314 if (o) 00315 o[p] = (27 >> (7 - b)); 00316 } 00317 n++; 00318 } 00319 } 00320 if (v == 128) 00321 return -1; /* invalid character */ 00322 if (o) 00323 o[p] |= (v << b); 00324 b += 7; 00325 if (b >= 8) { 00326 b -= 8; 00327 p++; 00328 if (o) 00329 o[p] = (v >> (7 - b)); 00330 } 00331 if (++n >= SMSLEN) 00332 return n; 00333 } 00334 return n; 00335 }
|
|
Definition at line 341 of file app_sms.c. Referenced by packsms(). 00342 { 00343 unsigned char p = 0; 00344 00345 /* header - no encoding */ 00346 if (udhl) { 00347 if (o) 00348 o[p++] = udhl; 00349 while (udhl--) { 00350 if (o) 00351 o[p++] = *udh++; 00352 if (p >= 140) 00353 return p; 00354 } 00355 } 00356 while (udl--) { 00357 long u; 00358 u = *ud++; 00359 if (u < 0 || u > 0xFF) 00360 return -1; /* not valid */ 00361 if (o) 00362 o[p++] = u; 00363 if (p >= 140) 00364 return p; 00365 } 00366 return p; 00367 }
|
|
Definition at line 946 of file app_sms.c. Referenced by sms_nextoutgoing(). 00947 { 00948 struct dirent *f; 00949 do { 00950 f = readdir (d); 00951 } while (f && (*f->d_name == '.' || strncmp (f->d_name, queue, strlen (queue)) || f->d_name[strlen (queue)] != '.')); 00952 return f; 00953 }
|
|
Definition at line 188 of file app_sms.c.
|
|
Definition at line 1092 of file app_sms.c. References ast_verbose(), n, option_verbose, and VERBOSE_PREFIX_3. Referenced by sms_messagerx(), and sms_messagetx(). 01093 { 01094 char txt[259 * 3 + 1], 01095 *p = txt; /* always long enough */ 01096 int n = msg[1] + 3, 01097 q = 0; 01098 while (q < n && q < 30) { 01099 sprintf (p, " %02X", msg[q++]); 01100 p += 3; 01101 } 01102 if (q < n) 01103 sprintf (p, "..."); 01104 if (option_verbose > 2) 01105 ast_verbose (VERBOSE_PREFIX_3 "SMS %s%s\n", dir, txt); 01106 }
|
|
Definition at line 1361 of file app_sms.c. References answer, ast_log(), ast_channel::cid, ast_callerid::cid_num, sms_s::cli, sms_s::dcs, sms_s::ipc0, sms_s::ipc1, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, sms_s::oa, sms_s::pid, sms_s::queue, sms_s::scts, sms_s::smsc, and sms_s::srr. Referenced by load_module(). 01362 { 01363 int res = -1; 01364 struct localuser *u; 01365 struct ast_frame *f; 01366 sms_t h = { 0 }; 01367 01368 LOCAL_USER_ADD(u); 01369 01370 h.ipc0 = h.ipc1 = 20; /* phase for cosine */ 01371 h.dcs = 0xF1; /* default */ 01372 if (!data) { 01373 ast_log (LOG_ERROR, "Requires queue name at least\n"); 01374 LOCAL_USER_REMOVE(u); 01375 return -1; 01376 } 01377 01378 if (chan->cid.cid_num) 01379 ast_copy_string (h.cli, chan->cid.cid_num, sizeof (h.cli)); 01380 01381 { 01382 unsigned char *p; 01383 unsigned char *d = data, 01384 answer = 0; 01385 if (!*d || *d == '|') { 01386 ast_log (LOG_ERROR, "Requires queue name\n"); 01387 LOCAL_USER_REMOVE(u); 01388 return -1; 01389 } 01390 for (p = d; *p && *p != '|'; p++); 01391 if (p - d >= sizeof (h.queue)) { 01392 ast_log (LOG_ERROR, "Queue name too long\n"); 01393 LOCAL_USER_REMOVE(u); 01394 return -1; 01395 } 01396 strncpy (h.queue, d, p - d); 01397 if (*p == '|') 01398 p++; 01399 d = p; 01400 for (p = h.queue; *p; p++) 01401 if (!isalnum (*p)) 01402 *p = '-'; /* make very safe for filenames */ 01403 while (*d && *d != '|') { 01404 switch (*d) { 01405 case 'a': /* we have to send the initial FSK sequence */ 01406 answer = 1; 01407 break; 01408 case 's': /* we are acting as a service centre talking to a phone */ 01409 h.smsc = 1; 01410 break; 01411 /* the following apply if there is an arg3/4 and apply to the created message file */ 01412 case 'r': 01413 h.srr = 1; 01414 break; 01415 case 'o': 01416 h.dcs |= 4; /* octets */ 01417 break; 01418 case '1': 01419 case '2': 01420 case '3': 01421 case '4': 01422 case '5': 01423 case '6': 01424 case '7': /* set the pid for saved local message */ 01425 h.pid = 0x40 + (*d & 0xF); 01426 break; 01427 } 01428 d++; 01429 } 01430 if (*d == '|') { 01431 /* submitting a message, not taking call. */ 01432 /* depricated, use smsq instead */ 01433 d++; 01434 h.scts = time (0); 01435 for (p = d; *p && *p != '|'; p++); 01436 if (*p) 01437 *p++ = 0; 01438 if (strlen (d) >= sizeof (h.oa)) { 01439 ast_log (LOG_ERROR, "Address too long %s\n", d); 01440 return 0; 01441 } 01442 if (h.smsc) { 01443 ast_copy_string (h.oa, d, sizeof (h.oa)); 01444 } else { 01445 ast_copy_string (h.da, d, sizeof (h.da)); 01446 } 01447 if (!h.smsc) 01448 ast_copy_string (h.oa, h.cli, sizeof (h.oa)); 01449 d = p; 01450 h.udl = 0; 01451 while (*p && h.udl < SMSLEN) 01452 h.ud[h.udl++] = utf8decode(&p); 01453 if (is7bit (h.dcs) && packsms7 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01454 ast_log (LOG_WARNING, "Invalid 7 bit GSM data\n"); 01455 if (is8bit (h.dcs) && packsms8 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01456 ast_log (LOG_WARNING, "Invalid 8 bit data\n"); 01457 if (is16bit (h.dcs) && packsms16 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01458 ast_log (LOG_WARNING, "Invalid 16 bit data\n"); 01459 h.rx = 0; /* sent message */ 01460 h.mr = -1; 01461 sms_writefile (&h); 01462 LOCAL_USER_REMOVE(u); 01463 return 0; 01464 } 01465 01466 if (answer) { 01467 /* set up SMS_EST initial message */ 01468 h.omsg[0] = 0x93; 01469 h.omsg[1] = 0; 01470 sms_messagetx (&h); 01471 } 01472 } 01473 01474 if (chan->_state != AST_STATE_UP) 01475 ast_answer (chan); 01476 01477 #ifdef OUTALAW 01478 res = ast_set_write_format (chan, AST_FORMAT_ALAW); 01479 #else 01480 res = ast_set_write_format (chan, AST_FORMAT_SLINEAR); 01481 #endif 01482 if (res >= 0) 01483 res = ast_set_read_format (chan, AST_FORMAT_SLINEAR); 01484 if (res < 0) { 01485 ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n"); 01486 LOCAL_USER_REMOVE (u); 01487 return -1; 01488 } 01489 01490 if (ast_activate_generator (chan, &smsgen, &h) < 0) { 01491 ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name); 01492 LOCAL_USER_REMOVE (u); 01493 return -1; 01494 } 01495 01496 /* Do our thing here */ 01497 while (ast_waitfor (chan, -1) > -1 && !h.hangup) 01498 { 01499 f = ast_read (chan); 01500 if (!f) 01501 break; 01502 if (f->frametype == AST_FRAME_VOICE) { 01503 sms_process (&h, f->samples, f->data); 01504 } 01505 01506 ast_frfree (f); 01507 } 01508 01509 sms_log (&h, '?'); /* log incomplete message */ 01510 01511 LOCAL_USER_REMOVE (u); 01512 return (h.err); 01513 }
|
|
Definition at line 1178 of file app_sms.c. References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::mallocd, sms_s::obitp, sms_s::obyte, sms_s::obyten, sms_s::obytep, ast_frame::offset, sms_s::omsg, sms_s::opause, sms_s::ophase, sms_s::ophasep, sms_s::osync, ast_frame::samples, ast_frame::src, ast_frame::subclass, and wave. 01179 { 01180 struct ast_frame f = { 0 }; 01181 unsigned char waste[AST_FRIENDLY_OFFSET]; 01182 #ifdef OUTALAW 01183 unsigned char buf[800]; 01184 #else 01185 signed short buf[800]; 01186 #endif 01187 sms_t *h = data; 01188 int i; 01189 01190 if (len > sizeof (buf)) { 01191 ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len); 01192 len = sizeof (buf); 01193 #ifdef OUTALAW 01194 samples = len; 01195 #else 01196 samples = len / 2; 01197 #endif 01198 } 01199 waste[0] = 0; /* make compiler happy */ 01200 f.frametype = AST_FRAME_VOICE; 01201 #ifdef OUTALAW 01202 f.subclass = AST_FORMAT_ALAW; 01203 f.datalen = samples; 01204 #else 01205 f.subclass = AST_FORMAT_SLINEAR; 01206 f.datalen = samples * 2; 01207 #endif 01208 f.offset = AST_FRIENDLY_OFFSET; 01209 f.mallocd = 0; 01210 f.data = buf; 01211 f.samples = samples; 01212 f.src = "app_sms"; 01213 /* create a buffer containing the digital sms pattern */ 01214 for (i = 0; i < samples; i++) { 01215 #ifdef OUTALAW 01216 buf[i] = wavea[0]; 01217 #else 01218 buf[i] = wave[0]; 01219 #endif 01220 if (h->opause) 01221 h->opause--; 01222 else if (h->obyten || h->osync) { /* sending data */ 01223 #ifdef OUTALAW 01224 buf[i] = wavea[h->ophase]; 01225 #else 01226 buf[i] = wave[h->ophase]; 01227 #endif 01228 if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80) 01229 h->ophase -= 80; 01230 if ((h->ophasep += 12) >= 80) { /* next bit */ 01231 h->ophasep -= 80; 01232 if (h->osync) 01233 h->osync--; /* sending sync bits */ 01234 else { 01235 h->obyte >>= 1; 01236 h->obitp++; 01237 if (h->obitp == 1) 01238 h->obyte = 0; /* start bit; */ 01239 else if (h->obitp == 2) 01240 h->obyte = h->omsg[h->obytep]; 01241 else if (h->obitp == 10) { 01242 h->obyte = 1; /* stop bit */ 01243 h->obitp = 0; 01244 h->obytep++; 01245 if (h->obytep == h->obyten) { 01246 h->obytep = h->obyten = 0; /* sent */ 01247 h->osync = 10; /* trailing marks */ 01248 } 01249 } 01250 } 01251 } 01252 } 01253 } 01254 if (ast_write (chan, &f) < 0) { 01255 ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno)); 01256 return -1; 01257 } 01258 return 0; 01259 }
|
|
Definition at line 956 of file app_sms.c. References ast_log(), sms_s::cli, sms_s::da, sms_s::dcs, sms_s::imsg, LOG_WARNING, sms_s::mr, sms_s::oa, sms_s::pid, sms_s::rp, sms_s::rx, sms_s::scts, sms_writefile(), sms_s::smsc, sms_s::srr, sms_s::ud, sms_s::udh, sms_s::udhi, sms_s::udhl, sms_s::udl, unpackaddress(), unpackdate(), unpacksms(), and sms_s::vp. Referenced by sms_messagerx(). 00957 { 00958 unsigned char p = 3; 00959 if (h->smsc) { /* SMSC */ 00960 if ((h->imsg[2] & 3) == 1) { /* SMS-SUBMIT */ 00961 h->udhl = h->udl = 0; 00962 h->vp = 0; 00963 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0); 00964 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0); 00965 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0); 00966 ast_copy_string (h->oa, h->cli, sizeof (h->oa)); 00967 h->scts = time (0); 00968 h->mr = h->imsg[p++]; 00969 p += unpackaddress (h->da, h->imsg + p); 00970 h->pid = h->imsg[p++]; 00971 h->dcs = h->imsg[p++]; 00972 if ((h->imsg[2] & 0x18) == 0x10) { /* relative VP */ 00973 if (h->imsg[p] < 144) 00974 h->vp = (h->imsg[p] + 1) * 5; 00975 else if (h->imsg[p] < 168) 00976 h->vp = 720 + (h->imsg[p] - 143) * 30; 00977 else if (h->imsg[p] < 197) 00978 h->vp = (h->imsg[p] - 166) * 1440; 00979 else 00980 h->vp = (h->imsg[p] - 192) * 10080; 00981 p++; 00982 } else if (h->imsg[2] & 0x18) 00983 p += 7; /* ignore enhanced / absolute VP */ 00984 p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi); 00985 h->rx = 1; /* received message */ 00986 sms_writefile (h); /* write the file */ 00987 if (p != h->imsg[1] + 2) { 00988 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2); 00989 return 0xFF; /* duh! */ 00990 } 00991 } else { 00992 ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]); 00993 return 0xFF; 00994 } 00995 } else { /* client */ 00996 if (!(h->imsg[2] & 3)) { /* SMS-DELIVER */ 00997 *h->da = h->srr = h->rp = h->vp = h->udhi = h->udhl = h->udl = 0; 00998 h->srr = ((h->imsg[2] & 0x20) ? 1 : 0); 00999 h->udhi = ((h->imsg[2] & 0x40) ? 1 : 0); 01000 h->rp = ((h->imsg[2] & 0x80) ? 1 : 0); 01001 h->mr = -1; 01002 p += unpackaddress (h->oa, h->imsg + p); 01003 h->pid = h->imsg[p++]; 01004 h->dcs = h->imsg[p++]; 01005 h->scts = unpackdate (h->imsg + p); 01006 p += 7; 01007 p += unpacksms (h->dcs, h->imsg + p, h->udh, &h->udhl, h->ud, &h->udl, h->udhi); 01008 h->rx = 1; /* received message */ 01009 sms_writefile (h); /* write the file */ 01010 if (p != h->imsg[1] + 2) { 01011 ast_log (LOG_WARNING, "Mismatch receive unpacking %d/%d\n", p, h->imsg[1] + 2); 01012 return 0xFF; /* duh! */ 01013 } 01014 } else { 01015 ast_log (LOG_WARNING, "Unknown message type %02X\n", h->imsg[2]); 01016 return 0xFF; 01017 } 01018 } 01019 return 0; /* no error */ 01020 }
|
|
Definition at line 639 of file app_sms.c. References sms_s::da, isodate(), log_file, sms_s::mr, n, sms_s::oa, sms_s::queue, sms_s::rx, sms_s::smsc, sms_s::ud, and sms_s::udl. Referenced by sms_messagerx(). 00640 { 00641 if (*h->oa || *h->da) { 00642 int o = open (log_file, O_CREAT | O_APPEND | O_WRONLY, 0666); 00643 if (o >= 0) { 00644 char line[1000], mrs[3] = "", *p; 00645 unsigned char n; 00646 00647 if (h->mr >= 0) 00648 snprintf (mrs, sizeof (mrs), "%02X", h->mr); 00649 snprintf (line, sizeof (line), "%s %c%c%c%s %s %s %s ", 00650 isodate (time (0)), status, h->rx ? 'I' : 'O', h->smsc ? 'S' : 'M', mrs, h->queue, *h->oa ? h->oa : "-", 00651 *h->da ? h->da : "-"); 00652 p = line + strlen (line); 00653 for (n = 0; n < h->udl; n++) 00654 if (h->ud[n] == '\\') { 00655 *p++ = '\\'; 00656 *p++ = '\\'; 00657 } else if (h->ud[n] == '\n') { 00658 *p++ = '\\'; 00659 *p++ = 'n'; 00660 } else if (h->ud[n] == '\r') { 00661 *p++ = '\\'; 00662 *p++ = 'r'; 00663 } else if (h->ud[n] < 32 || h->ud[n] == 127) 00664 *p++ = 191; 00665 else 00666 *p++ = h->ud[n]; 00667 *p++ = '\n'; 00668 *p = 0; 00669 write (o, line, strlen (line)); 00670 close (o); 00671 } 00672 *h->oa = *h->da = h->udl = 0; 00673 } 00674 }
|
|
Definition at line 1108 of file app_sms.c. References sms_s::err, sms_s::hangup, sms_s::imsg, sms_s::omsg, sms_debug(), sms_handleincoming(), sms_log(), sms_messagetx(), and sms_nextoutgoing(). Referenced by sms_process(). 01109 { 01110 sms_debug ("RX", h->imsg); 01111 /* testing */ 01112 switch (h->imsg[0]) { 01113 case 0x91: /* SMS_DATA */ 01114 { 01115 unsigned char cause = sms_handleincoming (h); 01116 if (!cause) { 01117 sms_log (h, 'Y'); 01118 h->omsg[0] = 0x95; /* SMS_ACK */ 01119 h->omsg[1] = 0x02; 01120 h->omsg[2] = 0x00; /* deliver report */ 01121 h->omsg[3] = 0x00; /* no parameters */ 01122 } else { /* NACK */ 01123 sms_log (h, 'N'); 01124 h->omsg[0] = 0x96; /* SMS_NACK */ 01125 h->omsg[1] = 3; 01126 h->omsg[2] = 0; /* delivery report */ 01127 h->omsg[3] = cause; /* cause */ 01128 h->omsg[4] = 0; /* no parameters */ 01129 } 01130 sms_messagetx (h); 01131 } 01132 break; 01133 case 0x92: /* SMS_ERROR */ 01134 h->err = 1; 01135 sms_messagetx (h); /* send whatever we sent again */ 01136 break; 01137 case 0x93: /* SMS_EST */ 01138 sms_nextoutgoing (h); 01139 break; 01140 case 0x94: /* SMS_REL */ 01141 h->hangup = 1; /* hangup */ 01142 break; 01143 case 0x95: /* SMS_ACK */ 01144 sms_log (h, 'Y'); 01145 sms_nextoutgoing (h); 01146 break; 01147 case 0x96: /* SMS_NACK */ 01148 h->err = 1; 01149 sms_log (h, 'N'); 01150 sms_nextoutgoing (h); 01151 break; 01152 default: /* Unknown */ 01153 h->omsg[0] = 0x92; /* SMS_ERROR */ 01154 h->omsg[1] = 1; 01155 h->omsg[2] = 3; /* unknown message type; */ 01156 sms_messagetx (h); 01157 break; 01158 } 01159 }
|
|
Definition at line 1161 of file app_sms.c. References sms_s::obitp, sms_s::obyte, sms_s::obyten, sms_s::obytep, sms_s::omsg, sms_s::opause, sms_s::osync, and sms_debug(). Referenced by sms_messagerx(), sms_nextoutgoing(), and sms_process(). 01162 { 01163 unsigned char c = 0, p; 01164 for (p = 0; p < h->omsg[1] + 2; p++) 01165 c += h->omsg[p]; 01166 h->omsg[h->omsg[1] + 2] = 0 - c; 01167 sms_debug ("TX", h->omsg); 01168 h->obyte = 1; 01169 h->opause = 200; 01170 if (h->omsg[0] == 0x93) 01171 h->opause = 2400; /* initial message delay 300ms (for BT) */ 01172 h->obytep = 0; 01173 h->obitp = 0; 01174 h->osync = 80; 01175 h->obyten = h->omsg[1] + 3; 01176 }
|
|
Definition at line 1028 of file app_sms.c. References sms_s::da, sms_s::dcs, message_ref, sms_s::mr, sms_s::oa, sms_s::omsg, packaddress(), packdate(), packsms(), sms_s::pid, sms_s::queue, readdirqueue(), sms_s::rp, sms_s::rx, sms_s::scts, sms_messagetx(), sms_readfile(), sms_s::smsc, spool_dir, sms_s::srr, sms_s::ud, sms_s::udh, sms_s::udhi, sms_s::udhl, sms_s::udl, and sms_s::vp. Referenced by sms_messagerx(). 01029 { 01030 char fn[100 + NAME_MAX] = ""; 01031 DIR *d; 01032 char more = 0; 01033 ast_copy_string (fn, spool_dir, sizeof (fn)); 01034 mkdir (fn, 0777); /* ensure it exists */ 01035 h->rx = 0; /* outgoing message */ 01036 snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx"); 01037 mkdir (fn, 0777); /* ensure it exists */ 01038 d = opendir (fn); 01039 if (d) { 01040 struct dirent *f = readdirqueue (d, h->queue); 01041 if (f) { 01042 snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", f->d_name); 01043 sms_readfile (h, fn); 01044 if (readdirqueue (d, h->queue)) 01045 more = 1; /* more to send */ 01046 } 01047 closedir (d); 01048 } 01049 if (*h->da || *h->oa) { /* message to send */ 01050 unsigned char p = 2; 01051 h->omsg[0] = 0x91; /* SMS_DATA */ 01052 if (h->smsc) { /* deliver */ 01053 h->omsg[p++] = (more ? 4 : 0); 01054 p += packaddress (h->omsg + p, h->oa); 01055 h->omsg[p++] = h->pid; 01056 h->omsg[p++] = h->dcs; 01057 packdate (h->omsg + p, h->scts); 01058 p += 7; 01059 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud); 01060 } else { /* submit */ 01061 h->omsg[p++] = 01062 0x01 + (more ? 4 : 0) + (h->srr ? 0x20 : 0) + (h->rp ? 0x80 : 0) + (h->vp ? 0x10 : 0) + (h->udhi ? 0x40 : 0); 01063 if (h->mr < 0) 01064 h->mr = message_ref++; 01065 h->omsg[p++] = h->mr; 01066 p += packaddress (h->omsg + p, h->da); 01067 h->omsg[p++] = h->pid; 01068 h->omsg[p++] = h->dcs; 01069 if (h->vp) { /* relative VP */ 01070 if (h->vp < 720) 01071 h->omsg[p++] = (h->vp + 4) / 5 - 1; 01072 else if (h->vp < 1440) 01073 h->omsg[p++] = (h->vp - 720 + 29) / 30 + 143; 01074 else if (h->vp < 43200) 01075 h->omsg[p++] = (h->vp + 1439) / 1440 + 166; 01076 else if (h->vp < 635040) 01077 h->omsg[p++] = (h->vp + 10079) / 10080 + 192; 01078 else 01079 h->omsg[p++] = 255; /* max */ 01080 } 01081 p += packsms (h->dcs, h->omsg + p, h->udhl, h->udh, h->udl, h->ud); 01082 } 01083 h->omsg[1] = p - 2; 01084 sms_messagetx (h); 01085 } else { /* no message */ 01086 h->omsg[0] = 0x94; /* SMS_REL */ 01087 h->omsg[1] = 0; 01088 sms_messagetx (h); 01089 } 01090 }
|
|
Definition at line 1261 of file app_sms.c. References ast_log(), sms_s::err, sms_s::hangup, sms_s::ibitc, sms_s::ibith, sms_s::ibitl, sms_s::ibitn, sms_s::ibitt, sms_s::ibytec, sms_s::ibytep, sms_s::ibytev, sms_s::idle, sms_s::ierr, sms_s::imag, sms_s::imc0, sms_s::imc1, sms_s::ims0, sms_s::ims1, sms_s::imsg, sms_s::ipc0, sms_s::ipc1, sms_s::iphasep, sms_s::ips0, sms_s::ips1, LOG_EVENT, m1, sms_s::obyten, sms_s::omsg, sms_s::osync, sms_messagerx(), sms_messagetx(), and wave. 01262 { 01263 if (h->obyten || h->osync) 01264 return; /* sending */ 01265 while (samples--) { 01266 unsigned long long m0, m1; 01267 if (abs (*data) > h->imag) 01268 h->imag = abs (*data); 01269 else 01270 h->imag = h->imag * 7 / 8; 01271 if (h->imag > 500) { 01272 h->idle = 0; 01273 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7; 01274 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7; 01275 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7; 01276 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7; 01277 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0; 01278 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1; 01279 if ((h->ips0 += 21) >= 80) 01280 h->ips0 -= 80; 01281 if ((h->ipc0 += 21) >= 80) 01282 h->ipc0 -= 80; 01283 if ((h->ips1 += 13) >= 80) 01284 h->ips1 -= 80; 01285 if ((h->ipc1 += 13) >= 80) 01286 h->ipc1 -= 80; 01287 { 01288 char bit; 01289 h->ibith <<= 1; 01290 if (m1 > m0) 01291 h->ibith |= 1; 01292 if (h->ibith & 8) 01293 h->ibitt--; 01294 if (h->ibith & 1) 01295 h->ibitt++; 01296 bit = ((h->ibitt > 1) ? 1 : 0); 01297 if (bit != h->ibitl) 01298 h->ibitc = 1; 01299 else 01300 h->ibitc++; 01301 h->ibitl = bit; 01302 if (!h->ibitn && h->ibitc == 4 && !bit) { 01303 h->ibitn = 1; 01304 h->iphasep = 0; 01305 } 01306 if (bit && h->ibitc == 200) { /* sync, restart message */ 01307 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0; 01308 } 01309 if (h->ibitn) { 01310 h->iphasep += 12; 01311 if (h->iphasep >= 80) { /* next bit */ 01312 h->iphasep -= 80; 01313 if (h->ibitn++ == 9) { /* end of byte */ 01314 if (!bit) /* bad stop bit */ 01315 h->ierr = 0xFF; /* unknown error */ 01316 else { 01317 if (h->ibytep < sizeof (h->imsg)) { 01318 h->imsg[h->ibytep] = h->ibytev; 01319 h->ibytec += h->ibytev; 01320 h->ibytep++; 01321 } else if (h->ibytep == sizeof (h->imsg)) 01322 h->ierr = 2; /* bad message length */ 01323 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) { 01324 if (!h->ibytec) 01325 sms_messagerx (h); 01326 else 01327 h->ierr = 1; /* bad checksum */ 01328 } 01329 } 01330 h->ibitn = 0; 01331 } 01332 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0); 01333 } 01334 } 01335 } 01336 } else { /* lost carrier */ 01337 if (h->idle++ == 80000) { /* nothing happening */ 01338 ast_log (LOG_EVENT, "No data, hanging up\n"); 01339 h->hangup = 1; 01340 h->err = 1; 01341 } 01342 if (h->ierr) { /* error */ 01343 h->err = 1; 01344 h->omsg[0] = 0x92; /* error */ 01345 h->omsg[1] = 1; 01346 h->omsg[2] = h->ierr; 01347 sms_messagetx (h); /* send error */ 01348 } 01349 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0; 01350 } 01351 data++; 01352 } 01353 }
|
|
Definition at line 677 of file app_sms.c. References ast_log(), sms_s::da, sms_s::dcs, LOG_EVENT, LOG_WARNING, sms_s::mr, numcpy(), sms_s::oa, sms_s::pid, sms_s::rp, sms_s::rx, s, sms_s::scts, SMSLEN, sms_s::srr, t, sms_s::ud, sms_s::udhi, sms_s::udhl, sms_s::udl, utf8decode(), and sms_s::vp. Referenced by sms_nextoutgoing(). 00678 { 00679 char line[1000]; 00680 FILE *s; 00681 char dcsset = 0; /* if DSC set */ 00682 ast_log (LOG_EVENT, "Sending %s\n", fn); 00683 h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0; 00684 h->mr = -1; 00685 h->dcs = 0xF1; /* normal messages class 1 */ 00686 h->scts = time (0); 00687 s = fopen (fn, "r"); 00688 if (s) 00689 { 00690 if (unlink (fn)) 00691 { /* concurrent access, we lost */ 00692 fclose (s); 00693 return; 00694 } 00695 while (fgets (line, sizeof (line), s)) 00696 { /* process line in file */ 00697 unsigned char *p; 00698 for (p = line; *p && *p != '\n' && *p != '\r'; p++); 00699 *p = 0; /* strip eoln */ 00700 p = line; 00701 if (!*p || *p == ';') 00702 continue; /* blank line or comment, ignore */ 00703 while (isalnum (*p)) 00704 { 00705 *p = tolower (*p); 00706 p++; 00707 } 00708 while (isspace (*p)) 00709 *p++ = 0; 00710 if (*p == '=') 00711 { 00712 *p++ = 0; 00713 if (!strcmp (line, "ud")) 00714 { /* parse message (UTF-8) */ 00715 unsigned char o = 0; 00716 while (*p && o < SMSLEN) 00717 h->ud[o++] = utf8decode((unsigned char **)&p); 00718 h->udl = o; 00719 if (*p) 00720 ast_log (LOG_WARNING, "UD too long in %s\n", fn); 00721 } else 00722 { 00723 while (isspace (*p)) 00724 p++; 00725 if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa)) 00726 numcpy (h->oa, p); 00727 else if (!strcmp (line, "da") && strlen (p) < sizeof (h->oa)) 00728 numcpy (h->da, p); 00729 else if (!strcmp (line, "pid")) 00730 h->pid = atoi (p); 00731 else if (!strcmp (line, "dcs")) 00732 { 00733 h->dcs = atoi (p); 00734 dcsset = 1; 00735 } else if (!strcmp (line, "mr")) 00736 h->mr = atoi (p); 00737 else if (!strcmp (line, "srr")) 00738 h->srr = (atoi (p) ? 1 : 0); 00739 else if (!strcmp (line, "vp")) 00740 h->vp = atoi (p); 00741 else if (!strcmp (line, "rp")) 00742 h->rp = (atoi (p) ? 1 : 0); 00743 else if (!strcmp (line, "scts")) 00744 { /* get date/time */ 00745 int Y, 00746 m, 00747 d, 00748 H, 00749 M, 00750 S; 00751 if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6) 00752 { 00753 struct tm t; 00754 t.tm_year = Y - 1900; 00755 t.tm_mon = m - 1; 00756 t.tm_mday = d; 00757 t.tm_hour = H; 00758 t.tm_min = M; 00759 t.tm_sec = S; 00760 t.tm_isdst = -1; 00761 h->scts = mktime (&t); 00762 if (h->scts == (time_t) - 1) 00763 ast_log (LOG_WARNING, "Bad date/timein %s: %s", fn, p); 00764 } 00765 } else 00766 ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p); 00767 } 00768 } else if (*p == '#') 00769 { /* raw hex format */ 00770 *p++ = 0; 00771 if (*p == '#') 00772 { 00773 p++; 00774 if (!strcmp (line, "ud")) 00775 { /* user data */ 00776 int o = 0; 00777 while (*p && o < SMSLEN) 00778 { 00779 if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3])) 00780 { 00781 h->ud[o++] = 00782 (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) + 00783 (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) + 00784 (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF)); 00785 p += 4; 00786 } else 00787 break; 00788 } 00789 h->udl = o; 00790 if (*p) 00791 ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn); 00792 } else 00793 ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn); 00794 } else if (!strcmp (line, "ud")) 00795 { /* user data */ 00796 int o = 0; 00797 while (*p && o < SMSLEN) 00798 { 00799 if (isxdigit (*p) && isxdigit (p[1])) 00800 { 00801 h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)); 00802 p += 2; 00803 } else 00804 break; 00805 } 00806 h->udl = o; 00807 if (*p) 00808 ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn); 00809 } else if (!strcmp (line, "udh")) 00810 { /* user data header */ 00811 unsigned char o = 0; 00812 h->udhi = 1; 00813 while (*p && o < SMSLEN) 00814 { 00815 if (isxdigit (*p) && isxdigit (p[1])) 00816 { 00817 h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)); 00818 o++; 00819 p += 2; 00820 } else 00821 break; 00822 } 00823 h->udhl = o; 00824 if (*p) 00825 ast_log (LOG_WARNING, "UDH too long / invalid hex in %s\n", fn); 00826 } else 00827 ast_log (LOG_WARNING, "Only ud and udh can use # format, %s\n", fn); 00828 } else 00829 ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line); 00830 } 00831 fclose (s); 00832 if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00833 { 00834 if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00835 { 00836 if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00837 ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn); 00838 else 00839 { 00840 h->dcs = 0x08; /* default to 16 bit */ 00841 ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn); 00842 } 00843 } else 00844 { 00845 h->dcs = 0xF5; /* default to 8 bit */ 00846 ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn); 00847 } 00848 } 00849 if (is7bit (h->dcs) && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00850 ast_log (LOG_WARNING, "Invalid 7 bit GSM data %s\n", fn); 00851 if (is8bit (h->dcs) && packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00852 ast_log (LOG_WARNING, "Invalid 8 bit data %s\n", fn); 00853 if (is16bit (h->dcs) && packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0) 00854 ast_log (LOG_WARNING, "Invalid 16 bit data %s\n", fn); 00855 } 00856 }
|
|
Definition at line 193 of file app_sms.c.
|
|
Definition at line 859 of file app_sms.c. References sms_s::da, isodate(), sms_s::oa, sms_s::queue, sms_s::rx, sms_s::scts, seq, sms_s::smsc, spool_dir, sms_s::ud, sms_s::udh, sms_s::udhi, sms_s::udhl, and sms_s::udl. Referenced by sms_handleincoming(). 00860 { 00861 char fn[200] = "", fn2[200] = ""; 00862 FILE *o; 00863 ast_copy_string (fn, spool_dir, sizeof (fn)); 00864 mkdir (fn, 0777); /* ensure it exists */ 00865 snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? h->rx ? "morx" : "mttx" : h->rx ? "mtrx" : "motx"); 00866 mkdir (fn, 0777); /* ensure it exists */ 00867 ast_copy_string (fn2, fn, sizeof (fn2)); 00868 snprintf (fn2 + strlen (fn2), sizeof (fn2) - strlen (fn2), "/%s.%s-%d", h->queue, isodate (h->scts), seq++); 00869 snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/.%s", fn2 + strlen (fn) + 1); 00870 o = fopen (fn, "w"); 00871 if (o) { 00872 if (*h->oa) 00873 fprintf (o, "oa=%s\n", h->oa); 00874 if (*h->da) 00875 fprintf (o, "da=%s\n", h->da); 00876 if (h->udhi) { 00877 unsigned int p; 00878 fprintf (o, "udh#"); 00879 for (p = 0; p < h->udhl; p++) 00880 fprintf (o, "%02X", h->udh[p]); 00881 fprintf (o, "\n"); 00882 } 00883 if (h->udl) { 00884 unsigned int p; 00885 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++); 00886 if (p < h->udl) 00887 fputc (';', o); /* cannot use ud=, but include as a comment for human readable */ 00888 fprintf (o, "ud="); 00889 for (p = 0; p < h->udl; p++) { 00890 unsigned short v = h->ud[p]; 00891 if (v < 32) 00892 fputc (191, o); 00893 else if (v < 0x80) 00894 fputc (v, o); 00895 else if (v < 0x800) 00896 { 00897 fputc (0xC0 + (v >> 6), o); 00898 fputc (0x80 + (v & 0x3F), o); 00899 } else 00900 { 00901 fputc (0xE0 + (v >> 12), o); 00902 fputc (0x80 + ((v >> 6) & 0x3F), o); 00903 fputc (0x80 + (v & 0x3F), o); 00904 } 00905 } 00906 fprintf (o, "\n"); 00907 for (p = 0; p < h->udl && h->ud[p] >= ' '; p++); 00908 if (p < h->udl) { 00909 for (p = 0; p < h->udl && h->ud[p] < 0x100; p++); 00910 if (p == h->udl) { /* can write in ucs-1 hex */ 00911 fprintf (o, "ud#"); 00912 for (p = 0; p < h->udl; p++) 00913 fprintf (o, "%02X", h->ud[p]); 00914 fprintf (o, "\n"); 00915 } else { /* write in UCS-2 */ 00916 fprintf (o, "ud##"); 00917 for (p = 0; p < h->udl; p++) 00918 fprintf (o, "%04X", h->ud[p]); 00919 fprintf (o, "\n"); 00920 } 00921 } 00922 } 00923 if (h->scts) 00924 fprintf (o, "scts=%s\n", isodate (h->scts)); 00925 if (h->pid) 00926 fprintf (o, "pid=%d\n", h->pid); 00927 if (h->dcs != 0xF1) 00928 fprintf (o, "dcs=%d\n", h->dcs); 00929 if (h->vp) 00930 fprintf (o, "vp=%d\n", h->vp); 00931 if (h->srr) 00932 fprintf (o, "srr=1\n"); 00933 if (h->mr >= 0) 00934 fprintf (o, "mr=%d\n", h->mr); 00935 if (h->rp) 00936 fprintf (o, "rp=1\n"); 00937 fclose (o); 00938 if (rename (fn, fn2)) 00939 unlink (fn); 00940 else 00941 ast_log (LOG_EVENT, "Received to %s\n", fn2); 00942 } 00943 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 1515 of file app_sms.c. References app, ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 01516 { 01517 int res; 01518 01519 res = ast_unregister_application (app); 01520 01521 STANDARD_HANGUP_LOCALUSERS; 01522 01523 return res; 01524 }
|
|
Definition at line 597 of file app_sms.c. Referenced by sms_handleincoming(). 00598 { 00599 unsigned char l = i[0], 00600 p; 00601 if (i[1] == 0x91) 00602 *o++ = '+'; 00603 for (p = 0; p < l; p++) { 00604 if (p & 1) 00605 *o++ = (i[2 + p / 2] >> 4) + '0'; 00606 else 00607 *o++ = (i[2 + p / 2] & 0xF) + '0'; 00608 } 00609 *o = 0; 00610 return (l + 5) / 2; 00611 }
|
|
Definition at line 460 of file app_sms.c. Referenced by sms_handleincoming(). 00461 { 00462 struct tm t; 00463 t.tm_year = 100 + (i[0] & 0xF) * 10 + (i[0] >> 4); 00464 t.tm_mon = (i[1] & 0xF) * 10 + (i[1] >> 4) - 1; 00465 t.tm_mday = (i[2] & 0xF) * 10 + (i[2] >> 4); 00466 t.tm_hour = (i[3] & 0xF) * 10 + (i[3] >> 4); 00467 t.tm_min = (i[4] & 0xF) * 10 + (i[4] >> 4); 00468 t.tm_sec = (i[5] & 0xF) * 10 + (i[5] >> 4); 00469 t.tm_isdst = 0; 00470 if (i[6] & 0x08) 00471 t.tm_min += 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4)); 00472 else 00473 t.tm_min -= 15 * ((i[6] & 0x7) * 10 + (i[6] >> 4)); 00474 return mktime (&t); 00475 }
|
|
Definition at line 583 of file app_sms.c. References is7bit, is8bit, unpacksms16(), unpacksms7(), and unpacksms8(). Referenced by sms_handleincoming(). 00584 { 00585 int l = *i++; 00586 if (is7bit (dcs)) { 00587 unpacksms7 (i, l, udh, udhl, ud, udl, udhi); 00588 l = (l * 7 + 7) / 8; /* adjust length to return */ 00589 } else if (is8bit (dcs)) 00590 unpacksms8 (i, l, udh, udhl, ud, udl, udhi); 00591 else 00592 unpacksms16 (i, l, udh, udhl, ud, udl, udhi); 00593 return l + 1; 00594 }
|
|
Definition at line 556 of file app_sms.c. References n. Referenced by unpacksms(). 00557 { 00558 unsigned short *o = ud; 00559 *udhl = 0; 00560 if (udhi) { 00561 int n = *i; 00562 *udhl = n; 00563 if (n) { 00564 i++; 00565 l--; 00566 while (l && n) { 00567 l--; 00568 n--; 00569 *udh++ = *i++; 00570 } 00571 } 00572 } 00573 while (l--) { 00574 int v = *i++; 00575 if (l--) 00576 v = (v << 8) + *i++; 00577 *o++ = v; 00578 } 00579 *udl = (o - ud); 00580 }
|
|
Definition at line 480 of file app_sms.c. References defaultalphabet, and escapes. Referenced by unpacksms(). 00481 { 00482 unsigned char b = 0, p = 0; 00483 unsigned short *o = ud; 00484 *udhl = 0; 00485 if (udhi && l) { /* header */ 00486 int h = i[p]; 00487 *udhl = h; 00488 if (h) { 00489 b = 1; 00490 p++; 00491 l--; 00492 while (h-- && l) { 00493 *udh++ = i[p++]; 00494 b += 8; 00495 while (b >= 7) { 00496 b -= 7; 00497 l--; 00498 if (!l) 00499 break; 00500 } 00501 } 00502 /* adjust for fill, septets */ 00503 if (b) { 00504 b = 7 - b; 00505 l--; 00506 } 00507 } 00508 } 00509 while (l--) { 00510 unsigned char v; 00511 if (b < 2) 00512 v = ((i[p] >> b) & 0x7F); 00513 else 00514 v = ((((i[p] >> b) + (i[p + 1] << (8 - b)))) & 0x7F); 00515 b += 7; 00516 if (b >= 8) { 00517 b -= 8; 00518 p++; 00519 } 00520 if (o > ud && o[-1] == 0x00A0 && escapes[v]) 00521 o[-1] = escapes[v]; 00522 else 00523 *o++ = defaultalphabet[v]; 00524 } 00525 *udl = (o - ud); 00526 }
|
|
Definition at line 531 of file app_sms.c. References n. Referenced by unpacksms(). 00532 { 00533 unsigned short *o = ud; 00534 *udhl = 0; 00535 if (udhi) { 00536 int n = *i; 00537 *udhl = n; 00538 if (n) { 00539 i++; 00540 l--; 00541 while (l && n) { 00542 l--; 00543 n--; 00544 *udh++ = *i++; 00545 } 00546 } 00547 } 00548 while (l--) 00549 *o++ = *i++; /* not to UTF-8 as explicitely 8 bit coding in DCS */ 00550 *udl = (o - ud); 00551 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 1545 of file app_sms.c. References STANDARD_USECOUNT. 01546 { 01547 int res; 01548 STANDARD_USECOUNT (res); 01549 return res; 01550 }
|
|
Definition at line 224 of file app_sms.c. Referenced by sms_readfile(). 00225 { 00226 unsigned char *p = *pp; 00227 if (!*p) 00228 return 0; /* null termination of string */ 00229 (*pp)++; 00230 if (*p < 0xC0) 00231 return *p; /* ascii or continuation character */ 00232 if (*p < 0xE0) { 00233 if (*p < 0xC2 || (p[1] & 0xC0) != 0x80) 00234 return *p; /* not valid UTF-8 */ 00235 (*pp)++; 00236 return ((*p & 0x1F) << 6) + (p[1] & 0x3F); 00237 } 00238 if (*p < 0xF0) { 00239 if ((*p == 0xE0 && p[1] < 0xA0) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80) 00240 return *p; /* not valid UTF-8 */ 00241 (*pp) += 2; 00242 return ((*p & 0x0F) << 12) + ((p[1] & 0x3F) << 6) + (p[2] & 0x3F); 00243 } 00244 if (*p < 0xF8) { 00245 if ((*p == 0xF0 && p[1] < 0x90) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80) 00246 return *p; /* not valid UTF-8 */ 00247 (*pp) += 3; 00248 return ((*p & 0x07) << 18) + ((p[1] & 0x3F) << 12) + ((p[2] & 0x3F) << 6) + (p[3] & 0x3F); 00249 } 00250 if (*p < 0xFC) { 00251 if ((*p == 0xF8 && p[1] < 0x88) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80 00252 || (p[4] & 0xC0) != 0x80) 00253 return *p; /* not valid UTF-8 */ 00254 (*pp) += 4; 00255 return ((*p & 0x03) << 24) + ((p[1] & 0x3F) << 18) + ((p[2] & 0x3F) << 12) + ((p[3] & 0x3F) << 6) + (p[4] & 0x3F); 00256 } 00257 if (*p < 0xFE) { 00258 if ((*p == 0xFC && p[1] < 0x84) || (p[1] & 0xC0) != 0x80 || (p[2] & 0xC0) != 0x80 || (p[3] & 0xC0) != 0x80 00259 || (p[4] & 0xC0) != 0x80 || (p[5] & 0xC0) != 0x80) 00260 return *p; /* not valid UTF-8 */ 00261 (*pp) += 5; 00262 return ((*p & 0x01) << 30) + ((p[1] & 0x3F) << 24) + ((p[2] & 0x3F) << 18) + ((p[3] & 0x3F) << 12) + ((p[4] & 0x3F) << 6) + (p[5] & 0x3F); 00263 } 00264 return *p; /* not sensible */ 00265 }
|
|
|
|
Definition at line 102 of file app_sms.c. Referenced by unpacksms7(). |
|
|
|
Definition at line 115 of file app_sms.c. Referenced by unpacksms7(). |
|
|
|
Definition at line 60 of file app_sms.c. Referenced by load_module(), and sms_log(). |
|
Definition at line 57 of file app_sms.c. Referenced by sms_nextoutgoing(). |
|
Definition at line 58 of file app_sms.c. Referenced by handle_link_data(), handle_remote_data(), and sms_writefile(). |
|
Initial value: { alloc:sms_alloc, release:sms_release, generate:sms_generate, } |
|
Definition at line 61 of file app_sms.c. Referenced by load_module(), sms_nextoutgoing(), and sms_writefile(). |
|
|
|
|
|
|
|
Definition at line 84 of file app_sms.c. Referenced by festival_exec(), load_module(), sms_generate(), and sms_process(). |