chan_oss.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2007, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * FreeBSD changes and multiple device support by Luigi Rizzo, 2005.05.25
  9. * note-this code best seen with ts=8 (8-spaces tabs) in the editor
  10. *
  11. * See http://www.asterisk.org for more information about
  12. * the Asterisk project. Please do not directly contact
  13. * any of the maintainers of this project for assistance;
  14. * the project provides a web site, mailing lists and IRC
  15. * channels for your use.
  16. *
  17. * This program is free software, distributed under the terms of
  18. * the GNU General Public License Version 2. See the LICENSE file
  19. * at the top of the source tree.
  20. */
  21. // #define HAVE_VIDEO_CONSOLE // uncomment to enable video
  22. /*! \file
  23. *
  24. * \brief Channel driver for OSS sound cards
  25. *
  26. * \author Mark Spencer <markster@digium.com>
  27. * \author Luigi Rizzo
  28. *
  29. * \ingroup channel_drivers
  30. */
  31. /*! \li \ref chan_oss.c uses the configuration file \ref oss.conf
  32. * \addtogroup configuration_file
  33. */
  34. /*! \page oss.conf oss.conf
  35. * \verbinclude oss.conf.sample
  36. */
  37. /*** MODULEINFO
  38. <depend>oss</depend>
  39. <support_level>extended</support_level>
  40. ***/
  41. #include "asterisk.h"
  42. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  43. #include <ctype.h> /* isalnum() used here */
  44. #include <math.h>
  45. #include <sys/ioctl.h>
  46. #ifdef __linux
  47. #include <linux/soundcard.h>
  48. #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__CYGWIN__) || defined(__GLIBC__) || defined(__sun)
  49. #include <sys/soundcard.h>
  50. #else
  51. #include <soundcard.h>
  52. #endif
  53. #include "asterisk/channel.h"
  54. #include "asterisk/file.h"
  55. #include "asterisk/callerid.h"
  56. #include "asterisk/module.h"
  57. #include "asterisk/pbx.h"
  58. #include "asterisk/cli.h"
  59. #include "asterisk/causes.h"
  60. #include "asterisk/musiconhold.h"
  61. #include "asterisk/app.h"
  62. #include "asterisk/bridge.h"
  63. #include "asterisk/format_cache.h"
  64. #include "console_video.h"
  65. /*! Global jitterbuffer configuration - by default, jb is disabled
  66. * \note Values shown here match the defaults shown in oss.conf.sample */
  67. static struct ast_jb_conf default_jbconf =
  68. {
  69. .flags = 0,
  70. .max_size = 200,
  71. .resync_threshold = 1000,
  72. .impl = "fixed",
  73. .target_extra = 40,
  74. };
  75. static struct ast_jb_conf global_jbconf;
  76. /*
  77. * Basic mode of operation:
  78. *
  79. * we have one keyboard (which receives commands from the keyboard)
  80. * and multiple headset's connected to audio cards.
  81. * Cards/Headsets are named as the sections of oss.conf.
  82. * The section called [general] contains the default parameters.
  83. *
  84. * At any time, the keyboard is attached to one card, and you
  85. * can switch among them using the command 'console foo'
  86. * where 'foo' is the name of the card you want.
  87. *
  88. * oss.conf parameters are
  89. START_CONFIG
  90. [general]
  91. ; General config options, with default values shown.
  92. ; You should use one section per device, with [general] being used
  93. ; for the first device and also as a template for other devices.
  94. ;
  95. ; All but 'debug' can go also in the device-specific sections.
  96. ;
  97. ; debug = 0x0 ; misc debug flags, default is 0
  98. ; Set the device to use for I/O
  99. ; device = /dev/dsp
  100. ; Optional mixer command to run upon startup (e.g. to set
  101. ; volume levels, mutes, etc.
  102. ; mixer =
  103. ; Software mic volume booster (or attenuator), useful for sound
  104. ; cards or microphones with poor sensitivity. The volume level
  105. ; is in dB, ranging from -20.0 to +20.0
  106. ; boost = n ; mic volume boost in dB
  107. ; Set the callerid for outgoing calls
  108. ; callerid = John Doe <555-1234>
  109. ; autoanswer = no ; no autoanswer on call
  110. ; autohangup = yes ; hangup when other party closes
  111. ; extension = s ; default extension to call
  112. ; context = default ; default context for outgoing calls
  113. ; language = "" ; default language
  114. ; Default Music on Hold class to use when this channel is placed on hold in
  115. ; the case that the music class is not set on the channel with
  116. ; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
  117. ; putting this one on hold did not suggest a class to use.
  118. ;
  119. ; mohinterpret=default
  120. ; If you set overridecontext to 'yes', then the whole dial string
  121. ; will be interpreted as an extension, which is extremely useful
  122. ; to dial SIP, IAX and other extensions which use the '@' character.
  123. ; The default is 'no' just for backward compatibility, but the
  124. ; suggestion is to change it.
  125. ; overridecontext = no ; if 'no', the last @ will start the context
  126. ; if 'yes' the whole string is an extension.
  127. ; low level device parameters in case you have problems with the
  128. ; device driver on your operating system. You should not touch these
  129. ; unless you know what you are doing.
  130. ; queuesize = 10 ; frames in device driver
  131. ; frags = 8 ; argument to SETFRAGMENT
  132. ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
  133. ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
  134. ; OSS channel. Defaults to "no". An enabled jitterbuffer will
  135. ; be used only if the sending side can create and the receiving
  136. ; side can not accept jitter. The OSS channel can't accept jitter,
  137. ; thus an enabled jitterbuffer on the receive OSS side will always
  138. ; be used if the sending side can create jitter.
  139. ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
  140. ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
  141. ; resynchronized. Useful to improve the quality of the voice, with
  142. ; big jumps in/broken timestamps, usualy sent from exotic devices
  143. ; and programs. Defaults to 1000.
  144. ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an OSS
  145. ; channel. Two implementations are currenlty available - "fixed"
  146. ; (with size always equals to jbmax-size) and "adaptive" (with
  147. ; variable size, actually the new jb of IAX2). Defaults to fixed.
  148. ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
  149. ;-----------------------------------------------------------------------------------
  150. [card1]
  151. ; device = /dev/dsp1 ; alternate device
  152. END_CONFIG
  153. .. and so on for the other cards.
  154. */
  155. /*
  156. * The following parameters are used in the driver:
  157. *
  158. * FRAME_SIZE the size of an audio frame, in samples.
  159. * 160 is used almost universally, so you should not change it.
  160. *
  161. * FRAGS the argument for the SETFRAGMENT ioctl.
  162. * Overridden by the 'frags' parameter in oss.conf
  163. *
  164. * Bits 0-7 are the base-2 log of the device's block size,
  165. * bits 16-31 are the number of blocks in the driver's queue.
  166. * There are a lot of differences in the way this parameter
  167. * is supported by different drivers, so you may need to
  168. * experiment a bit with the value.
  169. * A good default for linux is 30 blocks of 64 bytes, which
  170. * results in 6 frames of 320 bytes (160 samples).
  171. * FreeBSD works decently with blocks of 256 or 512 bytes,
  172. * leaving the number unspecified.
  173. * Note that this only refers to the device buffer size,
  174. * this module will then try to keep the lenght of audio
  175. * buffered within small constraints.
  176. *
  177. * QUEUE_SIZE The max number of blocks actually allowed in the device
  178. * driver's buffer, irrespective of the available number.
  179. * Overridden by the 'queuesize' parameter in oss.conf
  180. *
  181. * Should be >=2, and at most as large as the hw queue above
  182. * (otherwise it will never be full).
  183. */
  184. #define FRAME_SIZE 160
  185. #define QUEUE_SIZE 10
  186. #if defined(__FreeBSD__)
  187. #define FRAGS 0x8
  188. #else
  189. #define FRAGS ( ( (6 * 5) << 16 ) | 0x6 )
  190. #endif
  191. /*
  192. * XXX text message sizes are probably 256 chars, but i am
  193. * not sure if there is a suitable definition anywhere.
  194. */
  195. #define TEXT_SIZE 256
  196. #if 0
  197. #define TRYOPEN 1 /* try to open on startup */
  198. #endif
  199. #define O_CLOSE 0x444 /* special 'close' mode for device */
  200. /* Which device to use */
  201. #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
  202. #define DEV_DSP "/dev/audio"
  203. #else
  204. #define DEV_DSP "/dev/dsp"
  205. #endif
  206. static char *config = "oss.conf"; /* default config file */
  207. static int oss_debug;
  208. /*!
  209. * \brief descriptor for one of our channels.
  210. *
  211. * There is one used for 'default' values (from the [general] entry in
  212. * the configuration file), and then one instance for each device
  213. * (the default is cloned from [general], others are only created
  214. * if the relevant section exists).
  215. */
  216. struct chan_oss_pvt {
  217. struct chan_oss_pvt *next;
  218. char *name;
  219. int total_blocks; /*!< total blocks in the output device */
  220. int sounddev;
  221. enum {
  222. CHAN_OSS_DUPLEX_UNSET,
  223. CHAN_OSS_DUPLEX_FULL,
  224. CHAN_OSS_DUPLEX_READ,
  225. CHAN_OSS_DUPLEX_WRITE
  226. } duplex;
  227. int autoanswer; /*!< Boolean: whether to answer the immediately upon calling */
  228. int autohangup; /*!< Boolean: whether to hangup the call when the remote end hangs up */
  229. int hookstate; /*!< Boolean: 1 if offhook; 0 if onhook */
  230. char *mixer_cmd; /*!< initial command to issue to the mixer */
  231. unsigned int queuesize; /*!< max fragments in queue */
  232. unsigned int frags; /*!< parameter for SETFRAGMENT */
  233. int warned; /*!< various flags used for warnings */
  234. #define WARN_used_blocks 1
  235. #define WARN_speed 2
  236. #define WARN_frag 4
  237. int w_errors; /*!< overfull in the write path */
  238. struct timeval lastopen;
  239. int overridecontext;
  240. int mute;
  241. /*! boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
  242. * be representable in 16 bits to avoid overflows.
  243. */
  244. #define BOOST_SCALE (1<<9)
  245. #define BOOST_MAX 40 /*!< slightly less than 7 bits */
  246. int boost; /*!< input boost, scaled by BOOST_SCALE */
  247. char device[64]; /*!< device to open */
  248. pthread_t sthread;
  249. struct ast_channel *owner;
  250. struct video_desc *env; /*!< parameters for video support */
  251. char ext[AST_MAX_EXTENSION];
  252. char ctx[AST_MAX_CONTEXT];
  253. char language[MAX_LANGUAGE];
  254. char cid_name[256]; /*!< Initial CallerID name */
  255. char cid_num[256]; /*!< Initial CallerID number */
  256. char mohinterpret[MAX_MUSICCLASS];
  257. /*! buffers used in oss_write */
  258. char oss_write_buf[FRAME_SIZE * 2];
  259. int oss_write_dst;
  260. /*! buffers used in oss_read - AST_FRIENDLY_OFFSET space for headers
  261. * plus enough room for a full frame
  262. */
  263. char oss_read_buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
  264. int readpos; /*!< read position above */
  265. struct ast_frame read_f; /*!< returned by oss_read */
  266. };
  267. /*! forward declaration */
  268. static struct chan_oss_pvt *find_desc(const char *dev);
  269. static char *oss_active; /*!< the active device */
  270. /*! \brief return the pointer to the video descriptor */
  271. struct video_desc *get_video_desc(struct ast_channel *c)
  272. {
  273. struct chan_oss_pvt *o = c ? ast_channel_tech_pvt(c) : find_desc(oss_active);
  274. return o ? o->env : NULL;
  275. }
  276. static struct chan_oss_pvt oss_default = {
  277. .sounddev = -1,
  278. .duplex = CHAN_OSS_DUPLEX_UNSET, /* XXX check this */
  279. .autoanswer = 1,
  280. .autohangup = 1,
  281. .queuesize = QUEUE_SIZE,
  282. .frags = FRAGS,
  283. .ext = "s",
  284. .ctx = "default",
  285. .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
  286. .lastopen = { 0, 0 },
  287. .boost = BOOST_SCALE,
  288. };
  289. static int setformat(struct chan_oss_pvt *o, int mode);
  290. static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
  291. const char *data, int *cause);
  292. static int oss_digit_begin(struct ast_channel *c, char digit);
  293. static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
  294. static int oss_text(struct ast_channel *c, const char *text);
  295. static int oss_hangup(struct ast_channel *c);
  296. static int oss_answer(struct ast_channel *c);
  297. static struct ast_frame *oss_read(struct ast_channel *chan);
  298. static int oss_call(struct ast_channel *c, const char *dest, int timeout);
  299. static int oss_write(struct ast_channel *chan, struct ast_frame *f);
  300. static int oss_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
  301. static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  302. static char tdesc[] = "OSS Console Channel Driver";
  303. /* cannot do const because need to update some fields at runtime */
  304. static struct ast_channel_tech oss_tech = {
  305. .type = "Console",
  306. .description = tdesc,
  307. .requester = oss_request,
  308. .send_digit_begin = oss_digit_begin,
  309. .send_digit_end = oss_digit_end,
  310. .send_text = oss_text,
  311. .hangup = oss_hangup,
  312. .answer = oss_answer,
  313. .read = oss_read,
  314. .call = oss_call,
  315. .write = oss_write,
  316. .write_video = console_write_video,
  317. .indicate = oss_indicate,
  318. .fixup = oss_fixup,
  319. };
  320. /*!
  321. * \brief returns a pointer to the descriptor with the given name
  322. */
  323. static struct chan_oss_pvt *find_desc(const char *dev)
  324. {
  325. struct chan_oss_pvt *o = NULL;
  326. if (!dev)
  327. ast_log(LOG_WARNING, "null dev\n");
  328. for (o = oss_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
  329. if (!o)
  330. ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
  331. return o;
  332. }
  333. /* !
  334. * \brief split a string in extension-context, returns pointers to malloc'ed
  335. * strings.
  336. *
  337. * If we do not have 'overridecontext' then the last @ is considered as
  338. * a context separator, and the context is overridden.
  339. * This is usually not very necessary as you can play with the dialplan,
  340. * and it is nice not to need it because you have '@' in SIP addresses.
  341. *
  342. * \return the buffer address.
  343. */
  344. static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
  345. {
  346. struct chan_oss_pvt *o = find_desc(oss_active);
  347. if (ext == NULL || ctx == NULL)
  348. return NULL; /* error */
  349. *ext = *ctx = NULL;
  350. if (src && *src != '\0')
  351. *ext = ast_strdup(src);
  352. if (*ext == NULL)
  353. return NULL;
  354. if (!o->overridecontext) {
  355. /* parse from the right */
  356. *ctx = strrchr(*ext, '@');
  357. if (*ctx)
  358. *(*ctx)++ = '\0';
  359. }
  360. return *ext;
  361. }
  362. /*!
  363. * \brief Returns the number of blocks used in the audio output channel
  364. */
  365. static int used_blocks(struct chan_oss_pvt *o)
  366. {
  367. struct audio_buf_info info;
  368. if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
  369. if (!(o->warned & WARN_used_blocks)) {
  370. ast_log(LOG_WARNING, "Error reading output space\n");
  371. o->warned |= WARN_used_blocks;
  372. }
  373. return 1;
  374. }
  375. if (o->total_blocks == 0) {
  376. if (0) /* debugging */
  377. ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
  378. o->total_blocks = info.fragments;
  379. }
  380. return o->total_blocks - info.fragments;
  381. }
  382. /*! Write an exactly FRAME_SIZE sized frame */
  383. static int soundcard_writeframe(struct chan_oss_pvt *o, short *data)
  384. {
  385. int res;
  386. if (o->sounddev < 0)
  387. setformat(o, O_RDWR);
  388. if (o->sounddev < 0)
  389. return 0; /* not fatal */
  390. /*
  391. * Nothing complex to manage the audio device queue.
  392. * If the buffer is full just drop the extra, otherwise write.
  393. * XXX in some cases it might be useful to write anyways after
  394. * a number of failures, to restart the output chain.
  395. */
  396. res = used_blocks(o);
  397. if (res > o->queuesize) { /* no room to write a block */
  398. if (o->w_errors++ == 0 && (oss_debug & 0x4))
  399. ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
  400. return 0;
  401. }
  402. o->w_errors = 0;
  403. return write(o->sounddev, (void *)data, FRAME_SIZE * 2);
  404. }
  405. /*!
  406. * reset and close the device if opened,
  407. * then open and initialize it in the desired mode,
  408. * trigger reads and writes so we can start using it.
  409. */
  410. static int setformat(struct chan_oss_pvt *o, int mode)
  411. {
  412. int fmt, desired, res, fd;
  413. if (o->sounddev >= 0) {
  414. ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
  415. close(o->sounddev);
  416. o->duplex = CHAN_OSS_DUPLEX_UNSET;
  417. o->sounddev = -1;
  418. }
  419. if (mode == O_CLOSE) /* we are done */
  420. return 0;
  421. if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
  422. return -1; /* don't open too often */
  423. o->lastopen = ast_tvnow();
  424. fd = o->sounddev = open(o->device, mode | O_NONBLOCK);
  425. if (fd < 0) {
  426. ast_log(LOG_WARNING, "Unable to re-open DSP device %s: %s\n", o->device, strerror(errno));
  427. return -1;
  428. }
  429. if (o->owner)
  430. ast_channel_set_fd(o->owner, 0, fd);
  431. #if __BYTE_ORDER == __LITTLE_ENDIAN
  432. fmt = AFMT_S16_LE;
  433. #else
  434. fmt = AFMT_S16_BE;
  435. #endif
  436. res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
  437. if (res < 0) {
  438. ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
  439. return -1;
  440. }
  441. switch (mode) {
  442. case O_RDWR:
  443. res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
  444. /* Check to see if duplex set (FreeBSD Bug) */
  445. res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
  446. if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
  447. ast_verb(2, "Console is full duplex\n");
  448. o->duplex = CHAN_OSS_DUPLEX_FULL;
  449. };
  450. break;
  451. case O_WRONLY:
  452. o->duplex = CHAN_OSS_DUPLEX_WRITE;
  453. break;
  454. case O_RDONLY:
  455. o->duplex = CHAN_OSS_DUPLEX_READ;
  456. break;
  457. }
  458. fmt = 0;
  459. res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
  460. if (res < 0) {
  461. ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
  462. return -1;
  463. }
  464. fmt = desired = DEFAULT_SAMPLE_RATE; /* 8000 Hz desired */
  465. res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
  466. if (res < 0) {
  467. ast_log(LOG_WARNING, "Failed to set sample rate to %d\n", desired);
  468. return -1;
  469. }
  470. if (fmt != desired) {
  471. if (!(o->warned & WARN_speed)) {
  472. ast_log(LOG_WARNING,
  473. "Requested %d Hz, got %d Hz -- sound may be choppy\n",
  474. desired, fmt);
  475. o->warned |= WARN_speed;
  476. }
  477. }
  478. /*
  479. * on Freebsd, SETFRAGMENT does not work very well on some cards.
  480. * Default to use 256 bytes, let the user override
  481. */
  482. if (o->frags) {
  483. fmt = o->frags;
  484. res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
  485. if (res < 0) {
  486. if (!(o->warned & WARN_frag)) {
  487. ast_log(LOG_WARNING,
  488. "Unable to set fragment size -- sound may be choppy\n");
  489. o->warned |= WARN_frag;
  490. }
  491. }
  492. }
  493. /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
  494. res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
  495. res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
  496. /* it may fail if we are in half duplex, never mind */
  497. return 0;
  498. }
  499. /*
  500. * some of the standard methods supported by channels.
  501. */
  502. static int oss_digit_begin(struct ast_channel *c, char digit)
  503. {
  504. return 0;
  505. }
  506. static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration)
  507. {
  508. /* no better use for received digits than print them */
  509. ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
  510. digit, duration);
  511. return 0;
  512. }
  513. static int oss_text(struct ast_channel *c, const char *text)
  514. {
  515. /* print received messages */
  516. ast_verbose(" << Console Received text %s >> \n", text);
  517. return 0;
  518. }
  519. /*!
  520. * \brief handler for incoming calls. Either autoanswer, or start ringing
  521. */
  522. static int oss_call(struct ast_channel *c, const char *dest, int timeout)
  523. {
  524. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  525. struct ast_frame f = { AST_FRAME_CONTROL, };
  526. AST_DECLARE_APP_ARGS(args,
  527. AST_APP_ARG(name);
  528. AST_APP_ARG(flags);
  529. );
  530. char *parse = ast_strdupa(dest);
  531. AST_NONSTANDARD_APP_ARGS(args, parse, '/');
  532. ast_verbose(" << Call to device '%s' dnid '%s' rdnis '%s' on console from '%s' <%s> >>\n",
  533. dest,
  534. S_OR(ast_channel_dialed(c)->number.str, ""),
  535. S_COR(ast_channel_redirecting(c)->from.number.valid, ast_channel_redirecting(c)->from.number.str, ""),
  536. S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, ""),
  537. S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, ""));
  538. if (!ast_strlen_zero(args.flags) && strcasecmp(args.flags, "answer") == 0) {
  539. f.subclass.integer = AST_CONTROL_ANSWER;
  540. ast_queue_frame(c, &f);
  541. } else if (!ast_strlen_zero(args.flags) && strcasecmp(args.flags, "noanswer") == 0) {
  542. f.subclass.integer = AST_CONTROL_RINGING;
  543. ast_queue_frame(c, &f);
  544. ast_indicate(c, AST_CONTROL_RINGING);
  545. } else if (o->autoanswer) {
  546. ast_verbose(" << Auto-answered >> \n");
  547. f.subclass.integer = AST_CONTROL_ANSWER;
  548. ast_queue_frame(c, &f);
  549. o->hookstate = 1;
  550. } else {
  551. ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
  552. f.subclass.integer = AST_CONTROL_RINGING;
  553. ast_queue_frame(c, &f);
  554. ast_indicate(c, AST_CONTROL_RINGING);
  555. }
  556. return 0;
  557. }
  558. /*!
  559. * \brief remote side answered the phone
  560. */
  561. static int oss_answer(struct ast_channel *c)
  562. {
  563. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  564. ast_verbose(" << Console call has been answered >> \n");
  565. ast_setstate(c, AST_STATE_UP);
  566. o->hookstate = 1;
  567. return 0;
  568. }
  569. static int oss_hangup(struct ast_channel *c)
  570. {
  571. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  572. ast_channel_tech_pvt_set(c, NULL);
  573. o->owner = NULL;
  574. ast_verbose(" << Hangup on console >> \n");
  575. console_video_uninit(o->env);
  576. ast_module_unref(ast_module_info->self);
  577. if (o->hookstate) {
  578. if (o->autoanswer || o->autohangup) {
  579. /* Assume auto-hangup too */
  580. o->hookstate = 0;
  581. setformat(o, O_CLOSE);
  582. }
  583. }
  584. return 0;
  585. }
  586. /*! \brief used for data coming from the network */
  587. static int oss_write(struct ast_channel *c, struct ast_frame *f)
  588. {
  589. int src;
  590. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  591. /*
  592. * we could receive a block which is not a multiple of our
  593. * FRAME_SIZE, so buffer it locally and write to the device
  594. * in FRAME_SIZE chunks.
  595. * Keep the residue stored for future use.
  596. */
  597. src = 0; /* read position into f->data */
  598. while (src < f->datalen) {
  599. /* Compute spare room in the buffer */
  600. int l = sizeof(o->oss_write_buf) - o->oss_write_dst;
  601. if (f->datalen - src >= l) { /* enough to fill a frame */
  602. memcpy(o->oss_write_buf + o->oss_write_dst, f->data.ptr + src, l);
  603. soundcard_writeframe(o, (short *) o->oss_write_buf);
  604. src += l;
  605. o->oss_write_dst = 0;
  606. } else { /* copy residue */
  607. l = f->datalen - src;
  608. memcpy(o->oss_write_buf + o->oss_write_dst, f->data.ptr + src, l);
  609. src += l; /* but really, we are done */
  610. o->oss_write_dst += l;
  611. }
  612. }
  613. return 0;
  614. }
  615. static struct ast_frame *oss_read(struct ast_channel *c)
  616. {
  617. int res;
  618. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  619. struct ast_frame *f = &o->read_f;
  620. /* XXX can be simplified returning &ast_null_frame */
  621. /* prepare a NULL frame in case we don't have enough data to return */
  622. memset(f, '\0', sizeof(struct ast_frame));
  623. f->frametype = AST_FRAME_NULL;
  624. f->src = oss_tech.type;
  625. res = read(o->sounddev, o->oss_read_buf + o->readpos, sizeof(o->oss_read_buf) - o->readpos);
  626. if (res < 0) /* audio data not ready, return a NULL frame */
  627. return f;
  628. o->readpos += res;
  629. if (o->readpos < sizeof(o->oss_read_buf)) /* not enough samples */
  630. return f;
  631. if (o->mute)
  632. return f;
  633. o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */
  634. if (ast_channel_state(c) != AST_STATE_UP) /* drop data if frame is not up */
  635. return f;
  636. /* ok we can build and deliver the frame to the caller */
  637. f->frametype = AST_FRAME_VOICE;
  638. f->subclass.format = ast_format_slin;
  639. f->samples = FRAME_SIZE;
  640. f->datalen = FRAME_SIZE * 2;
  641. f->data.ptr = o->oss_read_buf + AST_FRIENDLY_OFFSET;
  642. if (o->boost != BOOST_SCALE) { /* scale and clip values */
  643. int i, x;
  644. int16_t *p = (int16_t *) f->data.ptr;
  645. for (i = 0; i < f->samples; i++) {
  646. x = (p[i] * o->boost) / BOOST_SCALE;
  647. if (x > 32767)
  648. x = 32767;
  649. else if (x < -32768)
  650. x = -32768;
  651. p[i] = x;
  652. }
  653. }
  654. f->offset = AST_FRIENDLY_OFFSET;
  655. return f;
  656. }
  657. static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  658. {
  659. struct chan_oss_pvt *o = ast_channel_tech_pvt(newchan);
  660. o->owner = newchan;
  661. return 0;
  662. }
  663. static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
  664. {
  665. struct chan_oss_pvt *o = ast_channel_tech_pvt(c);
  666. int res = 0;
  667. switch (cond) {
  668. case AST_CONTROL_INCOMPLETE:
  669. case AST_CONTROL_BUSY:
  670. case AST_CONTROL_CONGESTION:
  671. case AST_CONTROL_RINGING:
  672. case AST_CONTROL_PVT_CAUSE_CODE:
  673. case -1:
  674. res = -1;
  675. break;
  676. case AST_CONTROL_PROGRESS:
  677. case AST_CONTROL_PROCEEDING:
  678. case AST_CONTROL_VIDUPDATE:
  679. case AST_CONTROL_SRCUPDATE:
  680. break;
  681. case AST_CONTROL_HOLD:
  682. ast_verbose(" << Console Has Been Placed on Hold >> \n");
  683. ast_moh_start(c, data, o->mohinterpret);
  684. break;
  685. case AST_CONTROL_UNHOLD:
  686. ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
  687. ast_moh_stop(c);
  688. break;
  689. default:
  690. ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast_channel_name(c));
  691. return -1;
  692. }
  693. return res;
  694. }
  695. /*!
  696. * \brief allocate a new channel.
  697. */
  698. static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
  699. {
  700. struct ast_channel *c;
  701. c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, assignedids, requestor, 0, "Console/%s", o->device + 5);
  702. if (c == NULL)
  703. return NULL;
  704. ast_channel_tech_set(c, &oss_tech);
  705. if (o->sounddev < 0)
  706. setformat(o, O_RDWR);
  707. ast_channel_set_fd(c, 0, o->sounddev); /* -1 if device closed, override later */
  708. ast_channel_set_readformat(c, ast_format_slin);
  709. ast_channel_set_writeformat(c, ast_format_slin);
  710. ast_channel_nativeformats_set(c, oss_tech.capabilities);
  711. /* if the console makes the call, add video to the offer */
  712. /* if (state == AST_STATE_RINGING) TODO XXX CONSOLE VIDEO IS DISABLED UNTIL IT GETS A MAINTAINER
  713. c->nativeformats |= console_video_formats; */
  714. ast_channel_tech_pvt_set(c, o);
  715. if (!ast_strlen_zero(o->language))
  716. ast_channel_language_set(c, o->language);
  717. /* Don't use ast_set_callerid() here because it will
  718. * generate a needless NewCallerID event */
  719. if (!ast_strlen_zero(o->cid_num)) {
  720. ast_channel_caller(c)->ani.number.valid = 1;
  721. ast_channel_caller(c)->ani.number.str = ast_strdup(o->cid_num);
  722. }
  723. if (!ast_strlen_zero(ext)) {
  724. ast_channel_dialed(c)->number.str = ast_strdup(ext);
  725. }
  726. o->owner = c;
  727. ast_module_ref(ast_module_info->self);
  728. ast_jb_configure(c, &global_jbconf);
  729. ast_channel_unlock(c);
  730. if (state != AST_STATE_DOWN) {
  731. if (ast_pbx_start(c)) {
  732. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(c));
  733. ast_hangup(c);
  734. o->owner = c = NULL;
  735. }
  736. }
  737. console_video_start(get_video_desc(c), c); /* XXX cleanup */
  738. return c;
  739. }
  740. static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
  741. {
  742. struct ast_channel *c;
  743. struct chan_oss_pvt *o;
  744. AST_DECLARE_APP_ARGS(args,
  745. AST_APP_ARG(name);
  746. AST_APP_ARG(flags);
  747. );
  748. char *parse = ast_strdupa(data);
  749. AST_NONSTANDARD_APP_ARGS(args, parse, '/');
  750. o = find_desc(args.name);
  751. ast_log(LOG_WARNING, "oss_request ty <%s> data 0x%p <%s>\n", type, data, data);
  752. if (o == NULL) {
  753. ast_log(LOG_NOTICE, "Device %s not found\n", args.name);
  754. /* XXX we could default to 'dsp' perhaps ? */
  755. return NULL;
  756. }
  757. if (ast_format_cap_iscompatible_format(cap, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
  758. struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
  759. ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_format_cap_get_names(cap, &codec_buf));
  760. return NULL;
  761. }
  762. if (o->owner) {
  763. ast_log(LOG_NOTICE, "Already have a call (chan %p) on the OSS channel\n", o->owner);
  764. *cause = AST_CAUSE_BUSY;
  765. return NULL;
  766. }
  767. c = oss_new(o, NULL, NULL, AST_STATE_DOWN, assignedids, requestor);
  768. if (c == NULL) {
  769. ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
  770. return NULL;
  771. }
  772. return c;
  773. }
  774. static void store_config_core(struct chan_oss_pvt *o, const char *var, const char *value);
  775. /*! Generic console command handler. Basically a wrapper for a subset
  776. * of config file options which are also available from the CLI
  777. */
  778. static char *console_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  779. {
  780. struct chan_oss_pvt *o = find_desc(oss_active);
  781. const char *var, *value;
  782. switch (cmd) {
  783. case CLI_INIT:
  784. e->command = CONSOLE_VIDEO_CMDS;
  785. e->usage =
  786. "Usage: " CONSOLE_VIDEO_CMDS "...\n"
  787. " Generic handler for console commands.\n";
  788. return NULL;
  789. case CLI_GENERATE:
  790. return NULL;
  791. }
  792. if (a->argc < e->args)
  793. return CLI_SHOWUSAGE;
  794. if (o == NULL) {
  795. ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n",
  796. oss_active);
  797. return CLI_FAILURE;
  798. }
  799. var = a->argv[e->args-1];
  800. value = a->argc > e->args ? a->argv[e->args] : NULL;
  801. if (value) /* handle setting */
  802. store_config_core(o, var, value);
  803. if (!console_video_cli(o->env, var, a->fd)) /* print video-related values */
  804. return CLI_SUCCESS;
  805. /* handle other values */
  806. if (!strcasecmp(var, "device")) {
  807. ast_cli(a->fd, "device is [%s]\n", o->device);
  808. }
  809. return CLI_SUCCESS;
  810. }
  811. static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  812. {
  813. struct chan_oss_pvt *o = find_desc(oss_active);
  814. switch (cmd) {
  815. case CLI_INIT:
  816. e->command = "console {set|show} autoanswer [on|off]";
  817. e->usage =
  818. "Usage: console {set|show} autoanswer [on|off]\n"
  819. " Enables or disables autoanswer feature. If used without\n"
  820. " argument, displays the current on/off status of autoanswer.\n"
  821. " The default value of autoanswer is in 'oss.conf'.\n";
  822. return NULL;
  823. case CLI_GENERATE:
  824. return NULL;
  825. }
  826. if (a->argc == e->args - 1) {
  827. ast_cli(a->fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off");
  828. return CLI_SUCCESS;
  829. }
  830. if (a->argc != e->args)
  831. return CLI_SHOWUSAGE;
  832. if (o == NULL) {
  833. ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n",
  834. oss_active);
  835. return CLI_FAILURE;
  836. }
  837. if (!strcasecmp(a->argv[e->args-1], "on"))
  838. o->autoanswer = 1;
  839. else if (!strcasecmp(a->argv[e->args - 1], "off"))
  840. o->autoanswer = 0;
  841. else
  842. return CLI_SHOWUSAGE;
  843. return CLI_SUCCESS;
  844. }
  845. /*! \brief helper function for the answer key/cli command */
  846. static char *console_do_answer(int fd)
  847. {
  848. struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
  849. struct chan_oss_pvt *o = find_desc(oss_active);
  850. if (!o->owner) {
  851. if (fd > -1)
  852. ast_cli(fd, "No one is calling us\n");
  853. return CLI_FAILURE;
  854. }
  855. o->hookstate = 1;
  856. ast_queue_frame(o->owner, &f);
  857. return CLI_SUCCESS;
  858. }
  859. /*!
  860. * \brief answer command from the console
  861. */
  862. static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  863. {
  864. switch (cmd) {
  865. case CLI_INIT:
  866. e->command = "console answer";
  867. e->usage =
  868. "Usage: console answer\n"
  869. " Answers an incoming call on the console (OSS) channel.\n";
  870. return NULL;
  871. case CLI_GENERATE:
  872. return NULL; /* no completion */
  873. }
  874. if (a->argc != e->args)
  875. return CLI_SHOWUSAGE;
  876. return console_do_answer(a->fd);
  877. }
  878. /*!
  879. * \brief Console send text CLI command
  880. *
  881. * \note concatenate all arguments into a single string. argv is NULL-terminated
  882. * so we can use it right away
  883. */
  884. static char *console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  885. {
  886. struct chan_oss_pvt *o = find_desc(oss_active);
  887. char buf[TEXT_SIZE];
  888. if (cmd == CLI_INIT) {
  889. e->command = "console send text";
  890. e->usage =
  891. "Usage: console send text <message>\n"
  892. " Sends a text message for display on the remote terminal.\n";
  893. return NULL;
  894. } else if (cmd == CLI_GENERATE)
  895. return NULL;
  896. if (a->argc < e->args + 1)
  897. return CLI_SHOWUSAGE;
  898. if (!o->owner) {
  899. ast_cli(a->fd, "Not in a call\n");
  900. return CLI_FAILURE;
  901. }
  902. ast_join(buf, sizeof(buf) - 1, a->argv + e->args);
  903. if (!ast_strlen_zero(buf)) {
  904. struct ast_frame f = { 0, };
  905. int i = strlen(buf);
  906. buf[i] = '\n';
  907. f.frametype = AST_FRAME_TEXT;
  908. f.subclass.integer = 0;
  909. f.data.ptr = buf;
  910. f.datalen = i + 1;
  911. ast_queue_frame(o->owner, &f);
  912. }
  913. return CLI_SUCCESS;
  914. }
  915. static char *console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  916. {
  917. struct chan_oss_pvt *o = find_desc(oss_active);
  918. if (cmd == CLI_INIT) {
  919. e->command = "console hangup";
  920. e->usage =
  921. "Usage: console hangup\n"
  922. " Hangs up any call currently placed on the console.\n";
  923. return NULL;
  924. } else if (cmd == CLI_GENERATE)
  925. return NULL;
  926. if (a->argc != e->args)
  927. return CLI_SHOWUSAGE;
  928. if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
  929. ast_cli(a->fd, "No call to hang up\n");
  930. return CLI_FAILURE;
  931. }
  932. o->hookstate = 0;
  933. if (o->owner)
  934. ast_queue_hangup_with_cause(o->owner, AST_CAUSE_NORMAL_CLEARING);
  935. setformat(o, O_CLOSE);
  936. return CLI_SUCCESS;
  937. }
  938. static char *console_flash(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  939. {
  940. struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH } };
  941. struct chan_oss_pvt *o = find_desc(oss_active);
  942. if (cmd == CLI_INIT) {
  943. e->command = "console flash";
  944. e->usage =
  945. "Usage: console flash\n"
  946. " Flashes the call currently placed on the console.\n";
  947. return NULL;
  948. } else if (cmd == CLI_GENERATE)
  949. return NULL;
  950. if (a->argc != e->args)
  951. return CLI_SHOWUSAGE;
  952. if (!o->owner) { /* XXX maybe !o->hookstate too ? */
  953. ast_cli(a->fd, "No call to flash\n");
  954. return CLI_FAILURE;
  955. }
  956. o->hookstate = 0;
  957. if (o->owner)
  958. ast_queue_frame(o->owner, &f);
  959. return CLI_SUCCESS;
  960. }
  961. static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  962. {
  963. char *s = NULL;
  964. char *mye = NULL, *myc = NULL;
  965. struct chan_oss_pvt *o = find_desc(oss_active);
  966. if (cmd == CLI_INIT) {
  967. e->command = "console dial";
  968. e->usage =
  969. "Usage: console dial [extension[@context]]\n"
  970. " Dials a given extension (and context if specified)\n";
  971. return NULL;
  972. } else if (cmd == CLI_GENERATE)
  973. return NULL;
  974. if (a->argc > e->args + 1)
  975. return CLI_SHOWUSAGE;
  976. if (o->owner) { /* already in a call */
  977. int i;
  978. struct ast_frame f = { AST_FRAME_DTMF, { 0 } };
  979. const char *digits;
  980. if (a->argc == e->args) { /* argument is mandatory here */
  981. ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n");
  982. return CLI_FAILURE;
  983. }
  984. digits = a->argv[e->args];
  985. /* send the string one char at a time */
  986. for (i = 0; i < strlen(digits); i++) {
  987. f.subclass.integer = digits[i];
  988. ast_queue_frame(o->owner, &f);
  989. }
  990. return CLI_SUCCESS;
  991. }
  992. /* if we have an argument split it into extension and context */
  993. if (a->argc == e->args + 1)
  994. s = ast_ext_ctx(a->argv[e->args], &mye, &myc);
  995. /* supply default values if needed */
  996. if (mye == NULL)
  997. mye = o->ext;
  998. if (myc == NULL)
  999. myc = o->ctx;
  1000. if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
  1001. o->hookstate = 1;
  1002. oss_new(o, mye, myc, AST_STATE_RINGING, NULL, NULL);
  1003. } else
  1004. ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
  1005. if (s)
  1006. ast_free(s);
  1007. return CLI_SUCCESS;
  1008. }
  1009. static char *console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1010. {
  1011. struct chan_oss_pvt *o = find_desc(oss_active);
  1012. const char *s;
  1013. int toggle = 0;
  1014. if (cmd == CLI_INIT) {
  1015. e->command = "console {mute|unmute} [toggle]";
  1016. e->usage =
  1017. "Usage: console {mute|unmute} [toggle]\n"
  1018. " Mute/unmute the microphone.\n";
  1019. return NULL;
  1020. } else if (cmd == CLI_GENERATE)
  1021. return NULL;
  1022. if (a->argc > e->args)
  1023. return CLI_SHOWUSAGE;
  1024. if (a->argc == e->args) {
  1025. if (strcasecmp(a->argv[e->args-1], "toggle"))
  1026. return CLI_SHOWUSAGE;
  1027. toggle = 1;
  1028. }
  1029. s = a->argv[e->args-2];
  1030. if (!strcasecmp(s, "mute"))
  1031. o->mute = toggle ? !o->mute : 1;
  1032. else if (!strcasecmp(s, "unmute"))
  1033. o->mute = toggle ? !o->mute : 0;
  1034. else
  1035. return CLI_SHOWUSAGE;
  1036. ast_cli(a->fd, "Console mic is %s\n", o->mute ? "off" : "on");
  1037. return CLI_SUCCESS;
  1038. }
  1039. static char *console_transfer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1040. {
  1041. struct chan_oss_pvt *o = find_desc(oss_active);
  1042. char *tmp, *ext, *ctx;
  1043. switch (cmd) {
  1044. case CLI_INIT:
  1045. e->command = "console transfer";
  1046. e->usage =
  1047. "Usage: console transfer <extension>[@context]\n"
  1048. " Transfers the currently connected call to the given extension (and\n"
  1049. " context if specified)\n";
  1050. return NULL;
  1051. case CLI_GENERATE:
  1052. return NULL;
  1053. }
  1054. if (a->argc != 3)
  1055. return CLI_SHOWUSAGE;
  1056. if (o == NULL)
  1057. return CLI_FAILURE;
  1058. if (o->owner == NULL || !ast_channel_is_bridged(o->owner)) {
  1059. ast_cli(a->fd, "There is no call to transfer\n");
  1060. return CLI_SUCCESS;
  1061. }
  1062. tmp = ast_ext_ctx(a->argv[2], &ext, &ctx);
  1063. if (ctx == NULL) { /* supply default context if needed */
  1064. ctx = ast_strdupa(ast_channel_context(o->owner));
  1065. }
  1066. if (ast_bridge_transfer_blind(1, o->owner, ext, ctx, NULL, NULL) != AST_BRIDGE_TRANSFER_SUCCESS) {
  1067. ast_log(LOG_WARNING, "Unable to transfer call from channel %s\n", ast_channel_name(o->owner));
  1068. }
  1069. ast_free(tmp);
  1070. return CLI_SUCCESS;
  1071. }
  1072. static char *console_active(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1073. {
  1074. switch (cmd) {
  1075. case CLI_INIT:
  1076. e->command = "console {set|show} active [<device>]";
  1077. e->usage =
  1078. "Usage: console active [device]\n"
  1079. " If used without a parameter, displays which device is the current\n"
  1080. " console. If a device is specified, the console sound device is changed to\n"
  1081. " the device specified.\n";
  1082. return NULL;
  1083. case CLI_GENERATE:
  1084. return NULL;
  1085. }
  1086. if (a->argc == 3)
  1087. ast_cli(a->fd, "active console is [%s]\n", oss_active);
  1088. else if (a->argc != 4)
  1089. return CLI_SHOWUSAGE;
  1090. else {
  1091. struct chan_oss_pvt *o;
  1092. if (strcmp(a->argv[3], "show") == 0) {
  1093. for (o = oss_default.next; o; o = o->next)
  1094. ast_cli(a->fd, "device [%s] exists\n", o->name);
  1095. return CLI_SUCCESS;
  1096. }
  1097. o = find_desc(a->argv[3]);
  1098. if (o == NULL)
  1099. ast_cli(a->fd, "No device [%s] exists\n", a->argv[3]);
  1100. else
  1101. oss_active = o->name;
  1102. }
  1103. return CLI_SUCCESS;
  1104. }
  1105. /*!
  1106. * \brief store the boost factor
  1107. */
  1108. static void store_boost(struct chan_oss_pvt *o, const char *s)
  1109. {
  1110. double boost = 0;
  1111. if (sscanf(s, "%30lf", &boost) != 1) {
  1112. ast_log(LOG_WARNING, "invalid boost <%s>\n", s);
  1113. return;
  1114. }
  1115. if (boost < -BOOST_MAX) {
  1116. ast_log(LOG_WARNING, "boost %s too small, using %d\n", s, -BOOST_MAX);
  1117. boost = -BOOST_MAX;
  1118. } else if (boost > BOOST_MAX) {
  1119. ast_log(LOG_WARNING, "boost %s too large, using %d\n", s, BOOST_MAX);
  1120. boost = BOOST_MAX;
  1121. }
  1122. boost = exp(log(10) * boost / 20) * BOOST_SCALE;
  1123. o->boost = boost;
  1124. ast_log(LOG_WARNING, "setting boost %s to %d\n", s, o->boost);
  1125. }
  1126. static char *console_boost(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1127. {
  1128. struct chan_oss_pvt *o = find_desc(oss_active);
  1129. switch (cmd) {
  1130. case CLI_INIT:
  1131. e->command = "console boost";
  1132. e->usage =
  1133. "Usage: console boost [boost in dB]\n"
  1134. " Sets or display mic boost in dB\n";
  1135. return NULL;
  1136. case CLI_GENERATE:
  1137. return NULL;
  1138. }
  1139. if (a->argc == 2)
  1140. ast_cli(a->fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE)));
  1141. else if (a->argc == 3)
  1142. store_boost(o, a->argv[2]);
  1143. return CLI_SUCCESS;
  1144. }
  1145. static struct ast_cli_entry cli_oss[] = {
  1146. AST_CLI_DEFINE(console_answer, "Answer an incoming console call"),
  1147. AST_CLI_DEFINE(console_hangup, "Hangup a call on the console"),
  1148. AST_CLI_DEFINE(console_flash, "Flash a call on the console"),
  1149. AST_CLI_DEFINE(console_dial, "Dial an extension on the console"),
  1150. AST_CLI_DEFINE(console_mute, "Disable/Enable mic input"),
  1151. AST_CLI_DEFINE(console_transfer, "Transfer a call to a different extension"),
  1152. AST_CLI_DEFINE(console_cmd, "Generic console command"),
  1153. AST_CLI_DEFINE(console_sendtext, "Send text to the remote device"),
  1154. AST_CLI_DEFINE(console_autoanswer, "Sets/displays autoanswer"),
  1155. AST_CLI_DEFINE(console_boost, "Sets/displays mic boost in dB"),
  1156. AST_CLI_DEFINE(console_active, "Sets/displays active console"),
  1157. };
  1158. /*!
  1159. * store the mixer argument from the config file, filtering possibly
  1160. * invalid or dangerous values (the string is used as argument for
  1161. * system("mixer %s")
  1162. */
  1163. static void store_mixer(struct chan_oss_pvt *o, const char *s)
  1164. {
  1165. int i;
  1166. for (i = 0; i < strlen(s); i++) {
  1167. if (!isalnum(s[i]) && strchr(" \t-/", s[i]) == NULL) {
  1168. ast_log(LOG_WARNING, "Suspect char %c in mixer cmd, ignoring:\n\t%s\n", s[i], s);
  1169. return;
  1170. }
  1171. }
  1172. if (o->mixer_cmd)
  1173. ast_free(o->mixer_cmd);
  1174. o->mixer_cmd = ast_strdup(s);
  1175. ast_log(LOG_WARNING, "setting mixer %s\n", s);
  1176. }
  1177. /*!
  1178. * store the callerid components
  1179. */
  1180. static void store_callerid(struct chan_oss_pvt *o, const char *s)
  1181. {
  1182. ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
  1183. }
  1184. static void store_config_core(struct chan_oss_pvt *o, const char *var, const char *value)
  1185. {
  1186. CV_START(var, value);
  1187. /* handle jb conf */
  1188. if (!ast_jb_read_conf(&global_jbconf, var, value))
  1189. return;
  1190. if (!console_video_config(&o->env, var, value))
  1191. return; /* matched there */
  1192. CV_BOOL("autoanswer", o->autoanswer);
  1193. CV_BOOL("autohangup", o->autohangup);
  1194. CV_BOOL("overridecontext", o->overridecontext);
  1195. CV_STR("device", o->device);
  1196. CV_UINT("frags", o->frags);
  1197. CV_UINT("debug", oss_debug);
  1198. CV_UINT("queuesize", o->queuesize);
  1199. CV_STR("context", o->ctx);
  1200. CV_STR("language", o->language);
  1201. CV_STR("mohinterpret", o->mohinterpret);
  1202. CV_STR("extension", o->ext);
  1203. CV_F("mixer", store_mixer(o, value));
  1204. CV_F("callerid", store_callerid(o, value)) ;
  1205. CV_F("boost", store_boost(o, value));
  1206. CV_END;
  1207. }
  1208. /*!
  1209. * grab fields from the config file, init the descriptor and open the device.
  1210. */
  1211. static struct chan_oss_pvt *store_config(struct ast_config *cfg, char *ctg)
  1212. {
  1213. struct ast_variable *v;
  1214. struct chan_oss_pvt *o;
  1215. if (ctg == NULL) {
  1216. o = &oss_default;
  1217. ctg = "general";
  1218. } else {
  1219. if (!(o = ast_calloc(1, sizeof(*o))))
  1220. return NULL;
  1221. *o = oss_default;
  1222. /* "general" is also the default thing */
  1223. if (strcmp(ctg, "general") == 0) {
  1224. o->name = ast_strdup("dsp");
  1225. oss_active = o->name;
  1226. goto openit;
  1227. }
  1228. o->name = ast_strdup(ctg);
  1229. }
  1230. strcpy(o->mohinterpret, "default");
  1231. o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
  1232. /* fill other fields from configuration */
  1233. for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
  1234. store_config_core(o, v->name, v->value);
  1235. }
  1236. if (ast_strlen_zero(o->device))
  1237. ast_copy_string(o->device, DEV_DSP, sizeof(o->device));
  1238. if (o->mixer_cmd) {
  1239. char *cmd;
  1240. if (ast_asprintf(&cmd, "mixer %s", o->mixer_cmd) >= 0) {
  1241. ast_log(LOG_WARNING, "running [%s]\n", cmd);
  1242. if (system(cmd) < 0) {
  1243. ast_log(LOG_WARNING, "system() failed: %s\n", strerror(errno));
  1244. }
  1245. ast_free(cmd);
  1246. }
  1247. }
  1248. /* if the config file requested to start the GUI, do it */
  1249. if (get_gui_startup(o->env))
  1250. console_video_start(o->env, NULL);
  1251. if (o == &oss_default) /* we are done with the default */
  1252. return NULL;
  1253. openit:
  1254. #ifdef TRYOPEN
  1255. if (setformat(o, O_RDWR) < 0) { /* open device */
  1256. ast_verb(1, "Device %s not detected\n", ctg);
  1257. ast_verb(1, "Turn off OSS support by adding " "'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
  1258. goto error;
  1259. }
  1260. if (o->duplex != CHAN_OSS_DUPLEX_FULL)
  1261. ast_log(LOG_WARNING, "XXX I don't work right with non " "full-duplex sound cards XXX\n");
  1262. #endif /* TRYOPEN */
  1263. /* link into list of devices */
  1264. if (o != &oss_default) {
  1265. o->next = oss_default.next;
  1266. oss_default.next = o;
  1267. }
  1268. return o;
  1269. #ifdef TRYOPEN
  1270. error:
  1271. if (o != &oss_default)
  1272. ast_free(o);
  1273. return NULL;
  1274. #endif
  1275. }
  1276. static int unload_module(void)
  1277. {
  1278. struct chan_oss_pvt *o, *next;
  1279. ast_channel_unregister(&oss_tech);
  1280. ast_cli_unregister_multiple(cli_oss, ARRAY_LEN(cli_oss));
  1281. o = oss_default.next;
  1282. while (o) {
  1283. close(o->sounddev);
  1284. if (o->owner)
  1285. ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
  1286. if (o->owner)
  1287. return -1;
  1288. next = o->next;
  1289. ast_free(o->name);
  1290. ast_free(o);
  1291. o = next;
  1292. }
  1293. ao2_cleanup(oss_tech.capabilities);
  1294. oss_tech.capabilities = NULL;
  1295. return 0;
  1296. }
  1297. /*!
  1298. * \brief Load the module
  1299. *
  1300. * Module loading including tests for configuration or dependencies.
  1301. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  1302. * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
  1303. * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
  1304. * configuration file or other non-critical problem return
  1305. * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  1306. */
  1307. static int load_module(void)
  1308. {
  1309. struct ast_config *cfg = NULL;
  1310. char *ctg = NULL;
  1311. struct ast_flags config_flags = { 0 };
  1312. /* Copy the default jb config over global_jbconf */
  1313. memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
  1314. /* load config file */
  1315. if (!(cfg = ast_config_load(config, config_flags))) {
  1316. ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
  1317. return AST_MODULE_LOAD_DECLINE;
  1318. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  1319. ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
  1320. return AST_MODULE_LOAD_DECLINE;
  1321. }
  1322. do {
  1323. store_config(cfg, ctg);
  1324. } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
  1325. ast_config_destroy(cfg);
  1326. if (find_desc(oss_active) == NULL) {
  1327. ast_log(LOG_NOTICE, "Device %s not found\n", oss_active);
  1328. /* XXX we could default to 'dsp' perhaps ? */
  1329. unload_module();
  1330. return AST_MODULE_LOAD_DECLINE;
  1331. }
  1332. if (!(oss_tech.capabilities = ast_format_cap_alloc(0))) {
  1333. return AST_MODULE_LOAD_DECLINE;
  1334. }
  1335. ast_format_cap_append(oss_tech.capabilities, ast_format_slin, 0);
  1336. /* TODO XXX CONSOLE VIDEO IS DISABLE UNTIL IT HAS A MAINTAINER
  1337. * add console_video_formats to oss_tech.capabilities once this occurs. */
  1338. if (ast_channel_register(&oss_tech)) {
  1339. ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n");
  1340. return AST_MODULE_LOAD_DECLINE;
  1341. }
  1342. ast_cli_register_multiple(cli_oss, ARRAY_LEN(cli_oss));
  1343. return AST_MODULE_LOAD_SUCCESS;
  1344. }
  1345. AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "OSS Console Channel Driver");