chan_features.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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 feature Proxy Channel
  21. *
  22. * \note *** Experimental code ****
  23. *
  24. * \ingroup channel_drivers
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <unistd.h>
  29. #include <sys/socket.h>
  30. #include <errno.h>
  31. #include <stdlib.h>
  32. #include <fcntl.h>
  33. #include <netdb.h>
  34. #include <netinet/in.h>
  35. #include <arpa/inet.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/lock.h"
  47. #include "asterisk/sched.h"
  48. #include "asterisk/io.h"
  49. #include "asterisk/rtp.h"
  50. #include "asterisk/acl.h"
  51. #include "asterisk/callerid.h"
  52. #include "asterisk/file.h"
  53. #include "asterisk/cli.h"
  54. #include "asterisk/app.h"
  55. #include "asterisk/musiconhold.h"
  56. #include "asterisk/manager.h"
  57. static const char desc[] = "Feature Proxy Channel";
  58. static const char type[] = "Feature";
  59. static const char tdesc[] = "Feature Proxy Channel Driver";
  60. static int usecnt =0;
  61. AST_MUTEX_DEFINE_STATIC(usecnt_lock);
  62. #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
  63. /* Protect the interface list (of feature_pvt's) */
  64. AST_MUTEX_DEFINE_STATIC(featurelock);
  65. struct feature_sub {
  66. struct ast_channel *owner;
  67. int inthreeway;
  68. int pfd;
  69. int timingfdbackup;
  70. int alertpipebackup[2];
  71. };
  72. static struct feature_pvt {
  73. ast_mutex_t lock; /* Channel private lock */
  74. char tech[AST_MAX_EXTENSION]; /* Technology to abstract */
  75. char dest[AST_MAX_EXTENSION]; /* Destination to abstract */
  76. struct ast_channel *subchan;
  77. struct feature_sub subs[3]; /* Subs */
  78. struct ast_channel *owner; /* Current Master Channel */
  79. struct feature_pvt *next; /* Next entity */
  80. } *features = NULL;
  81. #define SUB_REAL 0 /* Active call */
  82. #define SUB_CALLWAIT 1 /* Call-Waiting call on hold */
  83. #define SUB_THREEWAY 2 /* Three-way call */
  84. static struct ast_channel *features_request(const char *type, int format, void *data, int *cause);
  85. static int features_digit(struct ast_channel *ast, char digit);
  86. static int features_call(struct ast_channel *ast, char *dest, int timeout);
  87. static int features_hangup(struct ast_channel *ast);
  88. static int features_answer(struct ast_channel *ast);
  89. static struct ast_frame *features_read(struct ast_channel *ast);
  90. static int features_write(struct ast_channel *ast, struct ast_frame *f);
  91. static int features_indicate(struct ast_channel *ast, int condition);
  92. static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  93. static const struct ast_channel_tech features_tech = {
  94. .type = type,
  95. .description = tdesc,
  96. .capabilities = -1,
  97. .requester = features_request,
  98. .send_digit = features_digit,
  99. .call = features_call,
  100. .hangup = features_hangup,
  101. .answer = features_answer,
  102. .read = features_read,
  103. .write = features_write,
  104. .exception = features_read,
  105. .indicate = features_indicate,
  106. .fixup = features_fixup,
  107. };
  108. static inline void init_sub(struct feature_sub *sub)
  109. {
  110. sub->inthreeway = 0;
  111. sub->pfd = -1;
  112. sub->timingfdbackup = -1;
  113. sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1;
  114. }
  115. static inline int indexof(struct feature_pvt *p, struct ast_channel *owner, int nullok)
  116. {
  117. int x;
  118. if (!owner) {
  119. ast_log(LOG_WARNING, "indexof called on NULL owner??\n");
  120. return -1;
  121. }
  122. for (x=0; x<3; x++) {
  123. if (owner == p->subs[x].owner)
  124. return x;
  125. }
  126. return -1;
  127. }
  128. #if 0
  129. static void wakeup_sub(struct feature_pvt *p, int a)
  130. {
  131. struct ast_frame null = { AST_FRAME_NULL, };
  132. for (;;) {
  133. if (p->subs[a].owner) {
  134. if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
  135. ast_mutex_unlock(&p->lock);
  136. usleep(1);
  137. ast_mutex_lock(&p->lock);
  138. } else {
  139. ast_queue_frame(p->subs[a].owner, &null);
  140. ast_mutex_unlock(&p->subs[a].owner->lock);
  141. break;
  142. }
  143. } else
  144. break;
  145. }
  146. }
  147. #endif
  148. static void restore_channel(struct feature_pvt *p, int index)
  149. {
  150. /* Restore timing/alertpipe */
  151. p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
  152. p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
  153. p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
  154. p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0];
  155. p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup;
  156. }
  157. static void update_features(struct feature_pvt *p, int index)
  158. {
  159. int x;
  160. if (p->subs[index].owner) {
  161. for (x=0; x<AST_MAX_FDS; x++) {
  162. if (index)
  163. p->subs[index].owner->fds[x] = -1;
  164. else
  165. p->subs[index].owner->fds[x] = p->subchan->fds[x];
  166. }
  167. if (!index) {
  168. /* Copy timings from master channel */
  169. p->subs[index].owner->timingfd = p->subchan->timingfd;
  170. p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0];
  171. p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1];
  172. if (p->subs[index].owner->nativeformats != p->subchan->readformat) {
  173. p->subs[index].owner->nativeformats = p->subchan->readformat;
  174. if (p->subs[index].owner->readformat)
  175. ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat);
  176. if (p->subs[index].owner->writeformat)
  177. ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat);
  178. }
  179. } else{
  180. restore_channel(p, index);
  181. }
  182. }
  183. }
  184. #if 0
  185. static void swap_subs(struct feature_pvt *p, int a, int b)
  186. {
  187. int tinthreeway;
  188. struct ast_channel *towner;
  189. ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
  190. towner = p->subs[a].owner;
  191. tinthreeway = p->subs[a].inthreeway;
  192. p->subs[a].owner = p->subs[b].owner;
  193. p->subs[a].inthreeway = p->subs[b].inthreeway;
  194. p->subs[b].owner = towner;
  195. p->subs[b].inthreeway = tinthreeway;
  196. update_features(p,a);
  197. update_features(p,b);
  198. wakeup_sub(p, a);
  199. wakeup_sub(p, b);
  200. }
  201. #endif
  202. static int features_answer(struct ast_channel *ast)
  203. {
  204. struct feature_pvt *p = ast->tech_pvt;
  205. int res = -1;
  206. int x;
  207. ast_mutex_lock(&p->lock);
  208. x = indexof(p, ast, 0);
  209. if (!x && p->subchan)
  210. res = ast_answer(p->subchan);
  211. ast_mutex_unlock(&p->lock);
  212. return res;
  213. }
  214. static struct ast_frame *features_read(struct ast_channel *ast)
  215. {
  216. static struct ast_frame null_frame = { AST_FRAME_NULL, };
  217. struct feature_pvt *p = ast->tech_pvt;
  218. struct ast_frame *f;
  219. int x;
  220. f = &null_frame;
  221. ast_mutex_lock(&p->lock);
  222. x = indexof(p, ast, 0);
  223. if (!x && p->subchan) {
  224. update_features(p, x);
  225. f = ast_read(p->subchan);
  226. }
  227. ast_mutex_unlock(&p->lock);
  228. return f;
  229. }
  230. static int features_write(struct ast_channel *ast, struct ast_frame *f)
  231. {
  232. struct feature_pvt *p = ast->tech_pvt;
  233. int res = -1;
  234. int x;
  235. ast_mutex_lock(&p->lock);
  236. x = indexof(p, ast, 0);
  237. if (!x && p->subchan)
  238. res = ast_write(p->subchan, f);
  239. ast_mutex_unlock(&p->lock);
  240. return res;
  241. }
  242. static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  243. {
  244. struct feature_pvt *p = newchan->tech_pvt;
  245. int x;
  246. ast_mutex_lock(&p->lock);
  247. if (p->owner == oldchan)
  248. p->owner = newchan;
  249. for (x = 0; x < 3; x++) {
  250. if (p->subs[x].owner == oldchan)
  251. p->subs[x].owner = newchan;
  252. }
  253. ast_mutex_unlock(&p->lock);
  254. return 0;
  255. }
  256. static int features_indicate(struct ast_channel *ast, int condition)
  257. {
  258. struct feature_pvt *p = ast->tech_pvt;
  259. int res = -1;
  260. int x;
  261. /* Queue up a frame representing the indication as a control frame */
  262. ast_mutex_lock(&p->lock);
  263. x = indexof(p, ast, 0);
  264. if (!x && p->subchan)
  265. res = ast_indicate(p->subchan, condition);
  266. ast_mutex_unlock(&p->lock);
  267. return res;
  268. }
  269. static int features_digit(struct ast_channel *ast, char digit)
  270. {
  271. struct feature_pvt *p = ast->tech_pvt;
  272. int res = -1;
  273. int x;
  274. /* Queue up a frame representing the indication as a control frame */
  275. ast_mutex_lock(&p->lock);
  276. x = indexof(p, ast, 0);
  277. if (!x && p->subchan)
  278. res = ast_senddigit(p->subchan, digit);
  279. ast_mutex_unlock(&p->lock);
  280. return res;
  281. }
  282. static int features_call(struct ast_channel *ast, char *dest, int timeout)
  283. {
  284. struct feature_pvt *p = ast->tech_pvt;
  285. int res = -1;
  286. int x;
  287. char *dest2;
  288. dest2 = strchr(dest, '/');
  289. if (dest2) {
  290. ast_mutex_lock(&p->lock);
  291. x = indexof(p, ast, 0);
  292. if (!x && p->subchan) {
  293. if (p->owner->cid.cid_num)
  294. p->subchan->cid.cid_num = strdup(p->owner->cid.cid_num);
  295. else
  296. p->subchan->cid.cid_num = NULL;
  297. if (p->owner->cid.cid_name)
  298. p->subchan->cid.cid_name = strdup(p->owner->cid.cid_name);
  299. else
  300. p->subchan->cid.cid_name = NULL;
  301. if (p->owner->cid.cid_rdnis)
  302. p->subchan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis);
  303. else
  304. p->subchan->cid.cid_rdnis = NULL;
  305. if (p->owner->cid.cid_ani)
  306. p->subchan->cid.cid_ani = strdup(p->owner->cid.cid_ani);
  307. else
  308. p->subchan->cid.cid_ani = NULL;
  309. p->subchan->cid.cid_pres = p->owner->cid.cid_pres;
  310. strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1);
  311. strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1);
  312. p->subchan->cdrflags = p->owner->cdrflags;
  313. res = ast_call(p->subchan, dest2, timeout);
  314. update_features(p, x);
  315. } else
  316. ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n");
  317. ast_mutex_unlock(&p->lock);
  318. }
  319. return res;
  320. }
  321. static int features_hangup(struct ast_channel *ast)
  322. {
  323. struct feature_pvt *p = ast->tech_pvt;
  324. struct feature_pvt *cur, *prev=NULL;
  325. int x;
  326. ast_mutex_lock(&p->lock);
  327. x = indexof(p, ast, 0);
  328. if (x > -1) {
  329. restore_channel(p, x);
  330. p->subs[x].owner = NULL;
  331. /* XXX Re-arrange, unconference, etc XXX */
  332. }
  333. ast->tech_pvt = NULL;
  334. if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
  335. ast_mutex_unlock(&p->lock);
  336. /* Remove from list */
  337. ast_mutex_lock(&featurelock);
  338. cur = features;
  339. while(cur) {
  340. if (cur == p) {
  341. if (prev)
  342. prev->next = cur->next;
  343. else
  344. features = cur->next;
  345. break;
  346. }
  347. prev = cur;
  348. cur = cur->next;
  349. }
  350. ast_mutex_unlock(&featurelock);
  351. ast_mutex_lock(&p->lock);
  352. /* And destroy */
  353. if (p->subchan)
  354. ast_hangup(p->subchan);
  355. ast_mutex_unlock(&p->lock);
  356. ast_mutex_destroy(&p->lock);
  357. free(p);
  358. return 0;
  359. }
  360. ast_mutex_unlock(&p->lock);
  361. return 0;
  362. }
  363. static struct feature_pvt *features_alloc(char *data, int format)
  364. {
  365. struct feature_pvt *tmp;
  366. char *dest=NULL;
  367. char *tech;
  368. int x;
  369. int status;
  370. struct ast_channel *chan;
  371. tech = ast_strdupa(data);
  372. if (tech) {
  373. dest = strchr(tech, '/');
  374. if (dest) {
  375. *dest = '\0';
  376. dest++;
  377. }
  378. }
  379. if (!tech || !dest) {
  380. ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n",
  381. data);
  382. return NULL;
  383. }
  384. ast_mutex_lock(&featurelock);
  385. tmp = features;
  386. while(tmp) {
  387. if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest))
  388. break;
  389. tmp = tmp->next;
  390. }
  391. ast_mutex_unlock(&featurelock);
  392. if (!tmp) {
  393. chan = ast_request(tech, format, dest, &status);
  394. if (!chan) {
  395. ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);
  396. return NULL;
  397. }
  398. tmp = malloc(sizeof(struct feature_pvt));
  399. if (tmp) {
  400. memset(tmp, 0, sizeof(struct feature_pvt));
  401. for (x=0;x<3;x++)
  402. init_sub(tmp->subs + x);
  403. ast_mutex_init(&tmp->lock);
  404. strncpy(tmp->tech, tech, sizeof(tmp->tech) - 1);
  405. strncpy(tmp->dest, dest, sizeof(tmp->dest) - 1);
  406. tmp->subchan = chan;
  407. ast_mutex_lock(&featurelock);
  408. tmp->next = features;
  409. features = tmp;
  410. ast_mutex_unlock(&featurelock);
  411. }
  412. }
  413. return tmp;
  414. }
  415. static struct ast_channel *features_new(struct feature_pvt *p, int state, int index)
  416. {
  417. struct ast_channel *tmp;
  418. int x,y;
  419. if (!p->subchan) {
  420. ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n");
  421. return NULL;
  422. }
  423. if (p->subs[index].owner) {
  424. ast_log(LOG_WARNING, "Called to put index %d already there!\n", index);
  425. return NULL;
  426. }
  427. tmp = ast_channel_alloc(0);
  428. if (!tmp) {
  429. ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
  430. return NULL;
  431. }
  432. tmp->tech = &features_tech;
  433. for (x=1;x<4;x++) {
  434. snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x);
  435. for (y=0;y<3;y++) {
  436. if (y == index)
  437. continue;
  438. if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, tmp->name))
  439. break;
  440. }
  441. if (y >= 3)
  442. break;
  443. }
  444. tmp->type = type;
  445. ast_setstate(tmp, state);
  446. tmp->writeformat = p->subchan->writeformat;
  447. tmp->rawwriteformat = p->subchan->rawwriteformat;
  448. tmp->readformat = p->subchan->readformat;
  449. tmp->rawreadformat = p->subchan->rawreadformat;
  450. tmp->nativeformats = p->subchan->readformat;
  451. tmp->tech_pvt = p;
  452. p->subs[index].owner = tmp;
  453. if (!p->owner)
  454. p->owner = tmp;
  455. ast_mutex_lock(&usecnt_lock);
  456. usecnt++;
  457. ast_mutex_unlock(&usecnt_lock);
  458. ast_update_use_count();
  459. return tmp;
  460. }
  461. static struct ast_channel *features_request(const char *type, int format, void *data, int *cause)
  462. {
  463. struct feature_pvt *p;
  464. struct ast_channel *chan = NULL;
  465. p = features_alloc(data, format);
  466. if (p && !p->subs[SUB_REAL].owner)
  467. chan = features_new(p, AST_STATE_DOWN, SUB_REAL);
  468. if (chan)
  469. update_features(p,SUB_REAL);
  470. return chan;
  471. }
  472. static int features_show(int fd, int argc, char **argv)
  473. {
  474. struct feature_pvt *p;
  475. if (argc != 3)
  476. return RESULT_SHOWUSAGE;
  477. ast_mutex_lock(&featurelock);
  478. p = features;
  479. while(p) {
  480. ast_mutex_lock(&p->lock);
  481. ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);
  482. ast_mutex_unlock(&p->lock);
  483. p = p->next;
  484. }
  485. if (!features)
  486. ast_cli(fd, "No feature channels in use\n");
  487. ast_mutex_unlock(&featurelock);
  488. return RESULT_SUCCESS;
  489. }
  490. static char show_features_usage[] =
  491. "Usage: feature show channels\n"
  492. " Provides summary information on feature channels.\n";
  493. static struct ast_cli_entry cli_show_features = {
  494. { "feature", "show", "channels", NULL }, features_show,
  495. "Show status of feature channels", show_features_usage, NULL };
  496. int load_module()
  497. {
  498. /* Make sure we can register our sip channel type */
  499. if (ast_channel_register(&features_tech)) {
  500. ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
  501. return -1;
  502. }
  503. ast_cli_register(&cli_show_features);
  504. return 0;
  505. }
  506. int reload()
  507. {
  508. return 0;
  509. }
  510. int unload_module()
  511. {
  512. struct feature_pvt *p;
  513. /* First, take us out of the channel loop */
  514. ast_cli_unregister(&cli_show_features);
  515. ast_channel_unregister(&features_tech);
  516. if (!ast_mutex_lock(&featurelock)) {
  517. /* Hangup all interfaces if they have an owner */
  518. p = features;
  519. while(p) {
  520. if (p->owner)
  521. ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
  522. p = p->next;
  523. }
  524. features = NULL;
  525. ast_mutex_unlock(&featurelock);
  526. } else {
  527. ast_log(LOG_WARNING, "Unable to lock the monitor\n");
  528. return -1;
  529. }
  530. return 0;
  531. }
  532. int usecount()
  533. {
  534. return usecnt;
  535. }
  536. char *key()
  537. {
  538. return ASTERISK_GPL_KEY;
  539. }
  540. char *description()
  541. {
  542. return (char *) desc;
  543. }