chan_modem.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief A/Open ITU-56/2 Voice Modem Driver (Rockwell, IS-101, and others)
  21. *
  22. * \ingroup channel_drivers
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <ctype.h>
  27. #include <string.h>
  28. #include <sys/time.h>
  29. #include <errno.h>
  30. #include <netinet/in.h>
  31. #include <arpa/inet.h>
  32. #include <sys/socket.h>
  33. #include <fcntl.h>
  34. #include <sys/ioctl.h>
  35. #include <sys/termios.h>
  36. #include <sys/signal.h>
  37. #include "asterisk.h"
  38. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  39. #include "asterisk/lock.h"
  40. #include "asterisk/channel.h"
  41. #include "asterisk/config.h"
  42. #include "asterisk/logger.h"
  43. #include "asterisk/module.h"
  44. #include "asterisk/pbx.h"
  45. #include "asterisk/options.h"
  46. #include "asterisk/vmodem.h"
  47. #include "asterisk/utils.h"
  48. /* Up to 10 seconds for an echo to arrive */
  49. #define ECHO_TIMEOUT 10
  50. static const char desc[] = "Generic Voice Modem Driver";
  51. static const char tdesc[] = "Generic Voice Modem Channel Driver";
  52. static const char type[] = "Modem";
  53. static const char config[] = "modem.conf";
  54. static char dialtype = 'T';
  55. static int gmode = MODEM_MODE_IMMEDIATE;
  56. /* Default modem type */
  57. static char mtype[80] = "autodetect";
  58. /* Default context for incoming calls */
  59. static char context[AST_MAX_EXTENSION]= "default";
  60. /* Default language */
  61. static char language[MAX_LANGUAGE] = "";
  62. /* Initialization String */
  63. static char initstr[AST_MAX_INIT_STR] = "ATE0Q0";
  64. /* Default MSN */
  65. static char msn[AST_MAX_EXTENSION]="";
  66. /* Default Listen */
  67. static char incomingmsn[AST_MAX_EXTENSION]="";
  68. /* Default DTMF-detection mode (i4l/asterisk) */
  69. static int dtmfmode = MODEM_DTMF_AST;
  70. /* Default DTMF-generation mode (i4l (outband) / asterisk (inband) */
  71. static int dtmfmodegen = MODEM_DTMF_AST;
  72. struct ast_dsp *dsp = NULL;
  73. /* Default valid outgoing MSN */
  74. static char outgoingmsn[AST_MAX_EXTENSION]="";
  75. /* Default group */
  76. static ast_group_t cur_group = 0;
  77. static int usecnt =0;
  78. static int baudrate = 115200;
  79. static int stripmsd = 0;
  80. AST_MUTEX_DEFINE_STATIC(usecnt_lock);
  81. /* Protect the interface list (of ast_modem_pvt's) */
  82. AST_MUTEX_DEFINE_STATIC(iflock);
  83. /* Protect the monitoring thread, so only one process can kill or start it, and not
  84. when it's doing something critical. */
  85. AST_MUTEX_DEFINE_STATIC(monlock);
  86. /* This is the thread for the monitor which checks for input on the channels
  87. which are not currently in use. */
  88. static pthread_t monitor_thread = AST_PTHREADT_NULL;
  89. static int restart_monitor(void);
  90. int dep_warning = 0;
  91. static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause);
  92. static int modem_digit(struct ast_channel *ast, char digit);
  93. static int modem_call(struct ast_channel *ast, char *idest, int timeout);
  94. static int modem_hangup(struct ast_channel *ast);
  95. static int modem_answer(struct ast_channel *ast);
  96. static struct ast_frame *modem_read(struct ast_channel *);
  97. static int modem_write(struct ast_channel *ast, struct ast_frame *frame);
  98. static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  99. static const struct ast_channel_tech modem_tech = {
  100. .type = type,
  101. .description = tdesc,
  102. .capabilities = AST_FORMAT_SLINEAR,
  103. .requester = modem_request,
  104. .send_digit = modem_digit,
  105. .call = modem_call,
  106. .hangup = modem_hangup,
  107. .answer = modem_answer,
  108. .read = modem_read,
  109. .write = modem_write,
  110. .fixup = modem_fixup,
  111. };
  112. /* The private structures of the Phone Jack channels are linked for
  113. selecting outgoing channels */
  114. static struct ast_modem_pvt *iflist = NULL;
  115. static int modem_digit(struct ast_channel *ast, char digit)
  116. {
  117. struct ast_modem_pvt *p;
  118. p = ast->tech_pvt;
  119. if (p->mc->dialdigit)
  120. return p->mc->dialdigit(p, digit);
  121. ast_log(LOG_DEBUG, "Channel %s lacks digit dialing\n", ast->name);
  122. return -1;
  123. }
  124. static struct ast_modem_driver *drivers = NULL;
  125. static struct ast_modem_driver *find_capability(char *ident)
  126. {
  127. struct ast_modem_driver *mc;
  128. int x;
  129. mc = drivers;
  130. while(mc) {
  131. for (x=0;mc->idents[x];x++) {
  132. if (!strcmp(ident, mc->idents[x]))
  133. break;
  134. }
  135. if (mc->idents[x])
  136. break;
  137. mc = mc->next;
  138. }
  139. if (mc) {
  140. if (mc->incusecnt)
  141. mc->incusecnt();
  142. }
  143. return mc;
  144. }
  145. static struct ast_modem_driver *find_driver(char *drv)
  146. {
  147. struct ast_modem_driver *mc;
  148. mc = drivers;
  149. while(mc) {
  150. if (!strcasecmp(mc->name, drv))
  151. break;
  152. mc = mc->next;
  153. }
  154. if (mc) {
  155. if (mc->incusecnt)
  156. mc->incusecnt();
  157. }
  158. return mc;
  159. }
  160. int ast_register_modem_driver(struct ast_modem_driver *mc)
  161. {
  162. mc->next = drivers;
  163. drivers = mc;
  164. return 0;
  165. }
  166. int ast_unregister_modem_driver(struct ast_modem_driver *mc)
  167. {
  168. struct ast_modem_driver *last = NULL, *cur;
  169. cur = drivers;
  170. while(cur) {
  171. if (cur == mc) {
  172. if (last)
  173. last->next = mc->next;
  174. else
  175. drivers = mc->next;
  176. return 0;
  177. }
  178. cur = cur->next;
  179. }
  180. return -1;
  181. }
  182. static int modem_call(struct ast_channel *ast, char *idest, int timeout)
  183. {
  184. struct ast_modem_pvt *p;
  185. int ms = timeout;
  186. char rdest[80], *where, dstr[100] = "";
  187. char *stringp=NULL;
  188. strncpy(rdest, idest, sizeof(rdest)-1);
  189. stringp=rdest;
  190. strsep(&stringp, ":");
  191. where = strsep(&stringp, ":");
  192. if (!where) {
  193. ast_log(LOG_WARNING, "Destination %s requres a real destination (device:destination)\n", idest);
  194. return -1;
  195. }
  196. p = ast->tech_pvt;
  197. strncpy(dstr, where + p->stripmsd, sizeof(dstr) - 1);
  198. /* if not a transfer or just sending tones, must be in correct state */
  199. if (strcasecmp(rdest, "transfer") && strcasecmp(rdest,"sendtones")) {
  200. if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
  201. ast_log(LOG_WARNING, "modem_call called on %s, neither down nor reserved\n", ast->name);
  202. return -1;
  203. }
  204. }
  205. if (!strcasecmp(rdest,"transfer")) /* if a transfer, put in transfer stuff */
  206. {
  207. snprintf(dstr, sizeof(dstr), "!,%s", where + p->stripmsd);
  208. }
  209. if (!strcasecmp(where, "handset")) {
  210. if (p->mc->setdev)
  211. if (p->mc->setdev(p, MODEM_DEV_HANDSET))
  212. return -1;
  213. /* Should be immediately up */
  214. ast_setstate(ast, AST_STATE_UP);
  215. } else {
  216. if (p->mc->setdev)
  217. if (p->mc->setdev(p, MODEM_DEV_TELCO_SPK))
  218. return -1;
  219. if (p->mc->dial)
  220. p->mc->dial(p, dstr);
  221. ast_setstate(ast, AST_STATE_DIALING);
  222. while((ast->_state != AST_STATE_UP) && (ms > 0)) {
  223. ms = ast_waitfor(ast, ms);
  224. /* Just read packets and watch what happens */
  225. if (ms > 0) {
  226. if (!modem_read(ast))
  227. return -1;
  228. }
  229. }
  230. if (ms < 0)
  231. return -1;
  232. }
  233. return 0;
  234. }
  235. int ast_modem_send(struct ast_modem_pvt *p, char *cmd, int len)
  236. {
  237. int i;
  238. usleep(5000);
  239. if (!len) {
  240. for(i = 0; cmd[i];)
  241. {
  242. if (fwrite(cmd + i,1,1,p->f) != 1)
  243. {
  244. if (errno == EWOULDBLOCK) continue;
  245. return -1;
  246. }
  247. i++;
  248. }
  249. tcdrain(fileno(p->f));
  250. fprintf(p->f,"\r\n");
  251. return 0;
  252. } else {
  253. if (fwrite(cmd, 1, len, p->f) < len)
  254. return -1;
  255. return 0;
  256. }
  257. }
  258. int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
  259. {
  260. int res = -1,c,i;
  261. timeout *= 1000;
  262. p->response[0] = 0;
  263. c = i = 0;
  264. do {
  265. res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
  266. if (res < 0) {
  267. strncpy(p->response, "(No Response)", sizeof(p->response)-1);
  268. return -1;
  269. }
  270. /* get no more then buffer length */
  271. while(i < sizeof(p->response) - 1)
  272. {
  273. c = fgetc(p->f); /* get a char */
  274. if (c < 1) /* if error */
  275. {
  276. /* if nothing in buffer, go back into timeout stuff */
  277. if (errno == EWOULDBLOCK) break;
  278. /* return as error */
  279. strncpy(p->response, "(No Response)", sizeof(p->response)-1);
  280. return -1;
  281. }
  282. /* save char */
  283. p->response[i++] = c;
  284. p->response[i] = 0;
  285. /* if end of input */
  286. if (c == '\n') break;
  287. }
  288. if (c >= 0) /* if input terminated normally */
  289. {
  290. /* ignore just CR/LF */
  291. if (!strcmp(p->response,"\r\n"))
  292. {
  293. /* reset input buffer stuff */
  294. i = 0;
  295. p->response[0] = 0;
  296. }
  297. else /* otherwise return with info in buffer */
  298. {
  299. return 0;
  300. }
  301. }
  302. } while(timeout > 0);
  303. strncpy(p->response, "(No Response)", sizeof(p->response)-1);
  304. return -1;
  305. }
  306. int ast_modem_expect(struct ast_modem_pvt *p, char *result, int timeout)
  307. {
  308. int res = -1;
  309. timeout *= 1000;
  310. strncpy(p->response, "(No Response)", sizeof(p->response)-1);
  311. do {
  312. res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
  313. if (res < 0) {
  314. return -1;
  315. }
  316. /* Read a response */
  317. fgets(p->response, sizeof(p->response), p->f);
  318. #if 0
  319. fprintf(stderr, "Modem said: %s", p->response);
  320. #endif
  321. if (!strncasecmp(p->response, result, strlen(result)))
  322. return 0;
  323. } while(timeout > 0);
  324. return -1;
  325. }
  326. void ast_modem_trim(char *s)
  327. {
  328. int x;
  329. x = strlen(s) - 1;
  330. while(x >= 0) {
  331. if ((s[x] != '\r') && (s[x] != '\n') && (s[x] != ' '))
  332. break;
  333. s[x] = '\0';
  334. x--;
  335. }
  336. }
  337. static int modem_setup(struct ast_modem_pvt *p, int baudrate)
  338. {
  339. /* Make sure there's a modem there and that it's in a reasonable
  340. mode. Set the baud rate, etc. */
  341. char identity[256];
  342. char *ident = NULL;
  343. char etx[2] = { 0x10, '!' };
  344. if (option_debug)
  345. ast_log(LOG_DEBUG, "Setting up modem %s\n", p->dev);
  346. if (ast_modem_send(p, etx, 2)) {
  347. ast_log(LOG_WARNING, "Failed to send ETX?\n");
  348. return -1;
  349. }
  350. if (ast_modem_send(p, "\r\n", 2)) {
  351. ast_log(LOG_WARNING, "Failed to send enter?\n");
  352. return -1;
  353. }
  354. usleep(10000);
  355. /* Read any outstanding stuff */
  356. while(!ast_modem_read_response(p, 0));
  357. if (ast_modem_send(p, "ATZ", 0)) {
  358. ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
  359. return -1;
  360. }
  361. if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
  362. ast_log(LOG_WARNING, "Modem reset failed: %s\n", p->response);
  363. return -1;
  364. }
  365. if (ast_modem_send(p, p->initstr, 0)) {
  366. ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
  367. return -1;
  368. }
  369. if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
  370. ast_log(LOG_WARNING, "Modem initialization failed: %s\n", p->response);
  371. return -1;
  372. }
  373. if (ast_modem_send(p, "ATI3", 0)) {
  374. ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
  375. return -1;
  376. }
  377. if (ast_modem_read_response(p, ECHO_TIMEOUT)) {
  378. ast_log(LOG_WARNING, "Modem did not provide identification\n");
  379. return -1;
  380. }
  381. strncpy(identity, p->response, sizeof(identity)-1);
  382. ast_modem_trim(identity);
  383. if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
  384. ast_log(LOG_WARNING, "Modem did not provide identification\n");
  385. return -1;
  386. }
  387. if (!strcasecmp(mtype, "autodetect")) {
  388. p->mc = find_capability(identity);
  389. if (!p->mc) {
  390. ast_log(LOG_WARNING, "Unable to autodetect modem. You'll need to specify a driver in modem.conf. Please report modem identification (%s) and which driver works to markster@linux-support.net.\n", identity);
  391. return -1;
  392. }
  393. } else {
  394. p->mc = find_driver(mtype);
  395. if (!p->mc) {
  396. ast_log(LOG_WARNING, "No driver for modem type '%s'\n", mtype);
  397. return -1;
  398. }
  399. }
  400. if (p->mc->init) {
  401. if (p->mc->init(p)) {
  402. ast_log(LOG_WARNING, "Modem Initialization Failed on '%s', driver %s.\n", p->dev, p->mc->name);
  403. p->mc->decusecnt();
  404. return -1;
  405. }
  406. }
  407. if (option_verbose > 2) {
  408. ast_verbose(VERBOSE_PREFIX_3 "Configured modem %s with driver %s (%s)\n", p->dev, p->mc->name, p->mc->identify ? (ident = p->mc->identify(p)) : "No identification");
  409. }
  410. if (ident)
  411. free(ident);
  412. return 0;
  413. }
  414. static int modem_hangup(struct ast_channel *ast)
  415. {
  416. struct ast_modem_pvt *p;
  417. if (option_debug)
  418. ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
  419. p = ast->tech_pvt;
  420. /* Hang up */
  421. if (p->mc->hangup)
  422. p->mc->hangup(p);
  423. /* Re-initialize */
  424. if (p->mc->init)
  425. p->mc->init(p);
  426. ast_setstate(ast, AST_STATE_DOWN);
  427. memset(p->cid_num, 0, sizeof(p->cid_num));
  428. memset(p->cid_name, 0, sizeof(p->cid_name));
  429. memset(p->dnid, 0, sizeof(p->dnid));
  430. ((struct ast_modem_pvt *)(ast->tech_pvt))->owner = NULL;
  431. ast_mutex_lock(&usecnt_lock);
  432. usecnt--;
  433. if (usecnt < 0)
  434. ast_log(LOG_WARNING, "Usecnt < 0???\n");
  435. ast_mutex_unlock(&usecnt_lock);
  436. ast_update_use_count();
  437. if (option_verbose > 2)
  438. ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
  439. ast->tech_pvt = NULL;
  440. ast_setstate(ast, AST_STATE_DOWN);
  441. restart_monitor();
  442. return 0;
  443. }
  444. static int modem_answer(struct ast_channel *ast)
  445. {
  446. struct ast_modem_pvt *p;
  447. int res=0;
  448. if (option_debug)
  449. ast_log(LOG_DEBUG, "modem_answer(%s)\n", ast->name);
  450. p = ast->tech_pvt;
  451. if (p->mc->answer) {
  452. res = p->mc->answer(p);
  453. }
  454. if (!res) {
  455. ast->rings = 0;
  456. ast_setstate(ast, AST_STATE_UP);
  457. }
  458. return res;
  459. }
  460. #if 0
  461. static char modem_2digit(char c)
  462. {
  463. if (c == 12)
  464. return '#';
  465. else if (c == 11)
  466. return '*';
  467. else if ((c < 10) && (c >= 0))
  468. return '0' + c - 1;
  469. else
  470. return '?';
  471. }
  472. #endif
  473. static struct ast_frame *modem_read(struct ast_channel *ast)
  474. {
  475. struct ast_modem_pvt *p = ast->tech_pvt;
  476. struct ast_frame *fr=NULL;
  477. if (p->mc->read)
  478. fr = p->mc->read(p);
  479. return fr;
  480. }
  481. static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
  482. {
  483. int res=0;
  484. long flags;
  485. struct ast_modem_pvt *p = ast->tech_pvt;
  486. /* Modems tend to get upset when they receive data whilst in
  487. * command mode. This makes esp. dial commands short lived.
  488. * Pauline Middelink - 2002-09-24 */
  489. if (ast->_state != AST_STATE_UP)
  490. return 0;
  491. /* Temporarily make non-blocking */
  492. flags = fcntl(ast->fds[0], F_GETFL);
  493. fcntl(ast->fds[0], F_SETFL, flags | O_NONBLOCK);
  494. if (p->mc->write)
  495. res = p->mc->write(p, frame);
  496. /* Block again */
  497. fcntl(ast->fds[0], F_SETFL, flags);
  498. return res;
  499. }
  500. static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  501. {
  502. struct ast_modem_pvt *p = newchan->tech_pvt;
  503. ast_log(LOG_WARNING, "fixup called\n");
  504. if (p->owner!=oldchan) {
  505. ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n",oldchan,p->owner);
  506. return -1;
  507. }
  508. p->owner = newchan;
  509. return 0;
  510. }
  511. struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
  512. {
  513. struct ast_channel *tmp;
  514. tmp = ast_channel_alloc(1);
  515. if (tmp) {
  516. tmp->tech = &modem_tech;
  517. snprintf(tmp->name, sizeof(tmp->name), "Modem[%s]/%s", i->mc->name, i->dev + 5);
  518. tmp->type = type;
  519. tmp->fds[0] = i->fd;
  520. tmp->nativeformats = i->mc->formats;
  521. ast_setstate(tmp, state);
  522. if (state == AST_STATE_RING)
  523. tmp->rings = 1;
  524. tmp->tech_pvt = i;
  525. strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
  526. if (!ast_strlen_zero(i->cid_num))
  527. tmp->cid.cid_num = strdup(i->cid_num);
  528. if (!ast_strlen_zero(i->cid_name))
  529. tmp->cid.cid_name = strdup(i->cid_name);
  530. if (!ast_strlen_zero(i->language))
  531. strncpy(tmp->language,i->language, sizeof(tmp->language)-1);
  532. if (!ast_strlen_zero(i->dnid))
  533. strncpy(tmp->exten, i->dnid, sizeof(tmp->exten) - 1);
  534. i->owner = tmp;
  535. ast_mutex_lock(&usecnt_lock);
  536. usecnt++;
  537. ast_mutex_unlock(&usecnt_lock);
  538. ast_update_use_count();
  539. if (state != AST_STATE_DOWN) {
  540. if (ast_pbx_start(tmp)) {
  541. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
  542. ast_hangup(tmp);
  543. tmp = NULL;
  544. }
  545. }
  546. } else
  547. ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
  548. return tmp;
  549. }
  550. static void modem_mini_packet(struct ast_modem_pvt *i)
  551. {
  552. struct ast_frame *fr;
  553. fr = i->mc->read(i);
  554. if (!fr) return;
  555. if (fr->frametype == AST_FRAME_CONTROL) {
  556. if (fr->subclass == AST_CONTROL_RING) {
  557. ast_modem_new(i, AST_STATE_RING);
  558. }
  559. }
  560. }
  561. static void *do_monitor(void *data)
  562. {
  563. fd_set rfds, efds;
  564. int n, res;
  565. struct ast_modem_pvt *i;
  566. /* This thread monitors all the frame relay interfaces which are not yet in use
  567. (and thus do not have a separate thread) indefinitely */
  568. /* From here on out, we die whenever asked */
  569. #if 0
  570. if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
  571. ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
  572. return NULL;
  573. }
  574. #endif
  575. for(;;) {
  576. /* Don't let anybody kill us right away. Nobody should lock the interface list
  577. and wait for the monitor list, but the other way around is okay. */
  578. if (ast_mutex_lock(&monlock)) {
  579. ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
  580. return NULL;
  581. }
  582. /* Lock the interface list */
  583. if (ast_mutex_lock(&iflock)) {
  584. ast_log(LOG_ERROR, "Unable to grab interface lock\n");
  585. ast_mutex_unlock(&monlock);
  586. return NULL;
  587. }
  588. /* Build the stuff we're going to select on, that is the socket of every
  589. ast_modem_pvt that does not have an associated owner channel */
  590. n = -1;
  591. FD_ZERO(&rfds);
  592. FD_ZERO(&efds);
  593. i = iflist;
  594. while(i) {
  595. if (FD_ISSET(i->fd, &rfds))
  596. ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
  597. if (!i->owner) {
  598. /* This needs to be watched, as it lacks an owner */
  599. FD_SET(i->fd, &rfds);
  600. FD_SET(i->fd, &efds);
  601. if (i->fd > n)
  602. n = i->fd;
  603. }
  604. i = i->next;
  605. }
  606. /* Okay, now that we know what to do, release the interface lock */
  607. ast_mutex_unlock(&iflock);
  608. /* And from now on, we're okay to be killed, so release the monitor lock as well */
  609. ast_mutex_unlock(&monlock);
  610. #if 0
  611. ast_log(LOG_DEBUG, "In monitor, n=%d, pid=%d\n", n, getpid());
  612. #endif
  613. /* Wait indefinitely for something to happen */
  614. pthread_testcancel();
  615. res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
  616. pthread_testcancel();
  617. /* Okay, select has finished. Let's see what happened. */
  618. if (res < 1) {
  619. if ((errno != EINTR) && (errno != EAGAIN))
  620. ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
  621. continue;
  622. }
  623. /* Alright, lock the interface list again, and let's look and see what has
  624. happened */
  625. if (ast_mutex_lock(&iflock)) {
  626. ast_log(LOG_WARNING, "Unable to lock the interface list\n");
  627. continue;
  628. }
  629. i = iflist;
  630. while(i) {
  631. if (FD_ISSET(i->fd, &rfds) || FD_ISSET(i->fd, &efds)) {
  632. if (i->owner) {
  633. ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d, %s)...\n", i->fd, i->dev);
  634. i = i->next;
  635. continue;
  636. }
  637. modem_mini_packet(i);
  638. }
  639. i=i->next;
  640. }
  641. ast_mutex_unlock(&iflock);
  642. }
  643. /* Never reached */
  644. return NULL;
  645. }
  646. static int restart_monitor()
  647. {
  648. /* If we're supposed to be stopped -- stay stopped */
  649. if (monitor_thread == AST_PTHREADT_STOP)
  650. return 0;
  651. if (ast_mutex_lock(&monlock)) {
  652. ast_log(LOG_WARNING, "Unable to lock monitor\n");
  653. return -1;
  654. }
  655. if (monitor_thread == pthread_self()) {
  656. ast_mutex_unlock(&monlock);
  657. ast_log(LOG_WARNING, "Cannot kill myself\n");
  658. return -1;
  659. }
  660. if (monitor_thread != AST_PTHREADT_NULL) {
  661. pthread_cancel(monitor_thread);
  662. /* Nudge it a little, as it's probably stuck in select */
  663. pthread_kill(monitor_thread, SIGURG);
  664. pthread_join(monitor_thread, NULL);
  665. }
  666. /* Start a new monitor */
  667. if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
  668. ast_mutex_unlock(&monlock);
  669. ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
  670. return -1;
  671. }
  672. ast_mutex_unlock(&monlock);
  673. return 0;
  674. }
  675. static void stty(struct ast_modem_pvt *p)
  676. {
  677. struct termios mode;
  678. memset(&mode, 0, sizeof(mode));
  679. if (tcgetattr(p->fd, &mode)) {
  680. ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", p->dev, strerror(errno));
  681. return;
  682. }
  683. #ifndef SOLARIS
  684. cfmakeraw(&mode);
  685. #else
  686. mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
  687. |INLCR|IGNCR|ICRNL|IXON);
  688. mode.c_oflag &= ~OPOST;
  689. mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
  690. mode.c_cflag &= ~(CSIZE|PARENB);
  691. mode.c_cflag |= CS8;
  692. #endif
  693. cfsetispeed(&mode, B115200);
  694. cfsetospeed(&mode, B115200);
  695. if (tcsetattr(p->fd, TCSANOW, &mode))
  696. ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", p->dev, strerror(errno));
  697. }
  698. static struct ast_modem_pvt *mkif(char *iface)
  699. {
  700. /* Make a ast_modem_pvt structure for this interface */
  701. struct ast_modem_pvt *tmp;
  702. #if 0
  703. int flags;
  704. #endif
  705. tmp = malloc(sizeof(struct ast_modem_pvt));
  706. if (tmp) {
  707. memset(tmp, 0, sizeof(struct ast_modem_pvt));
  708. tmp->fd = open(iface, O_RDWR | O_NONBLOCK);
  709. if (tmp->fd < 0) {
  710. ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
  711. free(tmp);
  712. return NULL;
  713. }
  714. strncpy(tmp->language, language, sizeof(tmp->language)-1);
  715. strncpy(tmp->msn, msn, sizeof(tmp->msn)-1);
  716. strncpy(tmp->incomingmsn, incomingmsn, sizeof(tmp->incomingmsn)-1);
  717. tmp->dtmfmode = dtmfmode;
  718. tmp->dtmfmodegen = dtmfmodegen;
  719. snprintf(tmp->outgoingmsn, sizeof(tmp->outgoingmsn), ",%s,", outgoingmsn);
  720. strncpy(tmp->dev, iface, sizeof(tmp->dev)-1);
  721. /* Maybe in the future we want to allow variable
  722. serial settings */
  723. stty(tmp);
  724. tmp->f = fdopen(tmp->fd, "w+");
  725. /* Disable buffering */
  726. setvbuf(tmp->f, NULL, _IONBF,0);
  727. if (tmp->f < 0) {
  728. ast_log(LOG_WARNING, "Unable to fdopen '%s'\n", iface);
  729. free(tmp);
  730. return NULL;
  731. }
  732. tmp->owner = NULL;
  733. tmp->ministate = 0;
  734. tmp->stripmsd = stripmsd;
  735. tmp->dialtype = dialtype;
  736. tmp->mode = gmode;
  737. tmp->group = cur_group;
  738. memset(tmp->cid_num, 0, sizeof(tmp->cid_num));
  739. memset(tmp->cid_name, 0, sizeof(tmp->cid_name));
  740. strncpy(tmp->context, context, sizeof(tmp->context)-1);
  741. strncpy(tmp->initstr, initstr, sizeof(tmp->initstr)-1);
  742. tmp->next = NULL;
  743. tmp->obuflen = 0;
  744. if (modem_setup(tmp, baudrate) < 0) {
  745. ast_log(LOG_WARNING, "Unable to configure modem '%s'\n", iface);
  746. free(tmp);
  747. return NULL;
  748. }
  749. }
  750. return tmp;
  751. }
  752. static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause)
  753. {
  754. int oldformat;
  755. struct ast_modem_pvt *p;
  756. struct ast_channel *tmp = NULL;
  757. char dev[80];
  758. ast_group_t group = 0;
  759. int groupint;
  760. char *stringp=NULL;
  761. strncpy(dev, (char *)data, sizeof(dev)-1);
  762. stringp=dev;
  763. strsep(&stringp, ":");
  764. oldformat = format;
  765. if (!dep_warning) {
  766. ast_log(LOG_WARNING, "This channel driver is deprecated. Please see the UPGRADE.txt file.\n");
  767. dep_warning = 1;
  768. }
  769. if (dev[0]=='g' && isdigit(dev[1])) {
  770. /* Retrieve the group number */
  771. if (sscanf(dev+1, "%u", &groupint) < 1) {
  772. ast_log(LOG_WARNING, "Unable to determine group from [%s]\n", (char *)data);
  773. return NULL;
  774. }
  775. group = 1 << groupint;
  776. }
  777. /* Search for an unowned channel */
  778. if (ast_mutex_lock(&iflock)) {
  779. ast_log(LOG_ERROR, "Unable to lock interface list???\n");
  780. return NULL;
  781. }
  782. p = iflist;
  783. while(p) {
  784. if (group) {
  785. /* if it belongs to the proper group, and the format matches
  786. * and it is not in use, we found a candidate! */
  787. if (p->group & group &&
  788. p->mc->formats & format &&
  789. !p->owner) {
  790. /* XXX Not quite sure that not having an owner is
  791. * sufficient evidence of beeing a free device XXX */
  792. tmp = ast_modem_new(p, AST_STATE_DOWN);
  793. restart_monitor();
  794. break;
  795. }
  796. } else {
  797. if (!strcmp(dev, p->dev + 5)) {
  798. if (p->mc->formats & format) {
  799. if (!p->owner) {
  800. tmp = ast_modem_new(p, AST_STATE_DOWN);
  801. restart_monitor();
  802. break;
  803. } else
  804. ast_log(LOG_WARNING, "Device '%s' is busy\n", p->dev);
  805. } else
  806. ast_log(LOG_WARNING, "Asked for a format %s line on %s\n", ast_getformatname(format), p->dev);
  807. break;
  808. }
  809. }
  810. p = p->next;
  811. }
  812. if (!p)
  813. ast_log(LOG_WARNING, "Requested device '%s' does not exist\n", dev);
  814. ast_mutex_unlock(&iflock);
  815. return tmp;
  816. }
  817. static ast_group_t get_group(char *s)
  818. {
  819. char *piece;
  820. int start, finish,x;
  821. ast_group_t group = 0;
  822. char *copy = ast_strdupa(s);
  823. char *stringp=NULL;
  824. if (!copy) {
  825. ast_log(LOG_ERROR, "Out of memory\n");
  826. return 0;
  827. }
  828. stringp=copy;
  829. piece = strsep(&stringp, ",");
  830. while(piece) {
  831. if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
  832. /* Range */
  833. } else if (sscanf(piece, "%d", &start)) {
  834. /* Just one */
  835. finish = start;
  836. } else {
  837. ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece);
  838. return 0;
  839. }
  840. piece = strsep(&stringp, ",");
  841. for (x=start;x<=finish;x++) {
  842. if ((x > 63) || (x < 0)) {
  843. ast_log(LOG_WARNING, "Ignoring invalid group %d\n", x);
  844. break;
  845. }
  846. group |= (1 << x);
  847. }
  848. }
  849. return group;
  850. }
  851. static int __unload_module(void)
  852. {
  853. struct ast_modem_pvt *p, *pl;
  854. /* First, take us out of the channel loop */
  855. ast_channel_unregister(&modem_tech);
  856. if (!ast_mutex_lock(&iflock)) {
  857. /* Hangup all interfaces if they have an owner */
  858. p = iflist;
  859. while(p) {
  860. if (p->owner)
  861. ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
  862. p = p->next;
  863. }
  864. iflist = NULL;
  865. ast_mutex_unlock(&iflock);
  866. } else {
  867. ast_log(LOG_WARNING, "Unable to lock the monitor\n");
  868. return -1;
  869. }
  870. if (!ast_mutex_lock(&monlock)) {
  871. if (monitor_thread != AST_PTHREADT_NULL && monitor_thread != AST_PTHREADT_STOP) {
  872. pthread_cancel(monitor_thread);
  873. pthread_join(monitor_thread, NULL);
  874. }
  875. monitor_thread = AST_PTHREADT_STOP;
  876. ast_mutex_unlock(&monlock);
  877. } else {
  878. ast_log(LOG_WARNING, "Unable to lock the monitor\n");
  879. return -1;
  880. }
  881. if (!ast_mutex_lock(&iflock)) {
  882. /* Destroy all the interfaces and free their memory */
  883. p = iflist;
  884. while(p) {
  885. /* Close the socket, assuming it's real */
  886. if (p->fd > -1)
  887. close(p->fd);
  888. pl = p;
  889. p = p->next;
  890. /* Free associated memory */
  891. free(pl);
  892. }
  893. iflist = NULL;
  894. ast_mutex_unlock(&iflock);
  895. } else {
  896. ast_log(LOG_WARNING, "Unable to lock the monitor\n");
  897. return -1;
  898. }
  899. return 0;
  900. }
  901. int unload_module()
  902. {
  903. return __unload_module();
  904. }
  905. int load_module()
  906. {
  907. struct ast_config *cfg;
  908. struct ast_variable *v;
  909. struct ast_modem_pvt *tmp;
  910. char driver[80];
  911. cfg = ast_config_load(config);
  912. /* We *must* have a config file otherwise stop immediately */
  913. if (!cfg) {
  914. ast_log(LOG_ERROR, "Unable to load config %s\n", config);
  915. return -1;
  916. }
  917. if (ast_mutex_lock(&iflock)) {
  918. /* It's a little silly to lock it, but we mind as well just to be sure */
  919. ast_log(LOG_ERROR, "Unable to lock interface list???\n");
  920. return -1;
  921. }
  922. v = ast_variable_browse(cfg, "interfaces");
  923. while(v) {
  924. /* Create the interface list */
  925. if (!strcasecmp(v->name, "device")) {
  926. tmp = mkif(v->value);
  927. if (tmp) {
  928. tmp->next = iflist;
  929. iflist = tmp;
  930. } else {
  931. ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
  932. ast_config_destroy(cfg);
  933. ast_mutex_unlock(&iflock);
  934. __unload_module();
  935. return -1;
  936. }
  937. } else if (!strcasecmp(v->name, "driver")) {
  938. snprintf(driver, sizeof(driver), "chan_modem_%s.so", v->value);
  939. if (option_verbose > 1)
  940. ast_verbose(VERBOSE_PREFIX_2 "Loading modem driver %s", driver);
  941. if (ast_load_resource(driver)) {
  942. ast_log(LOG_ERROR, "Failed to load driver %s\n", driver);
  943. ast_config_destroy(cfg);
  944. ast_mutex_unlock(&iflock);
  945. __unload_module();
  946. return -1;
  947. }
  948. } else if (!strcasecmp(v->name, "mode")) {
  949. if (!strncasecmp(v->value, "ri", 2))
  950. gmode = MODEM_MODE_WAIT_RING;
  951. else if (!strncasecmp(v->value, "im", 2))
  952. gmode = MODEM_MODE_IMMEDIATE;
  953. else if (!strncasecmp(v->value, "an", 2))
  954. gmode = MODEM_MODE_WAIT_ANSWER;
  955. else
  956. ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
  957. } else if (!strcasecmp(v->name, "stripmsd")) {
  958. stripmsd = atoi(v->value);
  959. } else if (!strcasecmp(v->name, "type")) {
  960. strncpy(mtype, v->value, sizeof(mtype)-1);
  961. } else if (!strcasecmp(v->name, "initstr")) {
  962. strncpy(initstr, v->value, sizeof(initstr)-1);
  963. } else if (!strcasecmp(v->name, "dialtype")) {
  964. dialtype = toupper(v->value[0]);
  965. } else if (!strcasecmp(v->name, "context")) {
  966. strncpy(context, v->value, sizeof(context)-1);
  967. } else if (!strcasecmp(v->name, "msn")) {
  968. strncpy(msn, v->value, sizeof(msn)-1);
  969. } else if (!strcasecmp(v->name, "incomingmsn")) {
  970. strncpy(incomingmsn, v->value, sizeof(incomingmsn)-1);
  971. } else if (!strcasecmp(v->name, "dtmfmode")) {
  972. char tmp[80];
  973. char *alt;
  974. strncpy(tmp, v->value, sizeof(tmp) - 1);
  975. alt = strchr(tmp, '/');
  976. if (!strcasecmp(tmp, "none"))
  977. dtmfmode=MODEM_DTMF_NONE;
  978. else if (!strcasecmp(tmp, "asterisk"))
  979. dtmfmode = MODEM_DTMF_AST;
  980. else if (!strcasecmp(tmp, "i4l"))
  981. dtmfmode = MODEM_DTMF_I4L;
  982. else {
  983. ast_log(LOG_WARNING, "Unknown dtmf detection mode '%s', using 'asterisk'\n", v->value);
  984. dtmfmode = MODEM_DTMF_AST;
  985. }
  986. if (alt) {
  987. if (!strcasecmp(alt, "none"))
  988. dtmfmodegen=MODEM_DTMF_NONE;
  989. else if (!strcasecmp(alt, "asterisk"))
  990. dtmfmodegen = MODEM_DTMF_AST;
  991. else if (!strcasecmp(alt, "i4l"))
  992. dtmfmodegen = MODEM_DTMF_I4L;
  993. else if (!strcasecmp(alt, "both"))
  994. dtmfmodegen = MODEM_DTMF_I4L | MODEM_DTMF_AST;
  995. else {
  996. ast_log(LOG_WARNING, "Unknown dtmf generation mode '%s', using 'asterisk'\n", v->value);
  997. dtmfmodegen = MODEM_DTMF_AST;
  998. }
  999. } else
  1000. dtmfmodegen = dtmfmode;
  1001. } else if (!strcasecmp(v->name, "outgoingmsn")) {
  1002. strncpy(outgoingmsn, v->value, sizeof(outgoingmsn)-1);
  1003. } else if (!strcasecmp(v->name, "language")) {
  1004. strncpy(language, v->value, sizeof(language)-1);
  1005. } else if (!strcasecmp(v->name, "group")) {
  1006. cur_group = get_group(v->value);
  1007. }
  1008. v = v->next;
  1009. }
  1010. ast_mutex_unlock(&iflock);
  1011. if (ast_channel_register(&modem_tech)) {
  1012. ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
  1013. ast_config_destroy(cfg);
  1014. __unload_module();
  1015. return -1;
  1016. }
  1017. ast_config_destroy(cfg);
  1018. /* And start the monitor for the first time */
  1019. restart_monitor();
  1020. return 0;
  1021. }
  1022. int usecount(void)
  1023. {
  1024. return usecnt;
  1025. }
  1026. char *description()
  1027. {
  1028. return (char *) desc;
  1029. }
  1030. char *key()
  1031. {
  1032. return ASTERISK_GPL_KEY;
  1033. }