#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"
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 | MAXSAMPLES 800 |
#define | SAMPLE2LEN sizeof(*buf) |
#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(). |
|
Referenced by sms_generate(). |
|
Referenced by sms_generate(). |
|
Definition at line 126 of file app_sms.c. Referenced by packsms7(), and sms_readfile(). |
|
|
|
Provides a description of the module.
Definition at line 1539 of file app_sms.c. References tdesc. 01540 { 01541 return tdesc; 01542 }
|
|
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 1551 of file app_sms.c. References ASTERISK_GPL_KEY. 01552 { 01553 return ASTERISK_GPL_KEY; 01554 }
|
|
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 1525 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. 01526 { 01527 #ifdef OUTALAW 01528 { 01529 int p; 01530 for (p = 0; p < 80; p++) 01531 wavea[p] = AST_LIN2A (wave[p]); 01532 } 01533 #endif 01534 snprintf (log_file, sizeof (log_file), "%s/sms", ast_config_AST_LOG_DIR); 01535 snprintf (spool_dir, sizeof (spool_dir), "%s/sms", ast_config_AST_SPOOL_DIR); 01536 return ast_register_application (app, sms_exec, synopsis, descrip); 01537 }
|
|
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 1360 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(). 01361 { 01362 int res = -1; 01363 struct localuser *u; 01364 struct ast_frame *f; 01365 sms_t h = { 0 }; 01366 01367 LOCAL_USER_ADD(u); 01368 01369 h.ipc0 = h.ipc1 = 20; /* phase for cosine */ 01370 h.dcs = 0xF1; /* default */ 01371 if (!data) { 01372 ast_log (LOG_ERROR, "Requires queue name at least\n"); 01373 LOCAL_USER_REMOVE(u); 01374 return -1; 01375 } 01376 01377 if (chan->cid.cid_num) 01378 ast_copy_string (h.cli, chan->cid.cid_num, sizeof (h.cli)); 01379 01380 { 01381 unsigned char *p; 01382 unsigned char *d = data, 01383 answer = 0; 01384 if (!*d || *d == '|') { 01385 ast_log (LOG_ERROR, "Requires queue name\n"); 01386 LOCAL_USER_REMOVE(u); 01387 return -1; 01388 } 01389 for (p = d; *p && *p != '|'; p++); 01390 if (p - d >= sizeof (h.queue)) { 01391 ast_log (LOG_ERROR, "Queue name too long\n"); 01392 LOCAL_USER_REMOVE(u); 01393 return -1; 01394 } 01395 strncpy (h.queue, d, p - d); 01396 if (*p == '|') 01397 p++; 01398 d = p; 01399 for (p = h.queue; *p; p++) 01400 if (!isalnum (*p)) 01401 *p = '-'; /* make very safe for filenames */ 01402 while (*d && *d != '|') { 01403 switch (*d) { 01404 case 'a': /* we have to send the initial FSK sequence */ 01405 answer = 1; 01406 break; 01407 case 's': /* we are acting as a service centre talking to a phone */ 01408 h.smsc = 1; 01409 break; 01410 /* the following apply if there is an arg3/4 and apply to the created message file */ 01411 case 'r': 01412 h.srr = 1; 01413 break; 01414 case 'o': 01415 h.dcs |= 4; /* octets */ 01416 break; 01417 case '1': 01418 case '2': 01419 case '3': 01420 case '4': 01421 case '5': 01422 case '6': 01423 case '7': /* set the pid for saved local message */ 01424 h.pid = 0x40 + (*d & 0xF); 01425 break; 01426 } 01427 d++; 01428 } 01429 if (*d == '|') { 01430 /* submitting a message, not taking call. */ 01431 /* depricated, use smsq instead */ 01432 d++; 01433 h.scts = time (0); 01434 for (p = d; *p && *p != '|'; p++); 01435 if (*p) 01436 *p++ = 0; 01437 if (strlen (d) >= sizeof (h.oa)) { 01438 ast_log (LOG_ERROR, "Address too long %s\n", d); 01439 return 0; 01440 } 01441 if (h.smsc) { 01442 ast_copy_string (h.oa, d, sizeof (h.oa)); 01443 } else { 01444 ast_copy_string (h.da, d, sizeof (h.da)); 01445 } 01446 if (!h.smsc) 01447 ast_copy_string (h.oa, h.cli, sizeof (h.oa)); 01448 d = p; 01449 h.udl = 0; 01450 while (*p && h.udl < SMSLEN) 01451 h.ud[h.udl++] = utf8decode(&p); 01452 if (is7bit (h.dcs) && packsms7 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01453 ast_log (LOG_WARNING, "Invalid 7 bit GSM data\n"); 01454 if (is8bit (h.dcs) && packsms8 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01455 ast_log (LOG_WARNING, "Invalid 8 bit data\n"); 01456 if (is16bit (h.dcs) && packsms16 (0, h.udhl, h.udh, h.udl, h.ud) < 0) 01457 ast_log (LOG_WARNING, "Invalid 16 bit data\n"); 01458 h.rx = 0; /* sent message */ 01459 h.mr = -1; 01460 sms_writefile (&h); 01461 LOCAL_USER_REMOVE(u); 01462 return 0; 01463 } 01464 01465 if (answer) { 01466 /* set up SMS_EST initial message */ 01467 h.omsg[0] = 0x93; 01468 h.omsg[1] = 0; 01469 sms_messagetx (&h); 01470 } 01471 } 01472 01473 if (chan->_state != AST_STATE_UP) 01474 ast_answer (chan); 01475 01476 #ifdef OUTALAW 01477 res = ast_set_write_format (chan, AST_FORMAT_ALAW); 01478 #else 01479 res = ast_set_write_format (chan, AST_FORMAT_SLINEAR); 01480 #endif 01481 if (res >= 0) 01482 res = ast_set_read_format (chan, AST_FORMAT_SLINEAR); 01483 if (res < 0) { 01484 ast_log (LOG_ERROR, "Unable to set to linear mode, giving up\n"); 01485 LOCAL_USER_REMOVE (u); 01486 return -1; 01487 } 01488 01489 if (ast_activate_generator (chan, &smsgen, &h) < 0) { 01490 ast_log (LOG_ERROR, "Failed to activate generator on '%s'\n", chan->name); 01491 LOCAL_USER_REMOVE (u); 01492 return -1; 01493 } 01494 01495 /* Do our thing here */ 01496 while (ast_waitfor (chan, -1) > -1 && !h.hangup) 01497 { 01498 f = ast_read (chan); 01499 if (!f) 01500 break; 01501 if (f->frametype == AST_FRAME_VOICE) { 01502 sms_process (&h, f->samples, f->data); 01503 } 01504 01505 ast_frfree (f); 01506 } 01507 01508 sms_log (&h, '?'); /* log incomplete message */ 01509 01510 LOCAL_USER_REMOVE (u); 01511 return (h.err); 01512 }
|
|
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, MAXSAMPLES, 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, SAMPLE2LEN, ast_frame::samples, ast_frame::src, ast_frame::subclass, and wave. 01179 { 01180 struct ast_frame f = { 0 }; 01181 #define MAXSAMPLES 800 01182 #ifdef OUTALAW 01183 unsigned char *buf; 01184 #else 01185 short *buf; 01186 #endif 01187 #define SAMPLE2LEN sizeof(*buf) 01188 sms_t *h = data; 01189 int i; 01190 01191 if (samples > MAXSAMPLES) { 01192 ast_log (LOG_WARNING, "Only doing %d samples (%d requested)\n", 01193 MAXSAMPLES, samples); 01194 samples = MAXSAMPLES; 01195 } 01196 len = samples * SAMPLE2LEN + AST_FRIENDLY_OFFSET; 01197 buf = alloca(len); 01198 01199 f.frametype = AST_FRAME_VOICE; 01200 #ifdef OUTALAW 01201 f.subclass = AST_FORMAT_ALAW; 01202 f.datalen = samples; 01203 #else 01204 f.subclass = AST_FORMAT_SLINEAR; 01205 f.datalen = samples * 2; 01206 #endif 01207 f.offset = AST_FRIENDLY_OFFSET; 01208 f.mallocd = 0; 01209 f.data = buf; 01210 f.samples = samples; 01211 f.src = "app_sms"; 01212 /* create a buffer containing the digital sms pattern */ 01213 for (i = 0; i < samples; i++) { 01214 #ifdef OUTALAW 01215 buf[i] = wavea[0]; 01216 #else 01217 buf[i] = wave[0]; 01218 #endif 01219 if (h->opause) 01220 h->opause--; 01221 else if (h->obyten || h->osync) { /* sending data */ 01222 #ifdef OUTALAW 01223 buf[i] = wavea[h->ophase]; 01224 #else 01225 buf[i] = wave[h->ophase]; 01226 #endif 01227 if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80) 01228 h->ophase -= 80; 01229 if ((h->ophasep += 12) >= 80) { /* next bit */ 01230 h->ophasep -= 80; 01231 if (h->osync) 01232 h->osync--; /* sending sync bits */ 01233 else { 01234 h->obyte >>= 1; 01235 h->obitp++; 01236 if (h->obitp == 1) 01237 h->obyte = 0; /* start bit; */ 01238 else if (h->obitp == 2) 01239 h->obyte = h->omsg[h->obytep]; 01240 else if (h->obitp == 10) { 01241 h->obyte = 1; /* stop bit */ 01242 h->obitp = 0; 01243 h->obytep++; 01244 if (h->obytep == h->obyten) { 01245 h->obytep = h->obyten = 0; /* sent */ 01246 h->osync = 10; /* trailing marks */ 01247 } 01248 } 01249 } 01250 } 01251 } 01252 } 01253 if (ast_write (chan, &f) < 0) { 01254 ast_log (LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror (errno)); 01255 return -1; 01256 } 01257 return 0; 01258 }
|
|
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 1260 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. 01261 { 01262 if (h->obyten || h->osync) 01263 return; /* sending */ 01264 while (samples--) { 01265 unsigned long long m0, m1; 01266 if (abs (*data) > h->imag) 01267 h->imag = abs (*data); 01268 else 01269 h->imag = h->imag * 7 / 8; 01270 if (h->imag > 500) { 01271 h->idle = 0; 01272 h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7; 01273 h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7; 01274 h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7; 01275 h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7; 01276 m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0; 01277 m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1; 01278 if ((h->ips0 += 21) >= 80) 01279 h->ips0 -= 80; 01280 if ((h->ipc0 += 21) >= 80) 01281 h->ipc0 -= 80; 01282 if ((h->ips1 += 13) >= 80) 01283 h->ips1 -= 80; 01284 if ((h->ipc1 += 13) >= 80) 01285 h->ipc1 -= 80; 01286 { 01287 char bit; 01288 h->ibith <<= 1; 01289 if (m1 > m0) 01290 h->ibith |= 1; 01291 if (h->ibith & 8) 01292 h->ibitt--; 01293 if (h->ibith & 1) 01294 h->ibitt++; 01295 bit = ((h->ibitt > 1) ? 1 : 0); 01296 if (bit != h->ibitl) 01297 h->ibitc = 1; 01298 else 01299 h->ibitc++; 01300 h->ibitl = bit; 01301 if (!h->ibitn && h->ibitc == 4 && !bit) { 01302 h->ibitn = 1; 01303 h->iphasep = 0; 01304 } 01305 if (bit && h->ibitc == 200) { /* sync, restart message */ 01306 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0; 01307 } 01308 if (h->ibitn) { 01309 h->iphasep += 12; 01310 if (h->iphasep >= 80) { /* next bit */ 01311 h->iphasep -= 80; 01312 if (h->ibitn++ == 9) { /* end of byte */ 01313 if (!bit) /* bad stop bit */ 01314 h->ierr = 0xFF; /* unknown error */ 01315 else { 01316 if (h->ibytep < sizeof (h->imsg)) { 01317 h->imsg[h->ibytep] = h->ibytev; 01318 h->ibytec += h->ibytev; 01319 h->ibytep++; 01320 } else if (h->ibytep == sizeof (h->imsg)) 01321 h->ierr = 2; /* bad message length */ 01322 if (h->ibytep > 1 && h->ibytep == 3 + h->imsg[1] && !h->ierr) { 01323 if (!h->ibytec) 01324 sms_messagerx (h); 01325 else 01326 h->ierr = 1; /* bad checksum */ 01327 } 01328 } 01329 h->ibitn = 0; 01330 } 01331 h->ibytev = (h->ibytev >> 1) + (bit ? 0x80 : 0); 01332 } 01333 } 01334 } 01335 } else { /* lost carrier */ 01336 if (h->idle++ == 80000) { /* nothing happening */ 01337 ast_log (LOG_EVENT, "No data, hanging up\n"); 01338 h->hangup = 1; 01339 h->err = 1; 01340 } 01341 if (h->ierr) { /* error */ 01342 h->err = 1; 01343 h->omsg[0] = 0x92; /* error */ 01344 h->omsg[1] = 1; 01345 h->omsg[2] = h->ierr; 01346 sms_messagetx (h); /* send error */ 01347 } 01348 h->ierr = h->ibitn = h->ibytep = h->ibytec = 0; 01349 } 01350 data++; 01351 } 01352 }
|
|
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 1514 of file app_sms.c. References app, ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 01515 { 01516 int res; 01517 01518 res = ast_unregister_application (app); 01519 01520 STANDARD_HANGUP_LOCALUSERS; 01521 01522 return res; 01523 }
|
|
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 1544 of file app_sms.c. References STANDARD_USECOUNT. 01545 { 01546 int res; 01547 STANDARD_USECOUNT (res); 01548 return res; 01549 }
|
|
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(). |