chan_nbs.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Generic Linux Telephony Interface driver
  5. *
  6. * Copyright (C) 1999, Mark Spencer
  7. *
  8. * Mark Spencer <markster@linux-support.net>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. */
  13. #include <stdio.h>
  14. #include <pthread.h>
  15. #include <string.h>
  16. #include <asterisk/lock.h>
  17. #include <asterisk/channel.h>
  18. #include <asterisk/channel_pvt.h>
  19. #include <asterisk/config.h>
  20. #include <asterisk/logger.h>
  21. #include <asterisk/module.h>
  22. #include <asterisk/pbx.h>
  23. #include <asterisk/options.h>
  24. #include <sys/socket.h>
  25. #include <sys/time.h>
  26. #include <errno.h>
  27. #include <unistd.h>
  28. #include <stdlib.h>
  29. #include <arpa/inet.h>
  30. #include <fcntl.h>
  31. #include <sys/ioctl.h>
  32. #include <nbs.h>
  33. static char *desc = "Network Broadcast Sound Support";
  34. static char *type = "NBS";
  35. static char *tdesc = "Network Broadcast Sound Driver";
  36. static int usecnt =0;
  37. /* Only linear is allowed */
  38. static int prefformat = AST_FORMAT_SLINEAR;
  39. static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
  40. static char context[AST_MAX_EXTENSION] = "default";
  41. /* NBS creates private structures on demand */
  42. struct nbs_pvt {
  43. NBS *nbs;
  44. struct ast_channel *owner; /* Channel we belong to, possibly NULL */
  45. char app[16]; /* Our app */
  46. char stream[80]; /* Our stream */
  47. struct ast_frame fr; /* "null" frame */
  48. };
  49. static int nbs_call(struct ast_channel *ast, char *dest, int timeout)
  50. {
  51. struct nbs_pvt *p;
  52. p = ast->pvt->pvt;
  53. if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
  54. ast_log(LOG_WARNING, "nbs_call called on %s, neither down nor reserved\n", ast->name);
  55. return -1;
  56. }
  57. /* When we call, it just works, really, there's no destination... Just
  58. ring the phone and wait for someone to answer */
  59. if (option_debug)
  60. ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name);
  61. /* If we can't connect, return congestion */
  62. if (nbs_connect(p->nbs)) {
  63. ast_log(LOG_WARNING, "NBS Connection failed on %s\n", ast->name);
  64. ast_queue_control(ast, AST_CONTROL_CONGESTION, 0);
  65. } else {
  66. ast_setstate(ast, AST_STATE_RINGING);
  67. ast_queue_control(ast, AST_CONTROL_ANSWER, 0);
  68. }
  69. return 0;
  70. }
  71. static void nbs_destroy(struct nbs_pvt *p)
  72. {
  73. if (p->nbs)
  74. nbs_delstream(p->nbs);
  75. free(p);
  76. }
  77. static struct nbs_pvt *nbs_alloc(void *data)
  78. {
  79. struct nbs_pvt *p;
  80. int flags = 0;
  81. char stream[256] = "";
  82. char *opts;
  83. strncpy(stream, data, sizeof(stream) - 1);
  84. if ((opts = strchr(stream, ':'))) {
  85. *opts = '\0';
  86. opts++;
  87. } else
  88. opts = "";
  89. p = malloc(sizeof(struct nbs_pvt));
  90. if (p) {
  91. memset(p, 0, sizeof(struct nbs_pvt));
  92. if (strlen(opts)) {
  93. if (strchr(opts, 'm'))
  94. flags |= NBS_FLAG_MUTE;
  95. if (strchr(opts, 'o'))
  96. flags |= NBS_FLAG_OVERSPEAK;
  97. if (strchr(opts, 'e'))
  98. flags |= NBS_FLAG_EMERGENCY;
  99. if (strchr(opts, 'O'))
  100. flags |= NBS_FLAG_OVERRIDE;
  101. } else
  102. flags = NBS_FLAG_OVERSPEAK;
  103. strncpy(p->stream, stream, sizeof(p->stream) - 1);
  104. p->nbs = nbs_newstream("asterisk", stream, flags);
  105. if (!p->nbs) {
  106. ast_log(LOG_WARNING, "Unable to allocate new NBS stream '%s' with flags %d\n", stream, flags);
  107. free(p);
  108. p = NULL;
  109. } else {
  110. /* Set for 8000 hz mono, 640 samples */
  111. nbs_setbitrate(p->nbs, 8000);
  112. nbs_setchannels(p->nbs, 1);
  113. nbs_setblocksize(p->nbs, 640);
  114. nbs_setblocking(p->nbs, 0);
  115. }
  116. }
  117. return p;
  118. }
  119. static int nbs_hangup(struct ast_channel *ast)
  120. {
  121. struct nbs_pvt *p;
  122. p = ast->pvt->pvt;
  123. if (option_debug)
  124. ast_log(LOG_DEBUG, "nbs_hangup(%s)\n", ast->name);
  125. if (!ast->pvt->pvt) {
  126. ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
  127. return 0;
  128. }
  129. nbs_destroy(p);
  130. ast->pvt->pvt = NULL;
  131. ast_setstate(ast, AST_STATE_DOWN);
  132. return 0;
  133. }
  134. static struct ast_frame *nbs_xread(struct ast_channel *ast)
  135. {
  136. struct nbs_pvt *p = ast->pvt->pvt;
  137. /* Some nice norms */
  138. p->fr.datalen = 0;
  139. p->fr.samples = 0;
  140. p->fr.data = NULL;
  141. p->fr.src = type;
  142. p->fr.offset = 0;
  143. p->fr.mallocd=0;
  144. ast_log(LOG_DEBUG, "Returning null frame on %s\n", ast->name);
  145. return &p->fr;
  146. }
  147. static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
  148. {
  149. struct nbs_pvt *p = ast->pvt->pvt;
  150. /* Write a frame of (presumably voice) data */
  151. if (frame->frametype != AST_FRAME_VOICE) {
  152. if (frame->frametype != AST_FRAME_IMAGE)
  153. ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
  154. return 0;
  155. }
  156. if (!(frame->subclass &
  157. (AST_FORMAT_SLINEAR))) {
  158. ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
  159. return 0;
  160. }
  161. if (ast->_state != AST_STATE_UP) {
  162. /* Don't try tos end audio on-hook */
  163. return 0;
  164. }
  165. if (nbs_write(p->nbs, frame->data, frame->datalen / 2) < 0)
  166. return -1;
  167. return 0;
  168. }
  169. static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
  170. {
  171. struct ast_channel *tmp;
  172. tmp = ast_channel_alloc(1);
  173. if (tmp) {
  174. snprintf(tmp->name, sizeof(tmp->name), "NBS/%s", i->stream);
  175. tmp->type = type;
  176. tmp->fds[0] = nbs_fd(i->nbs);
  177. tmp->nativeformats = prefformat;
  178. tmp->pvt->rawreadformat = prefformat;
  179. tmp->pvt->rawwriteformat = prefformat;
  180. tmp->writeformat = prefformat;
  181. tmp->readformat = prefformat;
  182. ast_setstate(tmp, state);
  183. if (state == AST_STATE_RING)
  184. tmp->rings = 1;
  185. tmp->pvt->pvt = i;
  186. tmp->pvt->call = nbs_call;
  187. tmp->pvt->hangup = nbs_hangup;
  188. tmp->pvt->read = nbs_xread;
  189. tmp->pvt->write = nbs_xwrite;
  190. strncpy(tmp->context, context, sizeof(tmp->context)-1);
  191. strncpy(tmp->exten, "s", sizeof(tmp->exten) - 1);
  192. strcpy(tmp->language, "");
  193. i->owner = tmp;
  194. ast_mutex_lock(&usecnt_lock);
  195. usecnt++;
  196. ast_mutex_unlock(&usecnt_lock);
  197. ast_update_use_count();
  198. if (state != AST_STATE_DOWN) {
  199. if (ast_pbx_start(tmp)) {
  200. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
  201. ast_hangup(tmp);
  202. }
  203. }
  204. } else
  205. ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
  206. return tmp;
  207. }
  208. static struct ast_channel *nbs_request(char *type, int format, void *data)
  209. {
  210. int oldformat;
  211. struct nbs_pvt *p;
  212. struct ast_channel *tmp = NULL;
  213. oldformat = format;
  214. format &= (AST_FORMAT_SLINEAR);
  215. if (!format) {
  216. ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
  217. return NULL;
  218. }
  219. p = nbs_alloc(data);
  220. if (p) {
  221. tmp = nbs_new(p, AST_STATE_DOWN);
  222. if (!tmp)
  223. nbs_destroy(p);
  224. }
  225. return tmp;
  226. }
  227. static int __unload_module(void)
  228. {
  229. /* First, take us out of the channel loop */
  230. ast_channel_unregister(type);
  231. return 0;
  232. }
  233. int unload_module(void)
  234. {
  235. return __unload_module();
  236. }
  237. int load_module()
  238. {
  239. /* Make sure we can register our Adtranphone channel type */
  240. if (ast_channel_register(type, tdesc,
  241. AST_FORMAT_SLINEAR, nbs_request)) {
  242. ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
  243. __unload_module();
  244. return -1;
  245. }
  246. return 0;
  247. }
  248. int usecount()
  249. {
  250. int res;
  251. ast_mutex_lock(&usecnt_lock);
  252. res = usecnt;
  253. ast_mutex_unlock(&usecnt_lock);
  254. return res;
  255. }
  256. char *description()
  257. {
  258. return desc;
  259. }
  260. char *key()
  261. {
  262. return ASTERISK_GPL_KEY;
  263. }