chan_usbradio.c 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. * Copyright (C) 2007, Jim Dixon
  6. *
  7. * Jim Dixon, WB6NIL <jim@lambdatel.com>
  8. * Steve Henke, W9SH <w9sh@arrl.net>
  9. * Based upon work by Mark Spencer <markster@digium.com> and Luigi Rizzo
  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. /*! \file
  22. *
  23. * \brief Channel driver for CM108 USB Cards with Radio Interface
  24. *
  25. * \author Jim Dixon <jim@lambdatel.com>
  26. * \author Steve Henke <w9sh@arrl.net>
  27. *
  28. * \par See also
  29. * \arg \ref Config_usbradio
  30. *
  31. * \ingroup channel_drivers
  32. */
  33. /*** MODULEINFO
  34. <depend>asound</depend>
  35. <depend>alsa</depend>
  36. <depend>usb</depend>
  37. <defaultenabled>no</defaultenabled>
  38. ***/
  39. #include "asterisk.h"
  40. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  41. #include <ctype.h>
  42. #include <math.h>
  43. #include <sys/ioctl.h>
  44. #include <fcntl.h>
  45. #include <sys/time.h>
  46. #include <usb.h>
  47. #include <alsa/asoundlib.h>
  48. #define CHAN_USBRADIO 1
  49. #define DEBUG_USBRADIO 0
  50. #define DEBUG_CAPTURES 1
  51. #define DEBUG_CAP_RX_OUT 0
  52. #define DEBUG_CAP_TX_OUT 0
  53. #define DEBUG_FILETEST 0
  54. #define RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm"
  55. #define RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm"
  56. #define RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm"
  57. #define TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm"
  58. #define TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm"
  59. #define TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm"
  60. #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
  61. #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
  62. #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
  63. #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
  64. #define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
  65. #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
  66. #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
  67. #include "./xpmr/xpmr.h"
  68. #if 0
  69. #define traceusb1(a, ...) ast_debug(4, a __VA_ARGS__)
  70. #else
  71. #define traceusb1(a, ...)
  72. #endif
  73. #if 0
  74. #define traceusb2(a, ...) ast_debug(4, a __VA_ARGS__)
  75. #else
  76. #define traceusb2(a, ...)
  77. #endif
  78. #ifdef __linux
  79. #include <linux/soundcard.h>
  80. #elif defined(__FreeBSD__)
  81. #include <sys/soundcard.h>
  82. #else
  83. #include <soundcard.h>
  84. #endif
  85. #include "asterisk/lock.h"
  86. #include "asterisk/frame.h"
  87. #include "asterisk/callerid.h"
  88. #include "asterisk/channel.h"
  89. #include "asterisk/module.h"
  90. #include "asterisk/pbx.h"
  91. #include "asterisk/config.h"
  92. #include "asterisk/cli.h"
  93. #include "asterisk/utils.h"
  94. #include "asterisk/causes.h"
  95. #include "asterisk/endian.h"
  96. #include "asterisk/stringfields.h"
  97. #include "asterisk/abstract_jb.h"
  98. #include "asterisk/musiconhold.h"
  99. #include "asterisk/dsp.h"
  100. #define C108_VENDOR_ID 0x0d8c
  101. #define C108_PRODUCT_ID 0x000c
  102. #define C108_HID_INTERFACE 3
  103. #define HID_REPORT_GET 0x01
  104. #define HID_REPORT_SET 0x09
  105. #define HID_RT_INPUT 0x01
  106. #define HID_RT_OUTPUT 0x02
  107. /*! Global jitterbuffer configuration - by default, jb is disabled */
  108. static struct ast_jb_conf default_jbconf =
  109. {
  110. .flags = 0,
  111. .max_size = -1,
  112. .resync_threshold = -1,
  113. .impl = "",
  114. .target_extra = -1,
  115. };
  116. static struct ast_jb_conf global_jbconf;
  117. /*!
  118. * usbradio.conf parameters are
  119. START_CONFIG
  120. [general]
  121. ; General config options, with default values shown.
  122. ; You should use one section per device, with [general] being used
  123. ; for the device.
  124. ;
  125. ;
  126. ; debug = 0x0 ; misc debug flags, default is 0
  127. ; Set the device to use for I/O
  128. ; devicenum = 0
  129. ; Set hardware type here
  130. ; hdwtype=0 ; 0=limey, 1=sph
  131. ; rxboostset=0 ; no rx gain boost
  132. ; rxctcssrelax=1 ; reduce talkoff from radios w/o CTCSS Tx HPF
  133. ; rxctcssfreq=100.0 ; rx ctcss freq in floating point. must be in table
  134. ; txctcssfreq=100.0 ; tx ctcss freq, any frequency permitted
  135. ; carrierfrom=dsp ;no,usb,usbinvert,dsp,vox
  136. ; ctcssfrom=dsp ;no,usb,dsp
  137. ; rxdemod=flat ; input type from radio: no,speaker,flat
  138. ; txprelim=yes ; output is pre-emphasised and limited
  139. ; txtoctype=no ; no,phase,notone
  140. ; txmixa=composite ;no,voice,tone,composite,auxvoice
  141. ; txmixb=no ;no,voice,tone,composite,auxvoice
  142. ; invertptt=0
  143. ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
  144. ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
  145. ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will
  146. ; be used only if the sending side can create and the receiving
  147. ; side can not accept jitter. The USBRADIO channel can't accept jitter,
  148. ; thus an enabled jitterbuffer on the receive USBRADIO side will always
  149. ; be used if the sending side can create jitter.
  150. ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
  151. ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
  152. ; resynchronized. Useful to improve the quality of the voice, with
  153. ; big jumps in/broken timestamps, usualy sent from exotic devices
  154. ; and programs. Defaults to 1000.
  155. ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an USBRADIO
  156. ; channel. Two implementations are currenlty available - "fixed"
  157. ; (with size always equals to jbmax-size) and "adaptive" (with
  158. ; variable size, actually the new jb of IAX2). Defaults to fixed.
  159. ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
  160. ;-----------------------------------------------------------------------------------
  161. END_CONFIG
  162. */
  163. /*!
  164. * The following parameters are used in the driver:
  165. *
  166. * FRAME_SIZE the size of an audio frame, in samples.
  167. * 160 is used almost universally, so you should not change it.
  168. *
  169. * FRAGS the argument for the SETFRAGMENT ioctl.
  170. * Overridden by the 'frags' parameter in usbradio.conf
  171. *
  172. * Bits 0-7 are the base-2 log of the device's block size,
  173. * bits 16-31 are the number of blocks in the driver's queue.
  174. * There are a lot of differences in the way this parameter
  175. * is supported by different drivers, so you may need to
  176. * experiment a bit with the value.
  177. * A good default for linux is 30 blocks of 64 bytes, which
  178. * results in 6 frames of 320 bytes (160 samples).
  179. * FreeBSD works decently with blocks of 256 or 512 bytes,
  180. * leaving the number unspecified.
  181. * Note that this only refers to the device buffer size,
  182. * this module will then try to keep the lenght of audio
  183. * buffered within small constraints.
  184. *
  185. * QUEUE_SIZE The max number of blocks actually allowed in the device
  186. * driver's buffer, irrespective of the available number.
  187. * Overridden by the 'queuesize' parameter in usbradio.conf
  188. *
  189. * Should be >=2, and at most as large as the hw queue above
  190. * (otherwise it will never be full).
  191. */
  192. #define FRAME_SIZE 160
  193. #define QUEUE_SIZE 20
  194. #if defined(__FreeBSD__)
  195. #define FRAGS 0x8
  196. #else
  197. #define FRAGS ( ( (6 * 5) << 16 ) | 0xc )
  198. #endif
  199. /*
  200. * XXX text message sizes are probably 256 chars, but i am
  201. * not sure if there is a suitable definition anywhere.
  202. */
  203. #define TEXT_SIZE 256
  204. #if 0
  205. #define TRYOPEN 1 /* try to open on startup */
  206. #endif
  207. #define O_CLOSE 0x444 /* special 'close' mode for device */
  208. /* Which device to use */
  209. #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
  210. #define DEV_DSP "/dev/audio"
  211. #else
  212. #define DEV_DSP "/dev/dsp"
  213. #endif
  214. static const char *config = "usbradio.conf"; /* default config file */
  215. static const char *config1 = "usbradio_tune.conf"; /* tune config file */
  216. static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
  217. static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
  218. static int usbradio_debug;
  219. #if 0 /* maw asdf sph */
  220. static int usbradio_debug_level = 0;
  221. #endif
  222. enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
  223. enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
  224. enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR}; /* no,external,externalinvert,software */
  225. enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
  226. enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
  227. enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
  228. /* DECLARE STRUCTURES */
  229. /*
  230. * descriptor for one of our channels.
  231. * There is one used for 'default' values (from the [general] entry in
  232. * the configuration file), and then one instance for each device
  233. * (the default is cloned from [general], others are only created
  234. * if the relevant section exists).
  235. */
  236. struct chan_usbradio_pvt {
  237. struct chan_usbradio_pvt *next;
  238. char *name;
  239. int total_blocks; /* total blocks in the output device */
  240. int sounddev;
  241. enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
  242. i16 cdMethod;
  243. int autoanswer;
  244. int autohangup;
  245. int hookstate;
  246. unsigned int queuesize; /* max fragments in queue */
  247. unsigned int frags; /* parameter for SETFRAGMENT */
  248. int warned; /* various flags used for warnings */
  249. #define WARN_used_blocks 1
  250. #define WARN_speed 2
  251. #define WARN_frag 4
  252. int w_errors; /* overfull in the write path */
  253. struct timeval lastopen;
  254. int overridecontext;
  255. int mute;
  256. /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
  257. * be representable in 16 bits to avoid overflows.
  258. */
  259. #define BOOST_SCALE (1<<9)
  260. #define BOOST_MAX 40 /* slightly less than 7 bits */
  261. int boost; /* input boost, scaled by BOOST_SCALE */
  262. char devicenum;
  263. int spkrmax;
  264. int micmax;
  265. pthread_t sthread;
  266. pthread_t hidthread;
  267. int stophid;
  268. struct ast_channel *owner;
  269. char ext[AST_MAX_EXTENSION];
  270. char ctx[AST_MAX_CONTEXT];
  271. char language[MAX_LANGUAGE];
  272. char cid_name[256]; /* XXX */
  273. char cid_num[256]; /* XXX */
  274. char mohinterpret[MAX_MUSICCLASS];
  275. /* buffers used in usbradio_write, 2 per int by 2 channels by 6 times oversampling (48KS/s) */
  276. char usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];
  277. char usbradio_write_buf_1[FRAME_SIZE * 2 * 2 * 6];
  278. int usbradio_write_dst;
  279. /* buffers used in usbradio_read - AST_FRIENDLY_OFFSET space for headers
  280. * plus enough room for a full frame
  281. */
  282. char usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
  283. char usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
  284. int readpos; /* read position above */
  285. struct ast_frame read_f; /* returned by usbradio_read */
  286. char debuglevel;
  287. char radioduplex;
  288. char lastrx;
  289. char rxhidsq;
  290. char rxcarrierdetect; /*!< status from pmr channel */
  291. char rxctcssdecode; /*!< status from pmr channel */
  292. char rxkeytype;
  293. char rxkeyed; /*!< indicates rx signal present */
  294. char lasttx;
  295. char txkeyed; /*! tx key request from upper layers */
  296. char txchankey;
  297. char txtestkey;
  298. time_t lasthidtime;
  299. struct ast_dsp *dsp;
  300. t_pmr_chan *pmrChan;
  301. char rxcpusaver;
  302. char txcpusaver;
  303. char rxdemod;
  304. float rxgain;
  305. char rxcdtype;
  306. char rxsdtype;
  307. int rxsquelchadj; /*!< this copy needs to be here for initialization */
  308. char txtoctype;
  309. char txprelim;
  310. float txctcssgain;
  311. char txmixa;
  312. char txmixb;
  313. char invertptt;
  314. char rxctcssrelax;
  315. float rxctcssgain;
  316. float rxctcssfreq;
  317. float txctcssfreq;
  318. int rxmixerset;
  319. int rxboostset;
  320. float rxvoiceadj;
  321. float rxctcssadj;
  322. int txmixaset;
  323. int txmixbset;
  324. int txctcssadj;
  325. int hdwtype;
  326. int hid_gpio_ctl;
  327. int hid_gpio_ctl_loc;
  328. int hid_io_cor;
  329. int hid_io_cor_loc;
  330. int hid_io_ctcss;
  331. int hid_io_ctcss_loc;
  332. int hid_io_ptt;
  333. int hid_gpio_loc;
  334. struct {
  335. unsigned rxcapraw:1;
  336. unsigned txcapraw:1;
  337. unsigned txcap2:1;
  338. unsigned rxcap2:1;
  339. } b;
  340. };
  341. /* maw add additional defaults !!! */
  342. static struct chan_usbradio_pvt usbradio_default = {
  343. .sounddev = -1,
  344. .duplex = M_UNSET, /* XXX check this */
  345. .autoanswer = 1,
  346. .autohangup = 1,
  347. .queuesize = QUEUE_SIZE,
  348. .frags = FRAGS,
  349. .ext = "s",
  350. .ctx = "default",
  351. .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
  352. .lastopen = { 0, 0 },
  353. .boost = BOOST_SCALE,
  354. };
  355. /* DECLARE FUNCTION PROTOTYPES */
  356. static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s);
  357. static int hidhdwconfig(struct chan_usbradio_pvt *o);
  358. static int set_txctcss_level(struct chan_usbradio_pvt *o);
  359. static void pmrdump(struct chan_usbradio_pvt *o);
  360. static void mult_set(struct chan_usbradio_pvt *o);
  361. static int mult_calc(int value);
  362. static void mixer_write(struct chan_usbradio_pvt *o);
  363. static void tune_rxinput(struct chan_usbradio_pvt *o);
  364. static void tune_rxvoice(struct chan_usbradio_pvt *o);
  365. static void tune_rxctcss(struct chan_usbradio_pvt *o);
  366. static void tune_txoutput(struct chan_usbradio_pvt *o, int value);
  367. static void tune_write(struct chan_usbradio_pvt *o);
  368. static char *usbradio_active; /* the active device */
  369. static int setformat(struct chan_usbradio_pvt *o, int mode);
  370. static struct ast_channel *usbradio_request(const char *type, int format, void *data
  371. , int *cause);
  372. static int usbradio_digit_begin(struct ast_channel *c, char digit);
  373. static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
  374. static int usbradio_text(struct ast_channel *c, const char *text);
  375. static int usbradio_hangup(struct ast_channel *c);
  376. static int usbradio_answer(struct ast_channel *c);
  377. static struct ast_frame *usbradio_read(struct ast_channel *chan);
  378. static int usbradio_call(struct ast_channel *c, char *dest, int timeout);
  379. static int usbradio_write(struct ast_channel *chan, struct ast_frame *f);
  380. static int usbradio_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
  381. static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  382. #if DEBUG_FILETEST == 1
  383. static int RxTestIt(struct chan_usbradio_pvt *o);
  384. #endif
  385. static char tdesc[] = "USB (CM108) Radio Channel Driver";
  386. static const struct ast_channel_tech usbradio_tech = {
  387. .type = "Radio",
  388. .description = tdesc,
  389. .capabilities = AST_FORMAT_SLINEAR,
  390. .requester = usbradio_request,
  391. .send_digit_begin = usbradio_digit_begin,
  392. .send_digit_end = usbradio_digit_end,
  393. .send_text = usbradio_text,
  394. .hangup = usbradio_hangup,
  395. .answer = usbradio_answer,
  396. .read = usbradio_read,
  397. .call = usbradio_call,
  398. .write = usbradio_write,
  399. .indicate = usbradio_indicate,
  400. .fixup = usbradio_fixup,
  401. };
  402. /* Call with: devnum: alsa major device number, param: ascii Formal
  403. Parameter Name, val1, first or only value, val2 second value, or 0
  404. if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
  405. Note: must add -lasound to end of linkage */
  406. static int amixer_max(int devnum,char *param)
  407. {
  408. int rv,type;
  409. char str[15];
  410. snd_hctl_t *hctl;
  411. snd_ctl_elem_id_t *id;
  412. snd_hctl_elem_t *elem;
  413. snd_ctl_elem_info_t *info;
  414. snprintf(str, sizeof(str), "hw:%d", devnum);
  415. if (snd_hctl_open(&hctl, str, 0))
  416. return -1;
  417. snd_hctl_load(hctl);
  418. id = alloca(snd_ctl_elem_id_sizeof());
  419. memset(id, 0, snd_ctl_elem_id_sizeof());
  420. snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
  421. snd_ctl_elem_id_set_name(id, param);
  422. elem = snd_hctl_find_elem(hctl, id);
  423. if (!elem) {
  424. snd_hctl_close(hctl);
  425. return -1;
  426. }
  427. info = alloca(snd_ctl_elem_info_sizeof());
  428. memset(info, 0, snd_ctl_elem_info_sizeof());
  429. snd_hctl_elem_info(elem,info);
  430. type = snd_ctl_elem_info_get_type(info);
  431. rv = 0;
  432. switch (type) {
  433. case SND_CTL_ELEM_TYPE_INTEGER:
  434. rv = snd_ctl_elem_info_get_max(info);
  435. break;
  436. case SND_CTL_ELEM_TYPE_BOOLEAN:
  437. rv = 1;
  438. break;
  439. }
  440. snd_hctl_close(hctl);
  441. return(rv);
  442. }
  443. /*! \brief Call with: devnum: alsa major device number, param: ascii Formal
  444. Parameter Name, val1, first or only value, val2 second value, or 0
  445. if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
  446. Note: must add -lasound to end of linkage */
  447. static int setamixer(int devnum, char *param, int v1, int v2)
  448. {
  449. int type;
  450. char str[15];
  451. snd_hctl_t *hctl;
  452. snd_ctl_elem_id_t *id;
  453. snd_ctl_elem_value_t *control;
  454. snd_hctl_elem_t *elem;
  455. snd_ctl_elem_info_t *info;
  456. snprintf(str, sizeof(str), "hw:%d", devnum);
  457. if (snd_hctl_open(&hctl, str, 0))
  458. return -1;
  459. snd_hctl_load(hctl);
  460. id = alloca(snd_ctl_elem_id_sizeof());
  461. memset(id, 0, snd_ctl_elem_id_sizeof());
  462. snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
  463. snd_ctl_elem_id_set_name(id, param);
  464. elem = snd_hctl_find_elem(hctl, id);
  465. if (!elem) {
  466. snd_hctl_close(hctl);
  467. return -1;
  468. }
  469. info = alloca(snd_ctl_elem_info_sizeof());
  470. memset(info, 0, snd_ctl_elem_info_sizeof());
  471. snd_hctl_elem_info(elem,info);
  472. type = snd_ctl_elem_info_get_type(info);
  473. control = alloca(snd_ctl_elem_value_sizeof());
  474. memset(control, 0, snd_ctl_elem_value_sizeof());
  475. snd_ctl_elem_value_set_id(control, id);
  476. switch (type) {
  477. case SND_CTL_ELEM_TYPE_INTEGER:
  478. snd_ctl_elem_value_set_integer(control, 0, v1);
  479. if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
  480. break;
  481. case SND_CTL_ELEM_TYPE_BOOLEAN:
  482. snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
  483. break;
  484. }
  485. if (snd_hctl_elem_write(elem, control)) {
  486. snd_hctl_close(hctl);
  487. return(-1);
  488. }
  489. snd_hctl_close(hctl);
  490. return 0;
  491. }
  492. static void hid_set_outputs(struct usb_dev_handle *handle,
  493. unsigned char *outputs)
  494. {
  495. usb_control_msg(handle,
  496. USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
  497. HID_REPORT_SET,
  498. 0 + (HID_RT_OUTPUT << 8),
  499. C108_HID_INTERFACE,
  500. (char *)outputs, 4, 5000);
  501. }
  502. static void hid_get_inputs(struct usb_dev_handle *handle,
  503. unsigned char *inputs)
  504. {
  505. usb_control_msg(handle,
  506. USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
  507. HID_REPORT_GET,
  508. 0 + (HID_RT_INPUT << 8),
  509. C108_HID_INTERFACE,
  510. (char *)inputs, 4, 5000);
  511. }
  512. static struct usb_device *hid_device_init(void)
  513. {
  514. struct usb_bus *usb_bus;
  515. struct usb_device *dev;
  516. usb_init();
  517. usb_find_busses();
  518. usb_find_devices();
  519. for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) {
  520. for (dev = usb_bus->devices; dev; dev = dev->next) {
  521. if ((dev->descriptor.idVendor == C108_VENDOR_ID) && (dev->descriptor.idProduct == C108_PRODUCT_ID))
  522. return dev;
  523. }
  524. }
  525. return NULL;
  526. }
  527. static int hidhdwconfig(struct chan_usbradio_pvt *o)
  528. {
  529. if (o->hdwtype == 1) { /*sphusb */
  530. o->hid_gpio_ctl = 0x08; /* set GPIO4 to output mode */
  531. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  532. o->hid_io_cor = 4; /* GPIO3 is COR */
  533. o->hid_io_cor_loc = 1; /* GPIO3 is COR */
  534. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  535. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  536. o->hid_io_ptt = 8; /* GPIO 4 is PTT */
  537. o->hid_gpio_loc = 1; /* For ALL GPIO */
  538. } else if (o->hdwtype == 0) { /* dudeusb */
  539. o->hid_gpio_ctl = 0x0c;/* set GPIO 3 & 4 to output mode */
  540. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  541. o->hid_io_cor = 2; /* VOLD DN is COR */
  542. o->hid_io_cor_loc = 0; /* VOL DN COR */
  543. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  544. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  545. o->hid_io_ptt = 4; /* GPIO 3 is PTT */
  546. o->hid_gpio_loc = 1; /* For ALL GPIO */
  547. } else if (o->hdwtype == 3) { /* custom version */
  548. o->hid_gpio_ctl = 0x0c; /* set GPIO 3 & 4 to output mode */
  549. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  550. o->hid_io_cor = 2; /* VOLD DN is COR */
  551. o->hid_io_cor_loc = 0; /* VOL DN COR */
  552. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  553. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  554. o->hid_io_ptt = 4; /* GPIO 3 is PTT */
  555. o->hid_gpio_loc = 1; /* For ALL GPIO */
  556. }
  557. return 0;
  558. }
  559. static void *hidthread(void *arg)
  560. {
  561. unsigned char buf[4], keyed;
  562. char lastrx, txtmp;
  563. struct usb_device *usb_dev;
  564. struct usb_dev_handle *usb_handle;
  565. struct chan_usbradio_pvt *o = arg;
  566. usb_dev = hid_device_init();
  567. if (usb_dev == NULL) {
  568. ast_log(LOG_ERROR, "USB HID device not found\n");
  569. pthread_exit(NULL);
  570. }
  571. usb_handle = usb_open(usb_dev);
  572. if (usb_handle == NULL) {
  573. ast_log(LOG_ERROR, "Not able to open USB device\n");
  574. pthread_exit(NULL);
  575. }
  576. if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
  577. if (usb_detach_kernel_driver_np(usb_handle, C108_HID_INTERFACE) < 0) {
  578. ast_log(LOG_ERROR, "Not able to detach the USB device\n");
  579. pthread_exit(NULL);
  580. }
  581. if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
  582. ast_log(LOG_ERROR, "Not able to claim the USB device\n");
  583. pthread_exit(NULL);
  584. }
  585. }
  586. memset(buf, 0, sizeof(buf));
  587. buf[2] = o->hid_gpio_ctl;
  588. buf[1] = 0;
  589. hid_set_outputs(usb_handle, buf);
  590. traceusb1("hidthread: Starting normally!!\n");
  591. lastrx = 0;
  592. while (!o->stophid) {
  593. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  594. hid_get_inputs(usb_handle, buf);
  595. keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
  596. if (keyed != o->rxhidsq) {
  597. if (o->debuglevel)
  598. ast_log(LOG_NOTICE, "chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
  599. o->rxhidsq = keyed;
  600. }
  601. /* if change in tx stuff */
  602. txtmp = 0;
  603. if (o->txkeyed || o->txchankey || o->txtestkey || o->pmrChan->txPttOut)
  604. txtmp = 1;
  605. if (o->lasttx != txtmp) {
  606. o->lasttx = txtmp;
  607. if (o->debuglevel)
  608. ast_log(LOG_NOTICE, "hidthread: tx set to %d\n", txtmp);
  609. buf[o->hid_gpio_loc] = 0;
  610. if (txtmp)
  611. buf[o->hid_gpio_loc] = o->hid_io_ptt;
  612. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  613. hid_set_outputs(usb_handle, buf);
  614. }
  615. time(&o->lasthidtime);
  616. usleep(50000);
  617. }
  618. buf[o->hid_gpio_loc] = 0;
  619. if (o->invertptt)
  620. buf[o->hid_gpio_loc] = o->hid_io_ptt;
  621. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  622. hid_set_outputs(usb_handle, buf);
  623. pthread_exit(0);
  624. }
  625. /*! \brief
  626. * returns a pointer to the descriptor with the given name
  627. */
  628. static struct chan_usbradio_pvt *find_desc(char *dev)
  629. {
  630. struct chan_usbradio_pvt *o = NULL;
  631. if (!dev)
  632. ast_log(LOG_WARNING, "null dev\n");
  633. for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
  634. if (!o)
  635. ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
  636. return o;
  637. }
  638. /*! \brief
  639. * split a string in extension-context, returns pointers to malloc'ed
  640. * strings.
  641. * If we do not have 'overridecontext' then the last @ is considered as
  642. * a context separator, and the context is overridden.
  643. * This is usually not very necessary as you can play with the dialplan,
  644. * and it is nice not to need it because you have '@' in SIP addresses.
  645. * Return value is the buffer address.
  646. */
  647. #if 0
  648. static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
  649. {
  650. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  651. if (ext == NULL || ctx == NULL)
  652. return NULL; /* error */
  653. *ext = *ctx = NULL;
  654. if (src && *src != '\0')
  655. *ext = ast_strdup(src);
  656. if (*ext == NULL)
  657. return NULL;
  658. if (!o->overridecontext) {
  659. /* parse from the right */
  660. *ctx = strrchr(*ext, '@');
  661. if (*ctx)
  662. *(*ctx)++ = '\0';
  663. }
  664. return *ext;
  665. }
  666. #endif
  667. /*! \brief
  668. * Returns the number of blocks used in the audio output channel
  669. */
  670. static int used_blocks(struct chan_usbradio_pvt *o)
  671. {
  672. struct audio_buf_info info;
  673. if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
  674. if (!(o->warned & WARN_used_blocks)) {
  675. ast_log(LOG_WARNING, "Error reading output space\n");
  676. o->warned |= WARN_used_blocks;
  677. }
  678. return 1;
  679. }
  680. if (o->total_blocks == 0) {
  681. ast_debug(4, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
  682. o->total_blocks = info.fragments;
  683. }
  684. return o->total_blocks - info.fragments;
  685. }
  686. /*! \brief Write an exactly FRAME_SIZE sized frame */
  687. static int soundcard_writeframe(struct chan_usbradio_pvt *o, short *data)
  688. {
  689. int res;
  690. if (o->sounddev < 0)
  691. setformat(o, O_RDWR);
  692. if (o->sounddev < 0)
  693. return 0; /* not fatal */
  694. /*
  695. * Nothing complex to manage the audio device queue.
  696. * If the buffer is full just drop the extra, otherwise write.
  697. * XXX in some cases it might be useful to write anyways after
  698. * a number of failures, to restart the output chain.
  699. */
  700. res = used_blocks(o);
  701. if (res > o->queuesize) { /* no room to write a block */
  702. if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
  703. ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
  704. return 0;
  705. }
  706. o->w_errors = 0;
  707. return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
  708. }
  709. /*
  710. * reset and close the device if opened,
  711. * then open and initialize it in the desired mode,
  712. * trigger reads and writes so we can start using it.
  713. */
  714. static int setformat(struct chan_usbradio_pvt *o, int mode)
  715. {
  716. int fmt, desired, res, fd;
  717. char device[20];
  718. if (o->sounddev >= 0) {
  719. ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
  720. close(o->sounddev);
  721. o->duplex = M_UNSET;
  722. o->sounddev = -1;
  723. }
  724. if (mode == O_CLOSE) /* we are done */
  725. return 0;
  726. if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
  727. return -1; /* don't open too often */
  728. o->lastopen = ast_tvnow();
  729. strcpy(device, "/dev/dsp");
  730. if (o->devicenum)
  731. snprintf(device + strlen("/dev/dsp"), sizeof(device) - strlen("/dev/dsp"), "%d", o->devicenum);
  732. fd = o->sounddev = open(device, mode | O_NONBLOCK);
  733. if (fd < 0) {
  734. ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
  735. return -1;
  736. }
  737. if (o->owner)
  738. o->owner->fds[0] = fd;
  739. #if __BYTE_ORDER == __LITTLE_ENDIAN
  740. fmt = AFMT_S16_LE;
  741. #else
  742. fmt = AFMT_S16_BE;
  743. #endif
  744. res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
  745. if (res < 0) {
  746. ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
  747. return -1;
  748. }
  749. switch (mode) {
  750. case O_RDWR:
  751. res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
  752. /* Check to see if duplex set (FreeBSD Bug) */
  753. res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
  754. if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
  755. ast_verb(2, "Console is full duplex\n");
  756. o->duplex = M_FULL;
  757. };
  758. break;
  759. case O_WRONLY:
  760. o->duplex = M_WRITE;
  761. break;
  762. case O_RDONLY:
  763. o->duplex = M_READ;
  764. break;
  765. }
  766. fmt = 1;
  767. res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
  768. if (res < 0) {
  769. ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
  770. return -1;
  771. }
  772. fmt = desired = 48000; /* 8000 Hz desired */
  773. res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
  774. if (res < 0) {
  775. ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
  776. return -1;
  777. }
  778. if (fmt != desired) {
  779. if (!(o->warned & WARN_speed)) {
  780. ast_log(LOG_WARNING,
  781. "Requested %d Hz, got %d Hz -- sound may be choppy\n",
  782. desired, fmt);
  783. o->warned |= WARN_speed;
  784. }
  785. }
  786. /*
  787. * on Freebsd, SETFRAGMENT does not work very well on some cards.
  788. * Default to use 256 bytes, let the user override
  789. */
  790. if (o->frags) {
  791. fmt = o->frags;
  792. res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
  793. if (res < 0) {
  794. if (!(o->warned & WARN_frag)) {
  795. ast_log(LOG_WARNING,
  796. "Unable to set fragment size -- sound may be choppy\n");
  797. o->warned |= WARN_frag;
  798. }
  799. }
  800. }
  801. /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
  802. res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
  803. res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
  804. /* it may fail if we are in half duplex, never mind */
  805. return 0;
  806. }
  807. /*
  808. * some of the standard methods supported by channels.
  809. */
  810. static int usbradio_digit_begin(struct ast_channel *c, char digit)
  811. {
  812. return 0;
  813. }
  814. static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
  815. {
  816. /* no better use for received digits than print them */
  817. ast_verb(0, " << Console Received digit %c of duration %u ms >> \n",
  818. digit, duration);
  819. return 0;
  820. }
  821. static int usbradio_text(struct ast_channel *c, const char *text)
  822. {
  823. /* print received messages */
  824. ast_verb(0, " << Console Received text %s >> \n", text);
  825. return 0;
  826. }
  827. /*
  828. * handler for incoming calls. Either autoanswer, or start ringing
  829. */
  830. static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
  831. {
  832. struct chan_usbradio_pvt *o = c->tech_pvt;
  833. time(&o->lasthidtime);
  834. ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
  835. ast_setstate(c, AST_STATE_UP);
  836. return 0;
  837. }
  838. /*
  839. * remote side answered the phone
  840. */
  841. static int usbradio_answer(struct ast_channel *c)
  842. {
  843. ast_setstate(c, AST_STATE_UP);
  844. return 0;
  845. }
  846. static int usbradio_hangup(struct ast_channel *c)
  847. {
  848. struct chan_usbradio_pvt *o = c->tech_pvt;
  849. c->tech_pvt = NULL;
  850. o->owner = NULL;
  851. ast_module_unref(ast_module_info->self);
  852. if (o->hookstate) {
  853. if (o->autoanswer || o->autohangup) {
  854. /* Assume auto-hangup too */
  855. o->hookstate = 0;
  856. setformat(o, O_CLOSE);
  857. }
  858. }
  859. o->stophid = 1;
  860. pthread_join(o->hidthread, NULL);
  861. return 0;
  862. }
  863. /* used for data coming from the network */
  864. static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
  865. {
  866. int src,datalen;
  867. struct chan_usbradio_pvt *o = c->tech_pvt;
  868. traceusb2("usbradio_write() o->nosound=%d\n", o->nosound); /*sph maw asdf */
  869. /*
  870. * we could receive a block which is not a multiple of our
  871. * FRAME_SIZE, so buffer it locally and write to the device
  872. * in FRAME_SIZE chunks.
  873. * Keep the residue stored for future use.
  874. */
  875. if (o->txkeyed || o->txtestkey)
  876. o->pmrChan->txPttIn = 1;
  877. else
  878. o->pmrChan->txPttIn = 0;
  879. #if DEBUG_CAPTURES == 1 /* to write input data to a file datalen=320 */
  880. if (ftxcapraw && o->b.txcapraw) {
  881. i16 i, tbuff[f->datalen];
  882. for (i = 0; i < f->datalen; i += 2) {
  883. tbuff[i] = ((i16 *)(f->data))[i / 2];
  884. tbuff[i + 1] = o->txkeyed * M_Q13;
  885. }
  886. if (fwrite(tbuff, 2, f->datalen, ftxcapraw) != f->datalen) {
  887. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  888. }
  889. /*fwrite(f->data,1,f->datalen,ftxcapraw); */
  890. }
  891. #endif
  892. PmrTx(o->pmrChan,(i16*)f->data,(i16*)o->usbradio_write_buf_1);
  893. #if 0 /* to write 48KS/s stereo data to a file */
  894. if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
  895. if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,f->datalen * 2 * 6,ftxoutraw);
  896. #endif
  897. #if DEBUG_CAPTURES == 1
  898. if ((o->b.txcap2 && ftxcaptrace) && (fwrite((o->pmrChan->ptxDebug), 1, FRAME_SIZE * 2 * 16, ftxcaptrace) != FRAME_SIZE * 2 * 16)) {
  899. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  900. }
  901. #endif
  902. src = 0; /* read position into f->data */
  903. datalen = f->datalen * 12;
  904. while (src < datalen) {
  905. /* Compute spare room in the buffer */
  906. int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
  907. if (datalen - src >= l) { /* enough to fill a frame */
  908. memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
  909. soundcard_writeframe(o, (short *) o->usbradio_write_buf);
  910. src += l;
  911. o->usbradio_write_dst = 0;
  912. } else { /* copy residue */
  913. l = datalen - src;
  914. memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
  915. src += l; /* but really, we are done */
  916. o->usbradio_write_dst += l;
  917. }
  918. }
  919. return 0;
  920. }
  921. static struct ast_frame *usbradio_read(struct ast_channel *c)
  922. {
  923. int res;
  924. struct chan_usbradio_pvt *o = c->tech_pvt;
  925. struct ast_frame *f = &o->read_f, *f1;
  926. struct ast_frame wf = { AST_FRAME_CONTROL };
  927. time_t now;
  928. traceusb2("usbradio_read()\n"); /* sph maw asdf */
  929. if (o->lasthidtime) {
  930. time(&now);
  931. if ((now - o->lasthidtime) > 3) {
  932. ast_log(LOG_ERROR, "HID process has died or something!!\n");
  933. return NULL;
  934. }
  935. }
  936. if (o->lastrx && (!o->rxkeyed)) {
  937. o->lastrx = 0;
  938. wf.subclass = AST_CONTROL_RADIO_UNKEY;
  939. ast_queue_frame(o->owner, &wf);
  940. } else if ((!o->lastrx) && (o->rxkeyed)) {
  941. o->lastrx = 1;
  942. wf.subclass = AST_CONTROL_RADIO_KEY;
  943. ast_queue_frame(o->owner, &wf);
  944. }
  945. /* XXX can be simplified returning &ast_null_frame */
  946. /* prepare a NULL frame in case we don't have enough data to return */
  947. memset(f, 0, sizeof(struct ast_frame));
  948. f->frametype = AST_FRAME_NULL;
  949. f->src = usbradio_tech.type;
  950. res = read(o->sounddev, o->usbradio_read_buf + o->readpos,
  951. sizeof(o->usbradio_read_buf) - o->readpos);
  952. if (res < 0) /* audio data not ready, return a NULL frame */
  953. return f;
  954. o->readpos += res;
  955. if (o->readpos < sizeof(o->usbradio_read_buf)) /* not enough samples */
  956. return f;
  957. if (o->mute)
  958. return f;
  959. #if DEBUG_CAPTURES == 1
  960. if ((o->b.rxcapraw && frxcapraw) && (fwrite((o->usbradio_read_buf + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2 * 2 * 6, frxcapraw) != FRAME_SIZE * 2 * 2 * 6)) {
  961. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  962. }
  963. #endif
  964. #if 1
  965. PmrRx( o->pmrChan,
  966. (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
  967. (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
  968. #else
  969. static FILE *hInput;
  970. i16 iBuff[FRAME_SIZE * 2 * 6];
  971. o->pmrChan->b.rxCapture = 1;
  972. if(!hInput) {
  973. hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
  974. if(!hInput) {
  975. ast_log(LOG_ERROR, " Input Data File Not Found.\n");
  976. return 0;
  977. }
  978. }
  979. if (0 == fread((void *)iBuff, 2, FRAME_SIZE * 2 * 6, hInput))
  980. exit;
  981. PmrRx( o->pmrChan,
  982. (i16 *)iBuff,
  983. (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
  984. #endif
  985. #if 0
  986. if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE, "w");
  987. if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2, frxoutraw);
  988. #endif
  989. #if DEBUG_CAPTURES == 1
  990. if ((frxcaptrace && o->b.rxcap2) && (fwrite((o->pmrChan->prxDebug), 1, FRAME_SIZE * 2 * 16, frxcaptrace) != FRAME_SIZE * 2 * 16)) {
  991. ast_log(LOG_ERROR, "fwrite() error: %s\n", strerror(errno));
  992. }
  993. #endif
  994. if (o->rxcdtype == CD_HID && (o->pmrChan->rxExtCarrierDetect != o->rxhidsq))
  995. o->pmrChan->rxExtCarrierDetect = o->rxhidsq;
  996. if (o->rxcdtype == CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect == o->rxhidsq))
  997. o->pmrChan->rxExtCarrierDetect = !o->rxhidsq;
  998. if ( (o->rxcdtype == CD_HID && o->rxhidsq) ||
  999. (o->rxcdtype == CD_HID_INVERT && !o->rxhidsq) ||
  1000. (o->rxcdtype == CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
  1001. (o->rxcdtype == CD_XPMR_VOX && o->pmrChan->rxCarrierDetect) )
  1002. res = 1;
  1003. else
  1004. res = 0;
  1005. if (res != o->rxcarrierdetect) {
  1006. o->rxcarrierdetect = res;
  1007. if (o->debuglevel)
  1008. ast_debug(4, "rxcarrierdetect = %d\n", res);
  1009. }
  1010. if (o->pmrChan->rxCtcss->decode != o->rxctcssdecode) {
  1011. if (o->debuglevel)
  1012. ast_debug(4, "rxctcssdecode = %d\n", o->pmrChan->rxCtcss->decode);
  1013. o->rxctcssdecode = o->pmrChan->rxCtcss->decode;
  1014. }
  1015. if ( ( o->rxctcssfreq && (o->rxctcssdecode == o->pmrChan->rxCtcssIndex)) ||
  1016. ( !o->rxctcssfreq && o->rxcarrierdetect) )
  1017. o->rxkeyed = 1;
  1018. else
  1019. o->rxkeyed = 0;
  1020. o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */
  1021. if (c->_state != AST_STATE_UP) /* drop data if frame is not up */
  1022. return f;
  1023. /* ok we can build and deliver the frame to the caller */
  1024. f->frametype = AST_FRAME_VOICE;
  1025. f->subclass = AST_FORMAT_SLINEAR;
  1026. f->samples = FRAME_SIZE;
  1027. f->datalen = FRAME_SIZE * 2;
  1028. f->data = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
  1029. if (o->boost != BOOST_SCALE) { /* scale and clip values */
  1030. int i, x;
  1031. int16_t *p = (int16_t *) f->data;
  1032. for (i = 0; i < f->samples; i++) {
  1033. x = (p[i] * o->boost) / BOOST_SCALE;
  1034. if (x > 32767)
  1035. x = 32767;
  1036. else if (x < -32768)
  1037. x = -32768;
  1038. p[i] = x;
  1039. }
  1040. }
  1041. f->offset = AST_FRIENDLY_OFFSET;
  1042. if (o->dsp) {
  1043. f1 = ast_dsp_process(c, o->dsp, f);
  1044. if ((f1->frametype == AST_FRAME_DTMF_END) || (f1->frametype == AST_FRAME_DTMF_BEGIN)) {
  1045. if ((f1->subclass == 'm') || (f1->subclass == 'u'))
  1046. f1->frametype = AST_FRAME_DTMF_BEGIN;
  1047. if (f1->frametype == AST_FRAME_DTMF_END)
  1048. ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
  1049. return f1;
  1050. }
  1051. }
  1052. return f;
  1053. }
  1054. static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  1055. {
  1056. struct chan_usbradio_pvt *o = newchan->tech_pvt;
  1057. ast_log(LOG_WARNING,"usbradio_fixup()\n");
  1058. o->owner = newchan;
  1059. return 0;
  1060. }
  1061. static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
  1062. {
  1063. struct chan_usbradio_pvt *o = c->tech_pvt;
  1064. int res = 0;
  1065. switch (cond) {
  1066. case AST_CONTROL_BUSY:
  1067. case AST_CONTROL_CONGESTION:
  1068. case AST_CONTROL_RINGING:
  1069. case -1:
  1070. res = -1;
  1071. break;
  1072. case AST_CONTROL_PROGRESS:
  1073. case AST_CONTROL_PROCEEDING:
  1074. case AST_CONTROL_VIDUPDATE:
  1075. break;
  1076. case AST_CONTROL_HOLD:
  1077. ast_verb(0, " << Console Has Been Placed on Hold >> \n");
  1078. ast_moh_start(c, data, o->mohinterpret);
  1079. break;
  1080. case AST_CONTROL_UNHOLD:
  1081. ast_verb(0, " << Console Has Been Retrieved from Hold >> \n");
  1082. ast_moh_stop(c);
  1083. break;
  1084. case AST_CONTROL_RADIO_KEY:
  1085. o->txkeyed = 1;
  1086. if (o->debuglevel)
  1087. ast_verb(0, " << Radio Transmit On. >> \n");
  1088. break;
  1089. case AST_CONTROL_RADIO_UNKEY:
  1090. o->txkeyed = 0;
  1091. if (o->debuglevel)
  1092. ast_verb(0, " << Radio Transmit Off. >> \n");
  1093. break;
  1094. default:
  1095. ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
  1096. return -1;
  1097. }
  1098. return res;
  1099. }
  1100. /*
  1101. * allocate a new channel.
  1102. */
  1103. static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
  1104. {
  1105. struct ast_channel *c;
  1106. char device[15] = "dsp";
  1107. if (o->devicenum)
  1108. snprintf(device + 3, sizeof(device) - 3, "%d", o->devicenum);
  1109. c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "usbRadio/%s", device);
  1110. if (c == NULL)
  1111. return NULL;
  1112. c->tech = &usbradio_tech;
  1113. if (o->sounddev < 0)
  1114. setformat(o, O_RDWR);
  1115. c->fds[0] = o->sounddev; /* -1 if device closed, override later */
  1116. c->nativeformats = AST_FORMAT_SLINEAR;
  1117. c->readformat = AST_FORMAT_SLINEAR;
  1118. c->writeformat = AST_FORMAT_SLINEAR;
  1119. c->tech_pvt = o;
  1120. if (!ast_strlen_zero(o->language))
  1121. ast_string_field_set(c, language, o->language);
  1122. /* Don't use ast_set_callerid() here because it will
  1123. * generate a needless NewCallerID event */
  1124. c->cid.cid_num = ast_strdup(o->cid_num);
  1125. c->cid.cid_ani = ast_strdup(o->cid_num);
  1126. c->cid.cid_name = ast_strdup(o->cid_name);
  1127. if (!ast_strlen_zero(ext))
  1128. c->cid.cid_dnid = ast_strdup(ext);
  1129. o->owner = c;
  1130. ast_module_ref(ast_module_info->self);
  1131. ast_jb_configure(c, &global_jbconf);
  1132. if (state != AST_STATE_DOWN) {
  1133. if (ast_pbx_start(c)) {
  1134. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
  1135. ast_hangup(c);
  1136. o->owner = c = NULL;
  1137. /* XXX what about the channel itself ? */
  1138. /* XXX what about usecnt ? */
  1139. }
  1140. }
  1141. return c;
  1142. }
  1143. static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
  1144. {
  1145. struct ast_channel *c;
  1146. struct chan_usbradio_pvt *o = find_desc(data);
  1147. ast_debug(4, "usbradio_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
  1148. if (o == NULL) {
  1149. ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
  1150. /* XXX we could default to 'dsp' perhaps ? */
  1151. return NULL;
  1152. }
  1153. if ((format & AST_FORMAT_SLINEAR) == 0) {
  1154. ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
  1155. return NULL;
  1156. }
  1157. if (o->owner) {
  1158. ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
  1159. *cause = AST_CAUSE_BUSY;
  1160. return NULL;
  1161. }
  1162. c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
  1163. if (c == NULL) {
  1164. ast_log(LOG_WARNING, "Unable to create new usb channel\n");
  1165. return NULL;
  1166. }
  1167. return c;
  1168. }
  1169. static char *handle_cli_radio_key(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1170. {
  1171. struct chan_usbradio_pvt *o = NULL;
  1172. switch (cmd) {
  1173. case CLI_INIT:
  1174. e->command = "radio key";
  1175. e->usage =
  1176. "Usage: radio key\n"
  1177. " Simulates COR active.\n";
  1178. return NULL;
  1179. case CLI_GENERATE:
  1180. return NULL;
  1181. }
  1182. if (a->argc != 2)
  1183. return CLI_SHOWUSAGE;
  1184. o = find_desc(usbradio_active);
  1185. o->txtestkey = 1;
  1186. return CLI_SUCCESS;
  1187. }
  1188. static char *handle_cli_radio_unkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1189. {
  1190. struct chan_usbradio_pvt *o = NULL;
  1191. switch (cmd) {
  1192. case CLI_INIT:
  1193. e->command = "radio unkey";
  1194. e->usage =
  1195. "Usage: radio unkey\n"
  1196. " Simulates COR un-active.\n";
  1197. return NULL;
  1198. case CLI_GENERATE:
  1199. return NULL;
  1200. }
  1201. if (a->argc != 2)
  1202. return CLI_SHOWUSAGE;
  1203. o = find_desc(usbradio_active);
  1204. o->txtestkey = 0;
  1205. return CLI_SUCCESS;
  1206. }
  1207. static char *handle_cli_radio_tune(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1208. {
  1209. struct chan_usbradio_pvt *o = NULL;
  1210. int i = 0;
  1211. switch (cmd) {
  1212. case CLI_INIT:
  1213. e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
  1214. "txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
  1215. /* radio tune 6 3000 measured tx value */
  1216. e->usage =
  1217. "Usage: radio tune <function>\n"
  1218. " rxnoise\n"
  1219. " rxvoice\n"
  1220. " rxtone\n"
  1221. " rxsquelch [newsetting]\n"
  1222. " rxcap\n"
  1223. " rxtracecap\n"
  1224. " txvoice [newsetting]\n"
  1225. " txtone [newsetting]\n"
  1226. " txcap\n"
  1227. " txtracecap\n"
  1228. " auxvoice [newsetting]\n"
  1229. " nocap\n"
  1230. " dump\n"
  1231. " save (settings to tuning file)\n"
  1232. "\n"
  1233. " All [newsetting]s are values 0-999\n";
  1234. return NULL;
  1235. case CLI_GENERATE:
  1236. return NULL;
  1237. }
  1238. if ((a->argc < 2) || (a->argc > 4))
  1239. return CLI_SHOWUSAGE;
  1240. if (a->argc == 2) { /* just show stuff */
  1241. ast_cli(a->fd, "Output A is currently set to %s.\n",
  1242. o->txmixa == TX_OUT_COMPOSITE ? "composite" :
  1243. o->txmixa == TX_OUT_VOICE ? "voice" :
  1244. o->txmixa == TX_OUT_LSD ? "tone" :
  1245. o->txmixa == TX_OUT_AUX ? "auxvoice" :
  1246. "off");
  1247. ast_cli(a->fd, "Output B is currently set to %s.\n",
  1248. o->txmixb == TX_OUT_COMPOSITE ? "composite" :
  1249. o->txmixb == TX_OUT_VOICE ? "voice" :
  1250. o->txmixb == TX_OUT_LSD ? "tone" :
  1251. o->txmixb == TX_OUT_AUX ? "auxvoice" :
  1252. "off");
  1253. ast_cli(a->fd, "Tx Voice Level currently set to %d\n", o->txmixaset);
  1254. ast_cli(a->fd, "Tx Tone Level currently set to %d\n", o->txctcssadj);
  1255. ast_cli(a->fd, "Rx Squelch currently set to %d\n", o->rxsquelchadj);
  1256. return CLI_SHOWUSAGE;
  1257. }
  1258. o = find_desc(usbradio_active);
  1259. if (!strcasecmp(a->argv[2], "rxnoise"))
  1260. tune_rxinput(o);
  1261. else if (!strcasecmp(a->argv[2], "rxvoice"))
  1262. tune_rxvoice(o);
  1263. else if (!strcasecmp(a->argv[2], "rxtone"))
  1264. tune_rxctcss(o);
  1265. else if (!strcasecmp(a->argv[2], "rxsquelch")) {
  1266. if (a->argc == 3) {
  1267. ast_cli(a->fd, "Current Signal Strength is %d\n", ((32767 - o->pmrChan->rxRssi) * 1000 / 32767));
  1268. ast_cli(a->fd, "Current Squelch setting is %d\n", o->rxsquelchadj);
  1269. #if 0
  1270. ast_cli(a->fd,"Current Raw RSSI is %d\n",o->pmrChan->rxRssi);
  1271. ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
  1272. #endif
  1273. } else {
  1274. i = atoi(a->argv[3]);
  1275. if ((i < 0) || (i > 999))
  1276. return CLI_SHOWUSAGE;
  1277. ast_cli(a->fd, "Changed Squelch setting to %d\n", i);
  1278. o->rxsquelchadj = i;
  1279. *(o->pmrChan->prxSquelchAdjust) = ((999 - i) * 32767) / 1000;
  1280. }
  1281. } else if (!strcasecmp(a->argv[2], "txvoice")) {
  1282. i = 0;
  1283. if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
  1284. (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE)) {
  1285. ast_log(LOG_ERROR, "No txvoice output configured.\n");
  1286. } else if (a->argc == 3) {
  1287. if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE))
  1288. ast_cli(a->fd, "Current txvoice setting on Channel A is %d\n", o->txmixaset);
  1289. else
  1290. ast_cli(a->fd, "Current txvoice setting on Channel B is %d\n", o->txmixbset);
  1291. } else {
  1292. i = atoi(a->argv[3]);
  1293. if ((i < 0) || (i > 999))
  1294. return CLI_SHOWUSAGE;
  1295. if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE)) {
  1296. o->txmixaset = i;
  1297. ast_cli(a->fd, "Changed txvoice setting on Channel A to %d\n", o->txmixaset);
  1298. } else {
  1299. o->txmixbset = i;
  1300. ast_cli(a->fd, "Changed txvoice setting on Channel B to %d\n", o->txmixbset);
  1301. }
  1302. mixer_write(o);
  1303. mult_set(o);
  1304. ast_cli(a->fd, "Changed Tx Voice Output setting to %d\n", i);
  1305. }
  1306. tune_txoutput(o,i);
  1307. } else if (!strcasecmp(a->argv[2], "auxvoice")) {
  1308. i = 0;
  1309. if ( (o->txmixa != TX_OUT_AUX) && (o->txmixb != TX_OUT_AUX))
  1310. ast_log(LOG_WARNING, "No auxvoice output configured.\n");
  1311. else if (a->argc == 3) {
  1312. if (o->txmixa == TX_OUT_AUX)
  1313. ast_cli(a->fd, "Current auxvoice setting on Channel A is %d\n", o->txmixaset);
  1314. else
  1315. ast_cli(a->fd, "Current auxvoice setting on Channel B is %d\n", o->txmixbset);
  1316. } else {
  1317. i = atoi(a->argv[3]);
  1318. if ((i < 0) || (i > 999))
  1319. return CLI_SHOWUSAGE;
  1320. if (o->txmixa == TX_OUT_AUX) {
  1321. o->txmixbset = i;
  1322. ast_cli(a->fd, "Changed auxvoice setting on Channel A to %d\n", o->txmixaset);
  1323. } else {
  1324. o->txmixbset = i;
  1325. ast_cli(a->fd, "Changed auxvoice setting on Channel B to %d\n", o->txmixbset);
  1326. }
  1327. mixer_write(o);
  1328. mult_set(o);
  1329. }
  1330. /* tune_auxoutput(o,i); */
  1331. } else if (!strcasecmp(a->argv[2], "txtone")) {
  1332. if (a->argc == 3)
  1333. ast_cli(a->fd, "Current Tx CTCSS modulation setting = %d\n", o->txctcssadj);
  1334. else {
  1335. i = atoi(a->argv[3]);
  1336. if ((i < 0) || (i > 999))
  1337. return CLI_SHOWUSAGE;
  1338. o->txctcssadj = i;
  1339. set_txctcss_level(o);
  1340. ast_cli(a->fd, "Changed Tx CTCSS modulation setting to %i\n", i);
  1341. }
  1342. o->txtestkey = 1;
  1343. usleep(5000000);
  1344. o->txtestkey = 0;
  1345. } else if (!strcasecmp(a->argv[2],"dump"))
  1346. pmrdump(o);
  1347. else if (!strcasecmp(a->argv[2],"nocap")) {
  1348. ast_cli(a->fd, "File capture (trace) was rx=%d tx=%d and now off.\n", o->b.rxcap2, o->b.txcap2);
  1349. ast_cli(a->fd, "File capture (raw) was rx=%d tx=%d and now off.\n", o->b.rxcapraw, o->b.txcapraw);
  1350. o->b.rxcapraw = o->b.txcapraw = o->b.rxcap2 = o->b.txcap2 = o->pmrChan->b.rxCapture = o->pmrChan->b.txCapture = 0;
  1351. if (frxcapraw) {
  1352. fclose(frxcapraw);
  1353. frxcapraw = NULL;
  1354. }
  1355. if (frxcaptrace) {
  1356. fclose(frxcaptrace);
  1357. frxcaptrace = NULL;
  1358. }
  1359. if (frxoutraw) {
  1360. fclose(frxoutraw);
  1361. frxoutraw = NULL;
  1362. }
  1363. if (ftxcapraw) {
  1364. fclose(ftxcapraw);
  1365. ftxcapraw = NULL;
  1366. }
  1367. if (ftxcaptrace) {
  1368. fclose(ftxcaptrace);
  1369. ftxcaptrace = NULL;
  1370. }
  1371. if (ftxoutraw) {
  1372. fclose(ftxoutraw);
  1373. ftxoutraw = NULL;
  1374. }
  1375. } else if (!strcasecmp(a->argv[2], "rxtracecap")) {
  1376. if (!frxcaptrace)
  1377. frxcaptrace = fopen(RX_CAP_TRACE_FILE, "w");
  1378. ast_cli(a->fd, "Trace rx on.\n");
  1379. o->b.rxcap2 = o->pmrChan->b.rxCapture = 1;
  1380. } else if (!strcasecmp(a->argv[2], "txtracecap")) {
  1381. if (!ftxcaptrace)
  1382. ftxcaptrace = fopen(TX_CAP_TRACE_FILE, "w");
  1383. ast_cli(a->fd, "Trace tx on.\n");
  1384. o->b.txcap2 = o->pmrChan->b.txCapture = 1;
  1385. } else if (!strcasecmp(a->argv[2], "rxcap")) {
  1386. if (!frxcapraw)
  1387. frxcapraw = fopen(RX_CAP_RAW_FILE, "w");
  1388. ast_cli(a->fd, "cap rx raw on.\n");
  1389. o->b.rxcapraw = 1;
  1390. } else if (!strcasecmp(a->argv[2], "txcap")) {
  1391. if (!ftxcapraw)
  1392. ftxcapraw = fopen(TX_CAP_RAW_FILE, "w");
  1393. ast_cli(a->fd, "cap tx raw on.\n");
  1394. o->b.txcapraw = 1;
  1395. } else if (!strcasecmp(a->argv[2], "save")) {
  1396. tune_write(o);
  1397. ast_cli(a->fd, "Saved radio tuning settings to usbradio_tune.conf\n");
  1398. } else
  1399. return CLI_SHOWUSAGE;
  1400. return CLI_SUCCESS;
  1401. }
  1402. /*
  1403. set transmit ctcss modulation level
  1404. adjust mixer output or internal gain depending on output type
  1405. setting range is 0.0 to 0.9
  1406. */
  1407. static int set_txctcss_level(struct chan_usbradio_pvt *o)
  1408. {
  1409. if (o->txmixa == TX_OUT_LSD) {
  1410. o->txmixaset = (151 * o->txctcssadj) / 1000;
  1411. mixer_write(o);
  1412. mult_set(o);
  1413. } else if (o->txmixb == TX_OUT_LSD) {
  1414. o->txmixbset = (151 * o->txctcssadj) / 1000;
  1415. mixer_write(o);
  1416. mult_set(o);
  1417. } else {
  1418. *o->pmrChan->ptxCtcssAdjust = (o->txctcssadj * M_Q8) / 1000;
  1419. }
  1420. return 0;
  1421. }
  1422. /*
  1423. CLI debugging on and off
  1424. */
  1425. static char *handle_cli_radio_set_debug_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1426. {
  1427. struct chan_usbradio_pvt *o = NULL;
  1428. switch (cmd) {
  1429. case CLI_INIT:
  1430. e->command = "radio set debug [off]";
  1431. e->usage =
  1432. "Usage: radio set debug [off]\n"
  1433. " Enable/Disable radio debugging.\n";
  1434. case CLI_GENERATE:
  1435. return NULL;
  1436. }
  1437. if (a->argc < 3 || a->argc > 4)
  1438. return CLI_SHOWUSAGE;
  1439. if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
  1440. return CLI_SHOWUSAGE;
  1441. o = find_desc(usbradio_active);
  1442. if (a->argc == 3)
  1443. o->debuglevel = 1;
  1444. else
  1445. o->debuglevel = 0;
  1446. ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
  1447. return CLI_SUCCESS;
  1448. }
  1449. static char *handle_cli_radio_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1450. {
  1451. struct chan_usbradio_pvt *o = NULL;
  1452. switch (cmd) {
  1453. case CLI_INIT:
  1454. e->command = "radio set debug {on|off}";
  1455. e->usage =
  1456. "Usage: radio set debug {on|off}\n"
  1457. " Enable/Disable radio debugging.\n";
  1458. case CLI_GENERATE:
  1459. return NULL;
  1460. }
  1461. if (a->argc != e->args)
  1462. return CLI_SHOWUSAGE;
  1463. o = find_desc(usbradio_active);
  1464. if (!strncasecmp(a->argv[e->args - 1], "on", 2))
  1465. o->debuglevel = 1;
  1466. else if (!strncasecmp(a->argv[e->args - 1], "off", 3))
  1467. o->debuglevel = 0;
  1468. else
  1469. return CLI_SHOWUSAGE;
  1470. ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
  1471. return CLI_SUCCESS;
  1472. }
  1473. static struct ast_cli_entry cli_radio_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_radio_set_debug_deprecated, "Enable/Disable Radio Debugging");
  1474. static struct ast_cli_entry cli_usbradio[] = {
  1475. AST_CLI_DEFINE(handle_cli_radio_key, "Simulate Rx Signal Present"),
  1476. AST_CLI_DEFINE(handle_cli_radio_unkey, "Simulate Rx Signal Lusb"),
  1477. AST_CLI_DEFINE(handle_cli_radio_tune, "Radio Tune"),
  1478. AST_CLI_DEFINE(handle_cli_radio_set_debug, "Enable/Disable Radio Debugging", .deprecate_cmd = &cli_radio_set_debug_deprecated),
  1479. };
  1480. /*
  1481. * store the callerid components
  1482. */
  1483. #if 0
  1484. static void store_callerid(struct chan_usbradio_pvt *o, const char *s)
  1485. {
  1486. ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
  1487. }
  1488. #endif
  1489. static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
  1490. {
  1491. if (!strcasecmp(s, "no")) {
  1492. o->rxdemod = RX_AUDIO_NONE;
  1493. } else if (!strcasecmp(s, "speaker")) {
  1494. o->rxdemod = RX_AUDIO_SPEAKER;
  1495. } else if (!strcasecmp(s, "flat")) {
  1496. o->rxdemod = RX_AUDIO_FLAT;
  1497. } else {
  1498. ast_log(LOG_WARNING, "Unrecognized rxdemod parameter: %s\n", s);
  1499. }
  1500. ast_debug(4, "set rxdemod = %s\n", s);
  1501. }
  1502. static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
  1503. {
  1504. if (!strcasecmp(s, "no"))
  1505. o->txmixa = TX_OUT_OFF;
  1506. else if (!strcasecmp(s, "voice"))
  1507. o->txmixa = TX_OUT_VOICE;
  1508. else if (!strcasecmp(s, "tone"))
  1509. o->txmixa = TX_OUT_LSD;
  1510. else if (!strcasecmp(s, "composite"))
  1511. o->txmixa = TX_OUT_COMPOSITE;
  1512. else if (!strcasecmp(s, "auxvoice"))
  1513. o->txmixb = TX_OUT_AUX;
  1514. else
  1515. ast_log(LOG_WARNING, "Unrecognized txmixa parameter: %s\n", s);
  1516. ast_debug(4, "set txmixa = %s\n", s);
  1517. }
  1518. static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
  1519. {
  1520. if (!strcasecmp(s, "no"))
  1521. o->txmixb = TX_OUT_OFF;
  1522. else if (!strcasecmp(s, "voice"))
  1523. o->txmixb = TX_OUT_VOICE;
  1524. else if (!strcasecmp(s, "tone"))
  1525. o->txmixb = TX_OUT_LSD;
  1526. else if (!strcasecmp(s, "composite"))
  1527. o->txmixb = TX_OUT_COMPOSITE;
  1528. else if (!strcasecmp(s, "auxvoice"))
  1529. o->txmixb = TX_OUT_AUX;
  1530. else
  1531. ast_log(LOG_WARNING, "Unrecognized txmixb parameter: %s\n", s);
  1532. ast_debug(4, "set txmixb = %s\n", s);
  1533. }
  1534. static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
  1535. {
  1536. if (!strcasecmp(s, "no"))
  1537. o->rxcdtype = CD_IGNORE;
  1538. else if (!strcasecmp(s, "usb"))
  1539. o->rxcdtype = CD_HID;
  1540. else if (!strcasecmp(s, "dsp"))
  1541. o->rxcdtype = CD_XPMR_NOISE;
  1542. else if (!strcasecmp(s, "vox"))
  1543. o->rxcdtype = CD_XPMR_VOX;
  1544. else if (!strcasecmp(s, "usbinvert"))
  1545. o->rxcdtype = CD_HID_INVERT;
  1546. else
  1547. ast_log(LOG_WARNING, "Unrecognized rxcdtype parameter: %s\n", s);
  1548. ast_debug(4, "set rxcdtype = %s\n", s);
  1549. }
  1550. static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
  1551. {
  1552. if (!strcasecmp(s, "no") || !strcasecmp(s, "SD_IGNORE"))
  1553. o->rxsdtype = SD_IGNORE;
  1554. else if (!strcasecmp(s, "usb") || !strcasecmp(s, "SD_HID"))
  1555. o->rxsdtype = SD_HID;
  1556. else if (!strcasecmp(s, "usbinvert") || !strcasecmp(s, "SD_HID_INVERT"))
  1557. o->rxsdtype = SD_HID_INVERT;
  1558. else if (!strcasecmp(s, "software") || !strcasecmp(s, "SD_XPMR"))
  1559. o->rxsdtype = SD_XPMR;
  1560. else
  1561. ast_log(LOG_WARNING, "Unrecognized rxsdtype parameter: %s\n", s);
  1562. ast_debug(4, "set rxsdtype = %s\n", s);
  1563. }
  1564. static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
  1565. {
  1566. float f;
  1567. if (sscanf(s, "%30f", &f) == 1)
  1568. o->rxgain = f;
  1569. ast_debug(4, "set rxgain = %f\n", f);
  1570. }
  1571. static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
  1572. {
  1573. float f;
  1574. if (sscanf(s, "%30f", &f) == 1)
  1575. o->rxvoiceadj = f;
  1576. ast_debug(4, "set rxvoiceadj = %f\n", f);
  1577. }
  1578. static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
  1579. {
  1580. float f;
  1581. if (sscanf(s, "%30f", &f) == 1)
  1582. o->rxctcssadj = f;
  1583. ast_debug(4, "set rxctcssadj = %f\n", f);
  1584. }
  1585. static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
  1586. {
  1587. if (!strcasecmp(s, "no") || !strcasecmp(s, "TOC_NONE"))
  1588. o->txtoctype = TOC_NONE;
  1589. else if (!strcasecmp(s, "phase") || !strcasecmp(s, "TOC_PHASE"))
  1590. o->txtoctype = TOC_PHASE;
  1591. else if (!strcasecmp(s, "notone") || !strcasecmp(s, "TOC_NOTONE"))
  1592. o->txtoctype = TOC_NOTONE;
  1593. else
  1594. ast_log(LOG_WARNING, "Unrecognized txtoctype parameter: %s\n", s);
  1595. ast_debug(4, "set txtoctype = %s\n", s);
  1596. }
  1597. static void store_rxctcssfreq(struct chan_usbradio_pvt *o, const char *s)
  1598. {
  1599. float f;
  1600. if (sscanf(s, "%f", &f) == 1)
  1601. o->rxctcssfreq = f;
  1602. ast_debug(4, "set rxctcss = %f\n", f);
  1603. }
  1604. static void store_txctcssfreq(struct chan_usbradio_pvt *o, const char *s)
  1605. {
  1606. float f;
  1607. if (sscanf(s, "%f", &f) == 1)
  1608. o->txctcssfreq = f;
  1609. ast_debug(4, "set txctcss = %f\n", f);
  1610. }
  1611. static void tune_txoutput(struct chan_usbradio_pvt *o, int value)
  1612. {
  1613. o->txtestkey = 1;
  1614. o->pmrChan->txPttIn = 1;
  1615. #if 0
  1616. /* generate 1KHz tone at 7200 peak */
  1617. o->pmrChan->spsSigGen1->freq = 10000;
  1618. o->pmrChan->spsSigGen1->outputGain = (float)(0.22 * M_Q8);
  1619. o->pmrChan->b.startSpecialTone = 1;
  1620. #endif
  1621. TxTestTone(o->pmrChan, 1);
  1622. usleep(5000000);
  1623. /* o->pmrChan->b.stopSpecialTone = 1; */
  1624. usleep(100000);
  1625. TxTestTone(o->pmrChan, 0);
  1626. o->pmrChan->txPttIn = 0;
  1627. o->txtestkey = 0;
  1628. }
  1629. static void tune_rxinput(struct chan_usbradio_pvt *o)
  1630. {
  1631. const int target = 23000;
  1632. const int tolerance = 2000;
  1633. const int settingmin = 1;
  1634. const int settingstart = 2;
  1635. const int maxtries = 12;
  1636. float settingmax;
  1637. int setting = 0, tries = 0, tmpdiscfactor, meas;
  1638. int tunetype = 0;
  1639. settingmax = o->micmax;
  1640. if (o->pmrChan->rxDemod)
  1641. tunetype = 1;
  1642. setting = settingstart;
  1643. while (tries < maxtries) {
  1644. setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0);
  1645. setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
  1646. usleep(100000);
  1647. if (o->rxcdtype == CD_XPMR_VOX || o->rxdemod == RX_AUDIO_SPEAKER) {
  1648. ast_debug(4, "Measure Direct Input\n");
  1649. o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
  1650. o->pmrChan->spsMeasure->discfactor = 1000;
  1651. o->pmrChan->spsMeasure->enabled = 1;
  1652. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  1653. usleep(400000);
  1654. meas = o->pmrChan->spsMeasure->apeak;
  1655. o->pmrChan->spsMeasure->enabled = 0;
  1656. } else {
  1657. ast_debug(4, "Measure HF Noise\n");
  1658. tmpdiscfactor = o->pmrChan->spsRx->discfactor;
  1659. o->pmrChan->spsRx->discfactor = (i16)1000;
  1660. o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
  1661. o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
  1662. usleep(200000);
  1663. meas = o->pmrChan->rxRssi;
  1664. o->pmrChan->spsRx->discfactor = tmpdiscfactor;
  1665. o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
  1666. o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
  1667. }
  1668. if (!meas)
  1669. meas++;
  1670. ast_log(LOG_NOTICE, "tries=%d, setting=%d, meas=%i\n", tries, setting, meas);
  1671. if ( meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
  1672. setting = setting * target / meas;
  1673. else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance) )
  1674. break;
  1675. if (setting < settingmin)
  1676. setting = settingmin;
  1677. else if (setting > settingmax)
  1678. setting = settingmax;
  1679. tries++;
  1680. }
  1681. ast_log(LOG_NOTICE, "DONE tries=%d, setting=%d, meas=%i\n", tries,
  1682. (setting * 1000) / o->micmax, meas);
  1683. if (meas < (target - tolerance) || meas > (target + tolerance))
  1684. ast_log(LOG_NOTICE, "ERROR: RX INPUT ADJUST FAILED.\n");
  1685. else {
  1686. ast_log(LOG_NOTICE, "INFO: RX INPUT ADJUST SUCCESS.\n");
  1687. o->rxmixerset = (setting * 1000) / o->micmax;
  1688. }
  1689. }
  1690. /*
  1691. */
  1692. static void tune_rxvoice(struct chan_usbradio_pvt *o)
  1693. {
  1694. const int target = 7200; /* peak */
  1695. const int tolerance = 360; /* peak to peak */
  1696. const float settingmin = 0.1;
  1697. const float settingmax = 4;
  1698. const float settingstart = 1;
  1699. const int maxtries = 12;
  1700. float setting;
  1701. int tries = 0, meas;
  1702. ast_log(LOG_NOTICE, "INFO: RX VOICE ADJUST START.\n");
  1703. ast_log(LOG_NOTICE, "target=%d tolerance=%d\n", target, tolerance);
  1704. if (!o->pmrChan->spsMeasure)
  1705. ast_log(LOG_ERROR, "NO MEASURE BLOCK.\n");
  1706. if (!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
  1707. ast_log(LOG_ERROR, "NO SOURCE OR MEASURE SETTING.\n");
  1708. o->pmrChan->spsMeasure->source = o->pmrChan->spsRxOut->sink;
  1709. o->pmrChan->spsMeasure->enabled = 1;
  1710. o->pmrChan->spsMeasure->discfactor = 1000;
  1711. setting=settingstart;
  1712. ast_debug(4, "ERROR: NO MEASURE BLOCK.\n");
  1713. while (tries < maxtries) {
  1714. *(o->pmrChan->prxVoiceAdjust) = setting * M_Q8;
  1715. usleep(10000);
  1716. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  1717. usleep(1000000);
  1718. meas = o->pmrChan->spsMeasure->apeak;
  1719. ast_log(LOG_NOTICE, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
  1720. if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
  1721. setting = setting * target / meas;
  1722. else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
  1723. break;
  1724. if (setting < settingmin)
  1725. setting = settingmin;
  1726. else if (setting > settingmax)
  1727. setting = settingmax;
  1728. tries++;
  1729. }
  1730. o->pmrChan->spsMeasure->enabled = 0;
  1731. ast_log(LOG_NOTICE, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
  1732. if (meas < (target - tolerance) || meas > (target + tolerance))
  1733. ast_log(LOG_ERROR, "RX VOICE GAIN ADJUST FAILED.\n");
  1734. else {
  1735. ast_log(LOG_NOTICE, "RX VOICE GAIN ADJUST SUCCESS.\n");
  1736. o->rxvoiceadj = setting;
  1737. }
  1738. }
  1739. static void tune_rxctcss(struct chan_usbradio_pvt *o)
  1740. {
  1741. const int target = 4096;
  1742. const int tolerance = 100;
  1743. const float settingmin = 0.1;
  1744. const float settingmax = 4;
  1745. const float settingstart = 1;
  1746. const int maxtries = 12;
  1747. float setting;
  1748. int tries = 0, meas;
  1749. ast_log(LOG_NOTICE, "RX CTCSS ADJUST START.\n");
  1750. ast_log(LOG_NOTICE, "target=%d tolerance=%d \n", target, tolerance);
  1751. o->pmrChan->spsMeasure->source = o->pmrChan->prxCtcssMeasure;
  1752. o->pmrChan->spsMeasure->discfactor = 400;
  1753. o->pmrChan->spsMeasure->enabled = 1;
  1754. setting = settingstart;
  1755. while (tries < maxtries) {
  1756. *(o->pmrChan->prxCtcssAdjust) = setting * M_Q8;
  1757. usleep(10000);
  1758. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  1759. usleep(500000);
  1760. meas = o->pmrChan->spsMeasure->apeak;
  1761. ast_debug(4, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
  1762. if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
  1763. setting = setting * target / meas;
  1764. else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
  1765. break;
  1766. if (setting < settingmin)
  1767. setting = settingmin;
  1768. else if (setting > settingmax)
  1769. setting = settingmax;
  1770. tries++;
  1771. }
  1772. o->pmrChan->spsMeasure->enabled = 0;
  1773. ast_debug(4, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
  1774. if (meas < (target - tolerance) || meas > (target + tolerance))
  1775. ast_log(LOG_ERROR, "RX CTCSS GAIN ADJUST FAILED.\n");
  1776. else {
  1777. ast_log(LOG_NOTICE, "RX CTCSS GAIN ADJUST SUCCESS.\n");
  1778. o->rxctcssadj = setting;
  1779. }
  1780. }
  1781. /*
  1782. this file then is included in chan_usbradio.conf
  1783. #include /etc/asterisk/usbradio_tune.conf
  1784. */
  1785. static void tune_write(struct chan_usbradio_pvt *o)
  1786. {
  1787. FILE *fp;
  1788. fp = fopen("/etc/asterisk/usbradio_tune.conf", "w");
  1789. if (!strcmp(o->name, "dsp"))
  1790. fprintf(fp, "[general]\n");
  1791. else
  1792. fprintf(fp, "[%s]\n", o->name);
  1793. fprintf(fp, "; name=%s\n", o->name);
  1794. fprintf(fp, "; devicenum=%d\n", o->devicenum);
  1795. fprintf(fp, "rxmixerset=%d\n", o->rxmixerset);
  1796. fprintf(fp, "rxboostset=%d\n", o->rxboostset);
  1797. fprintf(fp, "txmixaset=%d\n", o->txmixaset);
  1798. fprintf(fp, "txmixbset=%d\n", o->txmixbset);
  1799. fprintf(fp, "rxvoiceadj=%f\n", o->rxvoiceadj);
  1800. fprintf(fp, "rxctcssadj=%f\n", o->rxctcssadj);
  1801. fprintf(fp, "txctcssadj=%d\n", o->txctcssadj);
  1802. fprintf(fp, "rxsquelchadj=%d\n", o->rxsquelchadj);
  1803. fclose(fp);
  1804. }
  1805. static void mixer_write(struct chan_usbradio_pvt *o)
  1806. {
  1807. setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_SW, 0, 0);
  1808. setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_VOL, 0, 0);
  1809. setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_SW, 1, 0);
  1810. setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL,
  1811. o->txmixaset * o->spkrmax / 1000,
  1812. o->txmixbset * o->spkrmax / 1000);
  1813. setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL,
  1814. o->rxmixerset * o->micmax / 1000, 0);
  1815. setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
  1816. setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0);
  1817. }
  1818. /*
  1819. adjust dsp multiplier to add resolution to tx level adjustment
  1820. */
  1821. static void mult_set(struct chan_usbradio_pvt *o)
  1822. {
  1823. if (o->pmrChan->spsTxOutA) {
  1824. o->pmrChan->spsTxOutA->outputGain =
  1825. mult_calc((o->txmixaset * 152) / 1000);
  1826. }
  1827. if (o->pmrChan->spsTxOutB) {
  1828. o->pmrChan->spsTxOutB->outputGain =
  1829. mult_calc((o->txmixbset * 152) / 1000);
  1830. }
  1831. }
  1832. /*
  1833. * input 0 - 151 outputs are pot and multiplier
  1834. */
  1835. static int mult_calc(int value)
  1836. {
  1837. const int multx = M_Q8;
  1838. int pot, mult;
  1839. pot= ((int)(value / 4) * 4) + 2;
  1840. mult = multx - ((multx * (3 - (value % 4))) / (pot + 2));
  1841. return mult;
  1842. }
  1843. #define pd(x) ast_debug(4, #x" = %d\n", x)
  1844. #define pp(x) ast_debug(4, #x" = %p\n", x)
  1845. #define ps(x) ast_debug(4, #x" = %s\n", x)
  1846. #define pf(x) ast_debug(4, #x" = %f\n", x)
  1847. /*
  1848. */
  1849. static void pmrdump(struct chan_usbradio_pvt *o)
  1850. {
  1851. t_pmr_chan *p;
  1852. p = o->pmrChan;
  1853. ast_debug(4, "odump()\n");
  1854. pd(o->devicenum);
  1855. pd(o->rxdemod);
  1856. pd(o->rxcdtype);
  1857. pd(o->rxsdtype);
  1858. pd(o->txtoctype);
  1859. pd(o->rxmixerset);
  1860. pf(o->rxvoiceadj);
  1861. pf(o->rxctcssadj);
  1862. pd(o->rxsquelchadj);
  1863. pd(o->txprelim);
  1864. pd(o->txmixa);
  1865. pd(o->txmixb);
  1866. pd(o->txmixaset);
  1867. pd(o->txmixbset);
  1868. ast_debug(4, "pmrdump()\n");
  1869. ast_debug(4, "prxSquelchAdjust=%d\n", *(o->pmrChan->prxSquelchAdjust));
  1870. pd(p->rxCarrierPoint);
  1871. pd(p->rxCarrierHyst);
  1872. pd(p->rxCtcss->relax);
  1873. pf(p->rxCtcssFreq);
  1874. pd(p->rxCtcssIndex);
  1875. pf(p->txCtcssFreq);
  1876. pd(p->txMixA);
  1877. pd(p->txMixB);
  1878. pd(p->rxDeEmpEnable);
  1879. pd(p->rxCenterSlicerEnable);
  1880. pd(p->rxCtcssDecodeEnable);
  1881. pd(p->rxDcsDecodeEnable);
  1882. pd(p->txHpfEnable);
  1883. pd(p->txLimiterEnable);
  1884. pd(p->txPreEmpEnable);
  1885. pd(p->txLpfEnable);
  1886. if (p->spsTxOutA)
  1887. pd(p->spsTxOutA->outputGain);
  1888. if (p->spsTxOutB)
  1889. pd(p->spsTxOutB->outputGain);
  1890. return;
  1891. }
  1892. /*
  1893. * grab fields from the config file, init the descriptor and open the device.
  1894. */
  1895. static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
  1896. {
  1897. struct ast_variable *v;
  1898. struct chan_usbradio_pvt *o;
  1899. struct ast_config *cfg1;
  1900. struct ast_flags config_flags = { 0 };
  1901. if (ctg == NULL) {
  1902. traceusb1(" store_config() ctg == NULL\n");
  1903. o = &usbradio_default;
  1904. ctg = "general";
  1905. } else {
  1906. if (!(o = ast_calloc(1, sizeof(*o)))){
  1907. return NULL;
  1908. }
  1909. *o = usbradio_default;
  1910. /* "general" is also the default thing */
  1911. if (strcmp(ctg, "general") == 0) {
  1912. o->name = ast_strdup("dsp");
  1913. usbradio_active = o->name;
  1914. } else
  1915. o->name = ast_strdup(ctg);
  1916. }
  1917. strcpy(o->mohinterpret, "default");
  1918. o->micmax = amixer_max(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL);
  1919. o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
  1920. /* fill other fields from configuration */
  1921. for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
  1922. /* handle jb conf */
  1923. if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
  1924. continue;
  1925. CV_START(v->name, v->value);
  1926. CV_UINT("frags", o->frags);
  1927. CV_UINT("queuesize", o->queuesize);
  1928. CV_UINT("devicenum", o->devicenum);
  1929. CV_UINT("debug", usbradio_debug);
  1930. CV_BOOL("rxcpusaver", o->rxcpusaver);
  1931. CV_BOOL("txcpusaver", o->txcpusaver);
  1932. CV_BOOL("invertptt", o->invertptt);
  1933. CV_F("rxdemod", store_rxdemod(o, v->value));
  1934. CV_BOOL("txprelim", o->txprelim);;
  1935. CV_F("txmixa", store_txmixa(o, v->value));
  1936. CV_F("txmixb", store_txmixb(o, v->value));
  1937. CV_F("carrierfrom", store_rxcdtype(o, v->value));
  1938. CV_F("rxsdtype", store_rxsdtype(o, v->value));
  1939. CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
  1940. CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
  1941. CV_F("rxgain", store_rxgain(o, v->value));
  1942. CV_BOOL("rxboostset", o->rxboostset);
  1943. CV_UINT("rxctcssrelax", o->rxctcssrelax);
  1944. CV_F("txtoctype", store_txtoctype(o, v->value));
  1945. CV_UINT("hdwtype", o->hdwtype);
  1946. CV_UINT("duplex", o->radioduplex);
  1947. CV_END;
  1948. }
  1949. cfg1 = ast_config_load(config1, config_flags);
  1950. if (!cfg1) {
  1951. o->rxmixerset = 500;
  1952. o->txmixaset = 500;
  1953. o->txmixbset = 500;
  1954. o->rxvoiceadj = 0.5;
  1955. o->rxctcssadj = 0.5;
  1956. o->txctcssadj = 200;
  1957. o->rxsquelchadj = 500;
  1958. ast_log(LOG_WARNING, "File %s not found, using default parameters.\n", config1);
  1959. } else {
  1960. for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
  1961. CV_START(v->name, v->value);
  1962. CV_UINT("rxmixerset", o->rxmixerset);
  1963. CV_UINT("txmixaset", o->txmixaset);
  1964. CV_UINT("txmixbset", o->txmixbset);
  1965. CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
  1966. CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
  1967. CV_UINT("txctcssadj", o->txctcssadj);
  1968. CV_UINT("rxsquelchadj", o->rxsquelchadj);
  1969. CV_END;
  1970. }
  1971. ast_config_destroy(cfg1);
  1972. }
  1973. o->debuglevel = 0;
  1974. if (o == &usbradio_default) /* we are done with the default */
  1975. return NULL;
  1976. o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
  1977. o->dsp = ast_dsp_new();
  1978. if (o->dsp) {
  1979. ast_dsp_set_features(o->dsp, DSP_FEATURE_DTMF_DETECT);
  1980. ast_dsp_digitmode(o->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
  1981. }
  1982. if (o->rxctcssfreq != 0 && o->rxdemod == RX_AUDIO_SPEAKER)
  1983. ast_log(LOG_ERROR, "Incompatable Options o->rxctcssfreq=%f and o->rxdemod=speaker\n", o->rxctcssfreq);
  1984. if (o->pmrChan == NULL) {
  1985. t_pmr_chan tChan;
  1986. memset(&tChan, 0, sizeof(tChan));
  1987. tChan.rxDemod = o->rxdemod;
  1988. tChan.rxCdType = o->rxcdtype;
  1989. tChan.txMod = o->txprelim;
  1990. tChan.txMixA = o->txmixa;
  1991. tChan.txMixB = o->txmixb;
  1992. tChan.rxCpuSaver = o->rxcpusaver;
  1993. tChan.txCpuSaver = o->txcpusaver;
  1994. tChan.rxCtcssFreq = o->rxctcssfreq;
  1995. tChan.txCtcssFreq = o->txctcssfreq;
  1996. o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE);
  1997. o->pmrChan->radioDuplex = o->radioduplex;
  1998. o->pmrChan->rxCpuSaver = o->rxcpusaver;
  1999. o->pmrChan->txCpuSaver = o->txcpusaver;
  2000. *(o->pmrChan->prxSquelchAdjust) =
  2001. ((999 - o->rxsquelchadj) * 32767) / 1000;
  2002. o->pmrChan->spsRx->outputGain = o->rxvoiceadj*M_Q8;
  2003. o->pmrChan->txTocType = o->txtoctype;
  2004. if ((o->txmixa == TX_OUT_LSD) ||
  2005. (o->txmixa == TX_OUT_COMPOSITE) ||
  2006. (o->txmixb == TX_OUT_LSD) ||
  2007. (o->txmixb == TX_OUT_COMPOSITE)) {
  2008. *(o->pmrChan->prxCtcssAdjust) = o->rxctcssadj * M_Q8;
  2009. set_txctcss_level(o);
  2010. }
  2011. o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
  2012. }
  2013. if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
  2014. (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE))
  2015. ast_log(LOG_ERROR, "No txvoice output configured.\n");
  2016. if (o->txctcssfreq &&
  2017. o->txmixa != TX_OUT_LSD && o->txmixa != TX_OUT_COMPOSITE &&
  2018. o->txmixb != TX_OUT_LSD && o->txmixb != TX_OUT_COMPOSITE)
  2019. ast_log(LOG_ERROR, "No txtone output configured.\n");
  2020. if (o->rxctcssfreq && o->pmrChan->rxCtcssIndex < 0)
  2021. ast_log(LOG_ERROR, "Invalid CTCSS Frequency.\n");
  2022. /* RxTestIt(o); */
  2023. mixer_write(o);
  2024. mult_set(o);
  2025. hidhdwconfig(o);
  2026. /* pmrdump(o); */
  2027. /* link into list of devices */
  2028. if (o != &usbradio_default) {
  2029. o->next = usbradio_default.next;
  2030. usbradio_default.next = o;
  2031. }
  2032. return o;
  2033. }
  2034. #if DEBUG_FILETEST == 1
  2035. /*
  2036. Test It on a File
  2037. */
  2038. int RxTestIt(struct chan_usbradio_pvt *o)
  2039. {
  2040. const int numSamples = SAMPLES_PER_BLOCK;
  2041. const int numChannels = 16;
  2042. i16 sample, i, ii;
  2043. i32 txHangTime;
  2044. i16 txEnable;
  2045. t_pmr_chan tChan;
  2046. t_pmr_chan *pChan;
  2047. FILE *hInput = NULL, *hOutput = NULL, *hOutputTx = NULL;
  2048. i16 iBuff[numSamples * 2 * 6], oBuff[numSamples];
  2049. ast_debug(4, "RxTestIt()\n");
  2050. pChan = o->pmrChan;
  2051. pChan->b.txCapture = 1;
  2052. pChan->b.rxCapture = 1;
  2053. txEnable = 0;
  2054. hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
  2055. if (!hInput){
  2056. ast_debug(4, " RxTestIt() File Not Found.\n");
  2057. return 0;
  2058. }
  2059. hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm", "w");
  2060. ast_debug(4, " RxTestIt() Working...\n");
  2061. while (!feof(hInput)) {
  2062. fread((void *)iBuff, 2, numSamples * 2 * 6, hInput);
  2063. if (txHangTime)
  2064. txHangTime -= numSamples;
  2065. if (txHangTime < 0)
  2066. txHangTime = 0;
  2067. if (pChan->rxCtcss->decode)
  2068. txHangTime = (8000 / 1000 * 2000);
  2069. if (pChan->rxCtcss->decode && !txEnable) {
  2070. txEnable = 1;
  2071. /* pChan->inputBlanking = (8000 / 1000 * 200); */
  2072. } else if (!pChan->rxCtcss->decode && txEnable) {
  2073. txEnable = 0;
  2074. }
  2075. PmrRx(pChan, iBuff, oBuff);
  2076. if (fwrite((void *)pChan->prxDebug, 2, numSamples * numChannels, hOutput) != numSamples * numChannels) {
  2077. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  2078. }
  2079. }
  2080. pChan->b.txCapture = 0;
  2081. pChan->b.rxCapture = 0;
  2082. if (hInput)
  2083. fclose(hInput);
  2084. if (hOutput)
  2085. fclose(hOutput);
  2086. ast_debug(4, " RxTestIt() Complete.\n");
  2087. return 0;
  2088. }
  2089. #endif
  2090. #include "./xpmr/xpmr.c"
  2091. /*
  2092. */
  2093. static int load_module(void)
  2094. {
  2095. struct ast_config *cfg = NULL;
  2096. char *ctg = NULL;
  2097. struct ast_flags config_flags = { 0 };
  2098. /* Copy the default jb config over global_jbconf */
  2099. memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
  2100. /* load config file */
  2101. if (!(cfg = ast_config_load(config, config_flags))) {
  2102. ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
  2103. return AST_MODULE_LOAD_DECLINE;
  2104. }
  2105. do {
  2106. store_config(cfg, ctg);
  2107. } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
  2108. ast_config_destroy(cfg);
  2109. if (find_desc(usbradio_active) == NULL) {
  2110. ast_log(LOG_NOTICE, "Device %s not found\n", usbradio_active);
  2111. /* XXX we could default to 'dsp' perhaps ? */
  2112. /* XXX should cleanup allocated memory etc. */
  2113. return AST_MODULE_LOAD_FAILURE;
  2114. }
  2115. if (ast_channel_register(&usbradio_tech)) {
  2116. ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
  2117. return AST_MODULE_LOAD_FAILURE;
  2118. }
  2119. ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
  2120. return AST_MODULE_LOAD_SUCCESS;
  2121. }
  2122. /*
  2123. */
  2124. static int unload_module(void)
  2125. {
  2126. struct chan_usbradio_pvt *o;
  2127. ast_log(LOG_WARNING, "unload_module() called\n");
  2128. ast_channel_unregister(&usbradio_tech);
  2129. ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
  2130. for (o = usbradio_default.next; o; o = o->next) {
  2131. ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
  2132. if (o->pmrChan)
  2133. destroyPmrChannel(o->pmrChan);
  2134. #if DEBUG_CAPTURES == 1
  2135. if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
  2136. if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
  2137. if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
  2138. if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
  2139. if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
  2140. if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
  2141. #endif
  2142. close(o->sounddev);
  2143. if (o->dsp)
  2144. ast_dsp_free(o->dsp);
  2145. if (o->owner)
  2146. ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
  2147. if (o->owner) /* XXX how ??? */
  2148. return -1;
  2149. /* XXX what about the thread ? */
  2150. /* XXX what about the memory allocated ? */
  2151. }
  2152. return 0;
  2153. }
  2154. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
  2155. /* end of file */