chan_usbradio.c 107 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033
  1. #define NEW_ASTERISK
  2. /*
  3. * Asterisk -- An open source telephony toolkit.
  4. *
  5. * Copyright (C) 1999 - 2005, Digium, Inc.
  6. * Copyright (C) 2007 - 2008, Jim Dixon
  7. *
  8. * Jim Dixon, WB6NIL <jim@lambdatel.com>
  9. * Steve Henke, W9SH <w9sh@arrl.net>
  10. * Based upon work by Mark Spencer <markster@digium.com> and Luigi Rizzo
  11. *
  12. * See http://www.asterisk.org for more information about
  13. * the Asterisk project. Please do not directly contact
  14. * any of the maintainers of this project for assistance;
  15. * the project provides a web site, mailing lists and IRC
  16. * channels for your use.
  17. *
  18. * This program is free software, distributed under the terms of
  19. * the GNU General Public License Version 2. See the LICENSE file
  20. * at the top of the source tree.
  21. */
  22. /*! \file
  23. *
  24. * \brief Channel driver for CM108 USB Cards with Radio Interface
  25. *
  26. * \author Jim Dixon <jim@lambdatel.com>
  27. * \author Steve Henke <w9sh@arrl.net>
  28. *
  29. * \par See also
  30. * \arg \ref Config_usbradio
  31. *
  32. * \ingroup channel_drivers
  33. */
  34. /*** MODULEINFO
  35. <depend>oss</depend>
  36. <depend>alsa</depend>
  37. <depend>usb</depend>
  38. <defaultenabled>no</defaultenabled>
  39. <support_level>extended</support_level>
  40. ***/
  41. /*** MAKEOPTS
  42. <category name="MENUSELECT_CFLAGS" displayname="Compiler Flags" positive_output="yes">
  43. <member name="RADIO_RTX" displayname="Build RTX/DTX Radio Programming" touch_on_change="channels/chan_usbradio.c channels/xpmr/xpmr.h">
  44. <defaultenabled>no</defaultenabled>
  45. <depend>chan_usbradio</depend>
  46. <support_level>extended</support_level>
  47. </member>
  48. <member name="RADIO_XPMRX" displayname="Build Experimental Radio Protocols" touch_on_change="channels/chan_usbradio.c">
  49. <defaultenabled>no</defaultenabled>
  50. <depend>chan_usbradio</depend>
  51. <support_level>extended</support_level>
  52. </member>
  53. </category>
  54. ***/
  55. // 20070918 1600 EDT sph@xelatec.com changing to rx driven streams
  56. #include "asterisk.h"
  57. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  58. #include <stdio.h>
  59. #include <ctype.h>
  60. #include <math.h>
  61. #include <string.h>
  62. #include <unistd.h>
  63. #ifdef HAVE_SYS_IO_H
  64. #include <sys/io.h>
  65. #endif
  66. #include <sys/ioctl.h>
  67. #include <fcntl.h>
  68. #include <sys/time.h>
  69. #include <stdlib.h>
  70. #include <errno.h>
  71. #include <usb.h>
  72. #include <alsa/asoundlib.h>
  73. //#define HAVE_XPMRX 1
  74. #ifdef RADIO_XPMRX
  75. #define HAVE_XPMRX 1
  76. #endif
  77. #define CHAN_USBRADIO 1
  78. #define DEBUG_USBRADIO 0
  79. #define DEBUG_CAPTURES 1
  80. #define DEBUG_CAP_RX_OUT 0
  81. #define DEBUG_CAP_TX_OUT 0
  82. #define DEBUG_FILETEST 0
  83. #define RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm"
  84. #define RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm"
  85. #define RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm"
  86. #define TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm"
  87. #define TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm"
  88. #define TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm"
  89. #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
  90. #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
  91. #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
  92. #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
  93. #define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
  94. #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
  95. #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
  96. #define DELIMCHR ','
  97. #define QUOTECHR 34
  98. #define READERR_THRESHOLD 50
  99. #include "./xpmr/xpmr.h"
  100. #ifdef HAVE_XPMRX
  101. #include "./xpmrx/xpmrx.h"
  102. #include "./xpmrx/bitweight.h"
  103. #endif
  104. #if 0
  105. #define traceusb1(a) {printf a;}
  106. #else
  107. #define traceusb1(a)
  108. #endif
  109. #if 0
  110. #define traceusb2(a) {printf a;}
  111. #else
  112. #define traceusb2(a)
  113. #endif
  114. #ifdef __linux
  115. #include <linux/soundcard.h>
  116. #elif defined(__FreeBSD__)
  117. #include <sys/soundcard.h>
  118. #else
  119. #include <soundcard.h>
  120. #endif
  121. #include "asterisk/lock.h"
  122. #include "asterisk/frame.h"
  123. #include "asterisk/logger.h"
  124. #include "asterisk/callerid.h"
  125. #include "asterisk/channel.h"
  126. #include "asterisk/module.h"
  127. #include "asterisk/options.h"
  128. #include "asterisk/pbx.h"
  129. #include "asterisk/config.h"
  130. #include "asterisk/cli.h"
  131. #include "asterisk/utils.h"
  132. #include "asterisk/causes.h"
  133. #include "asterisk/endian.h"
  134. #include "asterisk/stringfields.h"
  135. #include "asterisk/abstract_jb.h"
  136. #include "asterisk/musiconhold.h"
  137. #include "asterisk/dsp.h"
  138. #ifndef NEW_ASTERISK
  139. /* ringtones we use */
  140. #include "busy.h"
  141. #include "ringtone.h"
  142. #include "ring10.h"
  143. #include "answer.h"
  144. #endif
  145. #define C108_VENDOR_ID 0x0d8c
  146. #define C108_PRODUCT_ID 0x000c
  147. #define C108_HID_INTERFACE 3
  148. #define HID_REPORT_GET 0x01
  149. #define HID_REPORT_SET 0x09
  150. #define HID_RT_INPUT 0x01
  151. #define HID_RT_OUTPUT 0x02
  152. #define EEPROM_START_ADDR 6
  153. #define EEPROM_END_ADDR 63
  154. #define EEPROM_PHYSICAL_LEN 64
  155. #define EEPROM_TEST_ADDR EEPROM_END_ADDR
  156. #define EEPROM_MAGIC_ADDR 6
  157. #define EEPROM_MAGIC 34329
  158. #define EEPROM_CS_ADDR 62
  159. #define EEPROM_RXMIXERSET 8
  160. #define EEPROM_TXMIXASET 9
  161. #define EEPROM_TXMIXBSET 10
  162. #define EEPROM_RXVOICEADJ 11
  163. #define EEPROM_RXCTCSSADJ 13
  164. #define EEPROM_TXCTCSSADJ 15
  165. #define EEPROM_RXSQUELCHADJ 16
  166. /*! Global jitterbuffer configuration - by default, jb is disabled
  167. * \note Values shown here match the defaults shown in usbradio.conf.sample */
  168. static struct ast_jb_conf default_jbconf =
  169. {
  170. .flags = 0,
  171. .max_size = 200,
  172. .resync_threshold = 1000,
  173. .impl = "fixed",
  174. .target_extra = 40,
  175. };
  176. static struct ast_jb_conf global_jbconf;
  177. /*
  178. * usbradio.conf parameters are
  179. START_CONFIG
  180. [general]
  181. ; General config options which propigate to all devices, with
  182. ; default values shown. You may have as many devices as the
  183. ; system will allow. You must use one section per device, with
  184. ; [usb] generally (although its up to you) being the first device.
  185. ;
  186. ;
  187. ; debug = 0x0 ; misc debug flags, default is 0
  188. ; Set the device to use for I/O
  189. ; devicenum = 0
  190. ; Set hardware type here
  191. ; hdwtype=0 ; 0=limey, 1=sph
  192. ; rxboost=0 ; no rx gain boost
  193. ; rxctcssrelax=1 ; reduce talkoff from radios w/o CTCSS Tx HPF
  194. ; rxctcssfreqs=100.0,123.0 ; list of rx ctcss freq in floating point. must be in table
  195. ; txctcssfreqs=100.0,123.0 ; list tx ctcss freq, any frequency permitted
  196. ; txctcssdefault=100.0 ; default tx ctcss freq, any frequency permitted
  197. ; carrierfrom=dsp ;no,usb,usbinvert,dsp,vox
  198. ; ctcssfrom=dsp ;no,usb,dsp
  199. ; rxdemod=flat ; input type from radio: no,speaker,flat
  200. ; txprelim=yes ; output is pre-emphasised and limited
  201. ; txtoctype=no ; no,phase,notone
  202. ; txmixa=composite ;no,voice,tone,composite,auxvoice
  203. ; txmixb=no ;no,voice,tone,composite,auxvoice
  204. ; invertptt=0
  205. ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
  206. ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
  207. ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will
  208. ; be used only if the sending side can create and the receiving
  209. ; side can not accept jitter. The USBRADIO channel can't accept jitter,
  210. ; thus an enabled jitterbuffer on the receive USBRADIO side will always
  211. ; be used if the sending side can create jitter.
  212. ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
  213. ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
  214. ; resynchronized. Useful to improve the quality of the voice, with
  215. ; big jumps in/broken timestamps, usualy sent from exotic devices
  216. ; and programs. Defaults to 1000.
  217. ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an USBRADIO
  218. ; channel. Two implementations are currenlty available - "fixed"
  219. ; (with size always equals to jbmax-size) and "adaptive" (with
  220. ; variable size, actually the new jb of IAX2). Defaults to fixed.
  221. ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
  222. ;-----------------------------------------------------------------------------------
  223. [usb]
  224. ; First channel unique config
  225. [usb1]
  226. ; Second channel config
  227. END_CONFIG
  228. */
  229. /*
  230. * Helper macros to parse config arguments. They will go in a common
  231. * header file if their usage is globally accepted. In the meantime,
  232. * we define them here. Typical usage is as below.
  233. * Remember to open a block right before M_START (as it declares
  234. * some variables) and use the M_* macros WITHOUT A SEMICOLON:
  235. *
  236. * {
  237. * M_START(v->name, v->value)
  238. *
  239. * M_BOOL("dothis", x->flag1)
  240. * M_STR("name", x->somestring)
  241. * M_F("bar", some_c_code)
  242. * M_END(some_final_statement)
  243. * ... other code in the block
  244. * }
  245. *
  246. * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
  247. * Likely we will come up with a better way of doing config file parsing.
  248. */
  249. #define M_START(var, val) \
  250. char *__s = var; char *__val = val;
  251. #define M_END(x) x;
  252. #define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
  253. #define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
  254. #define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
  255. #define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
  256. /*
  257. * The following parameters are used in the driver:
  258. *
  259. * FRAME_SIZE the size of an audio frame, in samples.
  260. * 160 is used almost universally, so you should not change it.
  261. *
  262. * FRAGS the argument for the SETFRAGMENT ioctl.
  263. * Overridden by the 'frags' parameter in usbradio.conf
  264. *
  265. * Bits 0-7 are the base-2 log of the device's block size,
  266. * bits 16-31 are the number of blocks in the driver's queue.
  267. * There are a lot of differences in the way this parameter
  268. * is supported by different drivers, so you may need to
  269. * experiment a bit with the value.
  270. * A good default for linux is 30 blocks of 64 bytes, which
  271. * results in 6 frames of 320 bytes (160 samples).
  272. * FreeBSD works decently with blocks of 256 or 512 bytes,
  273. * leaving the number unspecified.
  274. * Note that this only refers to the device buffer size,
  275. * this module will then try to keep the lenght of audio
  276. * buffered within small constraints.
  277. *
  278. * QUEUE_SIZE The max number of blocks actually allowed in the device
  279. * driver's buffer, irrespective of the available number.
  280. * Overridden by the 'queuesize' parameter in usbradio.conf
  281. *
  282. * Should be >=2, and at most as large as the hw queue above
  283. * (otherwise it will never be full).
  284. */
  285. #define FRAME_SIZE 160
  286. #define QUEUE_SIZE 2
  287. #if defined(__FreeBSD__)
  288. #define FRAGS 0x8
  289. #else
  290. #define FRAGS ( ( (6 * 5) << 16 ) | 0xc )
  291. #endif
  292. /*
  293. * XXX text message sizes are probably 256 chars, but i am
  294. * not sure if there is a suitable definition anywhere.
  295. */
  296. #define TEXT_SIZE 256
  297. #if 0
  298. #define TRYOPEN 1 /* try to open on startup */
  299. #endif
  300. #define O_CLOSE 0x444 /* special 'close' mode for device */
  301. /* Which device to use */
  302. #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
  303. #define DEV_DSP "/dev/audio"
  304. #else
  305. #define DEV_DSP "/dev/dsp"
  306. #endif
  307. static const char *config = "usbradio.conf"; /* default config file */
  308. #define config1 "usbradio_tune_%s.conf" /* tune config file */
  309. static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
  310. static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
  311. static char *usb_device_list = NULL;
  312. static int usb_device_list_size = 0;
  313. static int usbradio_debug;
  314. #if 0 //maw asdf sph
  315. static int usbradio_debug_level = 0;
  316. #endif
  317. enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
  318. enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
  319. enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR}; // no,external,externalinvert,software
  320. enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
  321. enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
  322. enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
  323. /* DECLARE STRUCTURES */
  324. /*
  325. * Each sound is made of 'datalen' samples of sound, repeated as needed to
  326. * generate 'samplen' samples of data, then followed by 'silencelen' samples
  327. * of silence. The loop is repeated if 'repeat' is set.
  328. */
  329. struct sound {
  330. int ind;
  331. char *desc;
  332. short *data;
  333. int datalen;
  334. int samplen;
  335. int silencelen;
  336. int repeat;
  337. };
  338. #ifndef NEW_ASTERISK
  339. static struct sound sounds[] = {
  340. { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
  341. { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
  342. { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
  343. { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
  344. { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
  345. { -1, NULL, 0, 0, 0, 0 }, /* end marker */
  346. };
  347. #endif
  348. /*
  349. * descriptor for one of our channels.
  350. * There is one used for 'default' values (from the [general] entry in
  351. * the configuration file), and then one instance for each device
  352. * (the default is cloned from [general], others are only created
  353. * if the relevant section exists).
  354. */
  355. struct chan_usbradio_pvt {
  356. struct chan_usbradio_pvt *next;
  357. char *name;
  358. #ifndef NEW_ASTERISK
  359. /*
  360. * cursound indicates which in struct sound we play. -1 means nothing,
  361. * any other value is a valid sound, in which case sampsent indicates
  362. * the next sample to send in [0..samplen + silencelen]
  363. * nosound is set to disable the audio data from the channel
  364. * (so we can play the tones etc.).
  365. */
  366. int sndcmd[2]; /* Sound command pipe */
  367. int cursound; /* index of sound to send */
  368. int sampsent; /* # of sound samples sent */
  369. int nosound; /* set to block audio from the PBX */
  370. #endif
  371. int pttkick[2];
  372. int total_blocks; /* total blocks in the output device */
  373. int sounddev;
  374. enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
  375. i16 cdMethod;
  376. int autoanswer;
  377. int autohangup;
  378. int hookstate;
  379. unsigned int queuesize; /* max fragments in queue */
  380. unsigned int frags; /* parameter for SETFRAGMENT */
  381. int warned; /* various flags used for warnings */
  382. #define WARN_used_blocks 1
  383. #define WARN_speed 2
  384. #define WARN_frag 4
  385. int w_errors; /* overfull in the write path */
  386. struct timeval lastopen;
  387. int overridecontext;
  388. int mute;
  389. /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
  390. * be representable in 16 bits to avoid overflows.
  391. */
  392. #define BOOST_SCALE (1<<9)
  393. #define BOOST_MAX 40 /* slightly less than 7 bits */
  394. int boost; /* input boost, scaled by BOOST_SCALE */
  395. char devicenum;
  396. char devstr[128];
  397. int spkrmax;
  398. int micmax;
  399. #ifndef NEW_ASTERISK
  400. pthread_t sthread;
  401. #endif
  402. pthread_t hidthread;
  403. int stophid;
  404. FILE *hkickhid;
  405. struct ast_channel *owner;
  406. char ext[AST_MAX_EXTENSION];
  407. char ctx[AST_MAX_CONTEXT];
  408. char language[MAX_LANGUAGE];
  409. char cid_name[256]; /*XXX */
  410. char cid_num[256]; /*XXX */
  411. char mohinterpret[MAX_MUSICCLASS];
  412. /* buffers used in usbradio_write, 2 per int by 2 channels by 6 times oversampling (48KS/s) */
  413. char usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];
  414. char usbradio_write_buf_1[FRAME_SIZE * 2 * 2* 6];
  415. int usbradio_write_dst;
  416. /* buffers used in usbradio_read - AST_FRIENDLY_OFFSET space for headers
  417. * plus enough room for a full frame
  418. */
  419. char usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
  420. char usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
  421. int readpos; /* read position above */
  422. struct ast_frame read_f; /* returned by usbradio_read */
  423. char debuglevel;
  424. char radioduplex; //
  425. char wanteeprom;
  426. int tracetype;
  427. int tracelevel;
  428. char area;
  429. char rptnum;
  430. int idleinterval;
  431. int turnoffs;
  432. int txsettletime;
  433. char ukey[48];
  434. char lastrx;
  435. char rxhidsq;
  436. char rxcarrierdetect; // status from pmr channel
  437. char rxctcssdecode; // status from pmr channel
  438. int rxdcsdecode;
  439. int rxlsddecode;
  440. char rxkeytype;
  441. char rxkeyed; // indicates rx signal present
  442. char lasttx;
  443. char txkeyed; // tx key request from upper layers
  444. char txchankey;
  445. char txtestkey;
  446. time_t lasthidtime;
  447. struct ast_dsp *dsp;
  448. t_pmr_chan *pmrChan;
  449. char rxcpusaver;
  450. char txcpusaver;
  451. char rxdemod;
  452. float rxgain;
  453. char rxcdtype;
  454. char rxsdtype;
  455. int rxsquelchadj; /* this copy needs to be here for initialization */
  456. int rxsqvoxadj;
  457. char txtoctype;
  458. char txprelim;
  459. float txctcssgain;
  460. char txmixa;
  461. char txmixb;
  462. char invertptt;
  463. char rxctcssrelax;
  464. float rxctcssgain;
  465. char txctcssdefault[16]; // for repeater operation
  466. char rxctcssfreqs[512]; // a string
  467. char txctcssfreqs[512];
  468. char txctcssfreq[32]; // encode now
  469. char rxctcssfreq[32]; // decode now
  470. char numrxctcssfreqs; // how many
  471. char numtxctcssfreqs;
  472. char *rxctcss[CTCSS_NUM_CODES]; // pointers to strings
  473. char *txctcss[CTCSS_NUM_CODES];
  474. int txfreq; // in Hz
  475. int rxfreq;
  476. // start remote operation info
  477. char set_txctcssdefault[16]; // for remote operation
  478. char set_txctcssfreq[16]; // encode now
  479. char set_rxctcssfreq[16]; // decode now
  480. char set_numrxctcssfreqs; // how many
  481. char set_numtxctcssfreqs;
  482. char set_rxctcssfreqs[16]; // a string
  483. char set_txctcssfreqs[16];
  484. char *set_rxctcss; // pointers to strings
  485. char *set_txctcss;
  486. int set_txfreq; // in Hz
  487. int set_rxfreq;
  488. // end remote operation info
  489. int rxmixerset;
  490. int rxboostset;
  491. float rxvoiceadj;
  492. float rxctcssadj;
  493. int txmixaset;
  494. int txmixbset;
  495. int txctcssadj;
  496. int hdwtype;
  497. int hid_gpio_ctl;
  498. int hid_gpio_ctl_loc;
  499. int hid_io_cor;
  500. int hid_io_cor_loc;
  501. int hid_io_ctcss;
  502. int hid_io_ctcss_loc;
  503. int hid_io_ptt;
  504. int hid_gpio_loc;
  505. struct {
  506. unsigned rxcapraw:1;
  507. unsigned txcapraw:1;
  508. unsigned txcap2:1;
  509. unsigned rxcap2:1;
  510. unsigned rxplmon:1;
  511. unsigned remoted:1;
  512. unsigned txpolarity:1;
  513. unsigned rxpolarity:1;
  514. unsigned dcstxpolarity:1;
  515. unsigned dcsrxpolarity:1;
  516. unsigned lsdtxpolarity:1;
  517. unsigned lsdrxpolarity:1;
  518. unsigned loopback:1;
  519. unsigned radioactive:1;
  520. }b;
  521. unsigned short eeprom[EEPROM_PHYSICAL_LEN];
  522. char eepromctl;
  523. ast_mutex_t eepromlock;
  524. struct usb_dev_handle *usb_handle;
  525. int readerrs;
  526. };
  527. // maw add additional defaults !!!
  528. static struct chan_usbradio_pvt usbradio_default = {
  529. #ifndef NEW_ASTERISK
  530. .cursound = -1,
  531. #endif
  532. .sounddev = -1,
  533. .duplex = M_UNSET, /* XXX check this */
  534. .autoanswer = 1,
  535. .autohangup = 1,
  536. .queuesize = QUEUE_SIZE,
  537. .frags = FRAGS,
  538. .ext = "s",
  539. .ctx = "default",
  540. .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
  541. .lastopen = { 0, 0 },
  542. .boost = BOOST_SCALE,
  543. .wanteeprom = 1,
  544. .area = 0,
  545. .rptnum = 0,
  546. };
  547. /* DECLARE FUNCTION PROTOTYPES */
  548. static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s);
  549. static int hidhdwconfig(struct chan_usbradio_pvt *o);
  550. static int set_txctcss_level(struct chan_usbradio_pvt *o);
  551. static void pmrdump(struct chan_usbradio_pvt *o);
  552. static void mult_set(struct chan_usbradio_pvt *o);
  553. static int mult_calc(int value);
  554. static void mixer_write(struct chan_usbradio_pvt *o);
  555. static void tune_rxinput(int fd, struct chan_usbradio_pvt *o);
  556. static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o);
  557. static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o);
  558. static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd);
  559. static void tune_write(struct chan_usbradio_pvt *o);
  560. static char *usbradio_active; /* the active device */
  561. static int setformat(struct chan_usbradio_pvt *o, int mode);
  562. static struct ast_channel *usbradio_request(const char *type, format_t format,
  563. const struct ast_channel *requestor,
  564. void *data, int *cause);
  565. static int usbradio_digit_begin(struct ast_channel *c, char digit);
  566. static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
  567. static int usbradio_text(struct ast_channel *c, const char *text);
  568. static int usbradio_hangup(struct ast_channel *c);
  569. static int usbradio_answer(struct ast_channel *c);
  570. static struct ast_frame *usbradio_read(struct ast_channel *chan);
  571. static int usbradio_call(struct ast_channel *c, char *dest, int timeout);
  572. static int usbradio_write(struct ast_channel *chan, struct ast_frame *f);
  573. static int usbradio_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
  574. static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  575. static int xpmr_config(struct chan_usbradio_pvt *o);
  576. #if DEBUG_FILETEST == 1
  577. static int RxTestIt(struct chan_usbradio_pvt *o);
  578. #endif
  579. static char tdesc[] = "USB (CM108) Radio Channel Driver";
  580. static const struct ast_channel_tech usbradio_tech = {
  581. .type = "Radio",
  582. .description = tdesc,
  583. .capabilities = AST_FORMAT_SLINEAR,
  584. .requester = usbradio_request,
  585. .send_digit_begin = usbradio_digit_begin,
  586. .send_digit_end = usbradio_digit_end,
  587. .send_text = usbradio_text,
  588. .hangup = usbradio_hangup,
  589. .answer = usbradio_answer,
  590. .read = usbradio_read,
  591. .call = usbradio_call,
  592. .write = usbradio_write,
  593. .indicate = usbradio_indicate,
  594. .fixup = usbradio_fixup,
  595. };
  596. /* Call with: devnum: alsa major device number, param: ascii Formal
  597. Parameter Name, val1, first or only value, val2 second value, or 0
  598. if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
  599. Note: must add -lasound to end of linkage */
  600. static int amixer_max(int devnum,char *param)
  601. {
  602. int rv,type;
  603. char str[100];
  604. snd_hctl_t *hctl;
  605. snd_ctl_elem_id_t *id;
  606. snd_hctl_elem_t *elem;
  607. snd_ctl_elem_info_t *info;
  608. sprintf(str,"hw:%d",devnum);
  609. if (snd_hctl_open(&hctl, str, 0)) return(-1);
  610. snd_hctl_load(hctl);
  611. snd_ctl_elem_id_alloca(&id);
  612. snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
  613. snd_ctl_elem_id_set_name(id, param);
  614. elem = snd_hctl_find_elem(hctl, id);
  615. if (!elem)
  616. {
  617. snd_hctl_close(hctl);
  618. return(-1);
  619. }
  620. snd_ctl_elem_info_alloca(&info);
  621. snd_hctl_elem_info(elem,info);
  622. type = snd_ctl_elem_info_get_type(info);
  623. rv = 0;
  624. switch(type)
  625. {
  626. case SND_CTL_ELEM_TYPE_INTEGER:
  627. rv = snd_ctl_elem_info_get_max(info);
  628. break;
  629. case SND_CTL_ELEM_TYPE_BOOLEAN:
  630. rv = 1;
  631. break;
  632. }
  633. snd_hctl_close(hctl);
  634. return(rv);
  635. }
  636. /* Call with: devnum: alsa major device number, param: ascii Formal
  637. Parameter Name, val1, first or only value, val2 second value, or 0
  638. if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
  639. Note: must add -lasound to end of linkage */
  640. static int setamixer(int devnum,char *param, int v1, int v2)
  641. {
  642. int type;
  643. char str[100];
  644. snd_hctl_t *hctl;
  645. snd_ctl_elem_id_t *id;
  646. snd_ctl_elem_value_t *control;
  647. snd_hctl_elem_t *elem;
  648. snd_ctl_elem_info_t *info;
  649. sprintf(str,"hw:%d",devnum);
  650. if (snd_hctl_open(&hctl, str, 0)) return(-1);
  651. snd_hctl_load(hctl);
  652. snd_ctl_elem_id_alloca(&id);
  653. snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
  654. snd_ctl_elem_id_set_name(id, param);
  655. elem = snd_hctl_find_elem(hctl, id);
  656. if (!elem)
  657. {
  658. snd_hctl_close(hctl);
  659. return(-1);
  660. }
  661. snd_ctl_elem_info_alloca(&info);
  662. snd_hctl_elem_info(elem,info);
  663. type = snd_ctl_elem_info_get_type(info);
  664. snd_ctl_elem_value_alloca(&control);
  665. snd_ctl_elem_value_set_id(control, id);
  666. switch(type)
  667. {
  668. case SND_CTL_ELEM_TYPE_INTEGER:
  669. snd_ctl_elem_value_set_integer(control, 0, v1);
  670. if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
  671. break;
  672. case SND_CTL_ELEM_TYPE_BOOLEAN:
  673. snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
  674. break;
  675. }
  676. if (snd_hctl_elem_write(elem, control))
  677. {
  678. snd_hctl_close(hctl);
  679. return(-1);
  680. }
  681. snd_hctl_close(hctl);
  682. return(0);
  683. }
  684. static void hid_set_outputs(struct usb_dev_handle *handle,
  685. unsigned char *outputs)
  686. {
  687. usleep(1500);
  688. usb_control_msg(handle,
  689. USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
  690. HID_REPORT_SET,
  691. 0 + (HID_RT_OUTPUT << 8),
  692. C108_HID_INTERFACE,
  693. (char*)outputs, 4, 5000);
  694. }
  695. static void hid_get_inputs(struct usb_dev_handle *handle,
  696. unsigned char *inputs)
  697. {
  698. usleep(1500);
  699. usb_control_msg(handle,
  700. USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
  701. HID_REPORT_GET,
  702. 0 + (HID_RT_INPUT << 8),
  703. C108_HID_INTERFACE,
  704. (char*)inputs, 4, 5000);
  705. }
  706. static unsigned short read_eeprom(struct usb_dev_handle *handle, int addr)
  707. {
  708. unsigned char buf[4];
  709. buf[0] = 0x80;
  710. buf[1] = 0;
  711. buf[2] = 0;
  712. buf[3] = 0x80 | (addr & 0x3f);
  713. hid_set_outputs(handle,buf);
  714. memset(buf,0,sizeof(buf));
  715. hid_get_inputs(handle,buf);
  716. return(buf[1] + (buf[2] << 8));
  717. }
  718. static void write_eeprom(struct usb_dev_handle *handle, int addr,
  719. unsigned short data)
  720. {
  721. unsigned char buf[4];
  722. buf[0] = 0x80;
  723. buf[1] = data & 0xff;
  724. buf[2] = data >> 8;
  725. buf[3] = 0xc0 | (addr & 0x3f);
  726. hid_set_outputs(handle,buf);
  727. }
  728. static unsigned short get_eeprom(struct usb_dev_handle *handle,
  729. unsigned short *buf)
  730. {
  731. int i;
  732. unsigned short cs;
  733. cs = 0xffff;
  734. for(i = EEPROM_START_ADDR; i < EEPROM_END_ADDR; i++)
  735. {
  736. cs += buf[i] = read_eeprom(handle,i);
  737. }
  738. return(cs);
  739. }
  740. static void put_eeprom(struct usb_dev_handle *handle,unsigned short *buf)
  741. {
  742. int i;
  743. unsigned short cs;
  744. cs = 0xffff;
  745. buf[EEPROM_MAGIC_ADDR] = EEPROM_MAGIC;
  746. for(i = EEPROM_START_ADDR; i < EEPROM_CS_ADDR; i++)
  747. {
  748. write_eeprom(handle,i,buf[i]);
  749. cs += buf[i];
  750. }
  751. buf[EEPROM_CS_ADDR] = (65535 - cs) + 1;
  752. write_eeprom(handle,i,buf[EEPROM_CS_ADDR]);
  753. }
  754. static struct usb_device *hid_device_init(char *desired_device)
  755. {
  756. struct usb_bus *usb_bus;
  757. struct usb_device *dev;
  758. char devstr[200],str[200],desdev[200],*cp;
  759. int i;
  760. FILE *fp;
  761. usb_init();
  762. usb_find_busses();
  763. usb_find_devices();
  764. for (usb_bus = usb_busses;
  765. usb_bus;
  766. usb_bus = usb_bus->next) {
  767. for (dev = usb_bus->devices;
  768. dev;
  769. dev = dev->next) {
  770. if ((dev->descriptor.idVendor
  771. == C108_VENDOR_ID) &&
  772. (dev->descriptor.idProduct
  773. == C108_PRODUCT_ID))
  774. {
  775. sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
  776. for(i = 0; i < 32; i++)
  777. {
  778. sprintf(str,"/proc/asound/card%d/usbbus",i);
  779. fp = fopen(str,"r");
  780. if (!fp) continue;
  781. if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
  782. {
  783. fclose(fp);
  784. continue;
  785. }
  786. fclose(fp);
  787. if (desdev[strlen(desdev) - 1] == '\n')
  788. desdev[strlen(desdev) -1 ] = 0;
  789. if (strcasecmp(desdev,devstr)) continue;
  790. if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
  791. else strcpy(str,"/sys/class/sound/dsp/device");
  792. memset(desdev,0,sizeof(desdev));
  793. if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
  794. {
  795. sprintf(str,"/sys/class/sound/controlC%d/device",i);
  796. memset(desdev,0,sizeof(desdev));
  797. if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
  798. }
  799. cp = strrchr(desdev,'/');
  800. if (cp) *cp = 0; else continue;
  801. cp = strrchr(desdev,'/');
  802. if (!cp) continue;
  803. cp++;
  804. break;
  805. }
  806. if (i >= 32) continue;
  807. if (!strcmp(cp,desired_device)) return dev;
  808. }
  809. }
  810. }
  811. return NULL;
  812. }
  813. static int hid_device_mklist(void)
  814. {
  815. struct usb_bus *usb_bus;
  816. struct usb_device *dev;
  817. char devstr[200],str[200],desdev[200],*cp;
  818. int i;
  819. FILE *fp;
  820. usb_device_list = ast_malloc(2);
  821. if (!usb_device_list) return -1;
  822. memset(usb_device_list,0,2);
  823. usb_init();
  824. usb_find_busses();
  825. usb_find_devices();
  826. for (usb_bus = usb_busses;
  827. usb_bus;
  828. usb_bus = usb_bus->next) {
  829. for (dev = usb_bus->devices;
  830. dev;
  831. dev = dev->next) {
  832. if ((dev->descriptor.idVendor
  833. == C108_VENDOR_ID) &&
  834. (dev->descriptor.idProduct
  835. == C108_PRODUCT_ID))
  836. {
  837. sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
  838. for(i = 0;i < 32; i++)
  839. {
  840. sprintf(str,"/proc/asound/card%d/usbbus",i);
  841. fp = fopen(str,"r");
  842. if (!fp) continue;
  843. if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
  844. {
  845. fclose(fp);
  846. continue;
  847. }
  848. fclose(fp);
  849. if (desdev[strlen(desdev) - 1] == '\n')
  850. desdev[strlen(desdev) -1 ] = 0;
  851. if (strcasecmp(desdev,devstr)) continue;
  852. if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
  853. else strcpy(str,"/sys/class/sound/dsp/device");
  854. memset(desdev,0,sizeof(desdev));
  855. if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
  856. {
  857. sprintf(str,"/sys/class/sound/controlC%d/device",i);
  858. memset(desdev,0,sizeof(desdev));
  859. if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
  860. }
  861. cp = strrchr(desdev,'/');
  862. if (cp) *cp = 0; else continue;
  863. cp = strrchr(desdev,'/');
  864. if (!cp) continue;
  865. cp++;
  866. break;
  867. }
  868. if (i >= 32) return -1;
  869. usb_device_list = ast_realloc(usb_device_list,
  870. usb_device_list_size + 2 +
  871. strlen(cp));
  872. if (!usb_device_list) return -1;
  873. usb_device_list_size += strlen(cp) + 2;
  874. i = 0;
  875. while(usb_device_list[i])
  876. {
  877. i += strlen(usb_device_list + i) + 1;
  878. }
  879. strcat(usb_device_list + i,cp);
  880. usb_device_list[strlen(cp) + i + 1] = 0;
  881. }
  882. }
  883. }
  884. return 0;
  885. }
  886. /* returns internal formatted string from external one */
  887. static int usb_get_usbdev(char *devstr)
  888. {
  889. int i;
  890. char str[200],desdev[200],*cp;
  891. for(i = 0;i < 32; i++)
  892. {
  893. if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
  894. else strcpy(str,"/sys/class/sound/dsp/device");
  895. memset(desdev,0,sizeof(desdev));
  896. if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
  897. {
  898. sprintf(str,"/sys/class/sound/controlC%d/device",i);
  899. memset(desdev,0,sizeof(desdev));
  900. if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
  901. }
  902. cp = strrchr(desdev,'/');
  903. if (cp) *cp = 0; else continue;
  904. cp = strrchr(desdev,'/');
  905. if (!cp) continue;
  906. cp++;
  907. if (!strcasecmp(cp,devstr)) break;
  908. }
  909. if (i >= 32) return -1;
  910. return i;
  911. }
  912. static int usb_list_check(char *devstr)
  913. {
  914. char *s = usb_device_list;
  915. if (!s) return(0);
  916. while(*s)
  917. {
  918. if (!strcasecmp(s,devstr)) return(1);
  919. s += strlen(s) + 1;
  920. }
  921. return(0);
  922. }
  923. static int hidhdwconfig(struct chan_usbradio_pvt *o)
  924. {
  925. if(o->hdwtype==1) //sphusb
  926. {
  927. o->hid_gpio_ctl = 0x08; /* set GPIO4 to output mode */
  928. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  929. o->hid_io_cor = 4; /* GPIO3 is COR */
  930. o->hid_io_cor_loc = 1; /* GPIO3 is COR */
  931. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  932. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  933. o->hid_io_ptt = 8; /* GPIO 4 is PTT */
  934. o->hid_gpio_loc = 1; /* For ALL GPIO */
  935. }
  936. else if(o->hdwtype==0) //dudeusb
  937. {
  938. o->hid_gpio_ctl = 0x0c; /* set GPIO 3 & 4 to output mode */
  939. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  940. o->hid_io_cor = 2; /* VOLD DN is COR */
  941. o->hid_io_cor_loc = 0; /* VOL DN COR */
  942. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  943. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  944. o->hid_io_ptt = 4; /* GPIO 3 is PTT */
  945. o->hid_gpio_loc = 1; /* For ALL GPIO */
  946. }
  947. else if(o->hdwtype==3) // custom version
  948. {
  949. o->hid_gpio_ctl = 0x0c; /* set GPIO 3 & 4 to output mode */
  950. o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
  951. o->hid_io_cor = 2; /* VOLD DN is COR */
  952. o->hid_io_cor_loc = 0; /* VOL DN COR */
  953. o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
  954. o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
  955. o->hid_io_ptt = 4; /* GPIO 3 is PTT */
  956. o->hid_gpio_loc = 1; /* For ALL GPIO */
  957. }
  958. return 0;
  959. }
  960. /*
  961. */
  962. static void kickptt(struct chan_usbradio_pvt *o)
  963. {
  964. char c = 0;
  965. //printf("kickptt %i %i %i\n",o->txkeyed,o->txchankey,o->txtestkey);
  966. if (!o) return;
  967. if (!o->pttkick) return;
  968. if (write(o->pttkick[1],&c,1) < 0) {
  969. ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
  970. }
  971. }
  972. /*
  973. */
  974. static void *hidthread(void *arg)
  975. {
  976. unsigned char buf[4],bufsave[4],keyed;
  977. char lastrx, txtmp;
  978. int res;
  979. struct usb_device *usb_dev;
  980. struct usb_dev_handle *usb_handle;
  981. struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
  982. struct pollfd pfd = { .events = POLLIN };
  983. usb_dev = hid_device_init(o->devstr);
  984. if (usb_dev == NULL) {
  985. ast_log(LOG_ERROR,"USB HID device not found\n");
  986. pthread_exit(NULL);
  987. }
  988. usb_handle = usb_open(usb_dev);
  989. if (usb_handle == NULL) {
  990. ast_log(LOG_ERROR,"Not able to open USB device\n");
  991. pthread_exit(NULL);
  992. }
  993. if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0)
  994. {
  995. if (usb_detach_kernel_driver_np(usb_handle,C108_HID_INTERFACE) < 0) {
  996. ast_log(LOG_ERROR,"Not able to detach the USB device\n");
  997. pthread_exit(NULL);
  998. }
  999. if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0) {
  1000. ast_log(LOG_ERROR,"Not able to claim the USB device\n");
  1001. pthread_exit(NULL);
  1002. }
  1003. }
  1004. memset(buf,0,sizeof(buf));
  1005. buf[2] = o->hid_gpio_ctl;
  1006. buf[1] = 0;
  1007. hid_set_outputs(usb_handle,buf);
  1008. memcpy(bufsave,buf,sizeof(buf));
  1009. if (pipe(o->pttkick) == -1)
  1010. {
  1011. ast_log(LOG_ERROR,"Not able to create pipe\n");
  1012. pthread_exit(NULL);
  1013. }
  1014. traceusb1(("hidthread: Starting normally on %s!!\n",o->name));
  1015. lastrx = 0;
  1016. // popen
  1017. while (!o->stophid) {
  1018. pfd.fd = o->pttkick[0];
  1019. pfd.revents = 0;
  1020. res = ast_poll(&pfd, 1, 50);
  1021. if (res < 0) {
  1022. ast_log(LOG_WARNING, "poll() failed: %s\n", strerror(errno));
  1023. usleep(10000);
  1024. continue;
  1025. }
  1026. if (pfd.revents & POLLIN) {
  1027. char c;
  1028. if (read(o->pttkick[0], &c, 1) < 0) {
  1029. ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
  1030. }
  1031. }
  1032. if (o->wanteeprom) {
  1033. ast_mutex_lock(&o->eepromlock);
  1034. if (o->eepromctl == 1) { /* to read */
  1035. /* if CS okay */
  1036. if (!get_eeprom(usb_handle, o->eeprom)) {
  1037. if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC) {
  1038. ast_log(LOG_NOTICE, "UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n", o->name);
  1039. } else {
  1040. o->rxmixerset = o->eeprom[EEPROM_RXMIXERSET];
  1041. o->txmixaset = o->eeprom[EEPROM_TXMIXASET];
  1042. o->txmixbset = o->eeprom[EEPROM_TXMIXBSET];
  1043. memcpy(&o->rxvoiceadj, &o->eeprom[EEPROM_RXVOICEADJ], sizeof(float));
  1044. memcpy(&o->rxctcssadj, &o->eeprom[EEPROM_RXCTCSSADJ], sizeof(float));
  1045. o->txctcssadj = o->eeprom[EEPROM_TXCTCSSADJ];
  1046. o->rxsquelchadj = o->eeprom[EEPROM_RXSQUELCHADJ];
  1047. ast_log(LOG_NOTICE,"EEPROM Loaded on channel %s\n",o->name);
  1048. }
  1049. } else {
  1050. ast_log(LOG_NOTICE, "USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n", o->name);
  1051. }
  1052. hid_set_outputs(usb_handle,bufsave);
  1053. }
  1054. if (o->eepromctl == 2) { /* to write */
  1055. put_eeprom(usb_handle,o->eeprom);
  1056. hid_set_outputs(usb_handle,bufsave);
  1057. ast_log(LOG_NOTICE, "USB Parameters written to EEPROM on %s\n", o->name);
  1058. }
  1059. o->eepromctl = 0;
  1060. ast_mutex_unlock(&o->eepromlock);
  1061. }
  1062. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  1063. hid_get_inputs(usb_handle,buf);
  1064. keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
  1065. if (keyed != o->rxhidsq) {
  1066. if (o->debuglevel) {
  1067. printf("chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
  1068. }
  1069. o->rxhidsq=keyed;
  1070. }
  1071. /* if change in tx state as controlled by xpmr */
  1072. txtmp = o->pmrChan->txPttOut;
  1073. if (o->lasttx != txtmp) {
  1074. o->pmrChan->txPttHid = o->lasttx = txtmp;
  1075. if (o->debuglevel) {
  1076. ast_debug(0, "hidthread: tx set to %d\n", txtmp);
  1077. }
  1078. buf[o->hid_gpio_loc] = 0;
  1079. if (!o->invertptt) {
  1080. if (txtmp) {
  1081. buf[o->hid_gpio_loc] = o->hid_io_ptt;
  1082. }
  1083. } else {
  1084. if (!txtmp) {
  1085. buf[o->hid_gpio_loc] = o->hid_io_ptt;
  1086. }
  1087. }
  1088. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  1089. memcpy(bufsave, buf, sizeof(buf));
  1090. hid_set_outputs(usb_handle, buf);
  1091. }
  1092. time(&o->lasthidtime);
  1093. }
  1094. buf[o->hid_gpio_loc] = 0;
  1095. if (o->invertptt) {
  1096. buf[o->hid_gpio_loc] = o->hid_io_ptt;
  1097. }
  1098. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  1099. hid_set_outputs(usb_handle, buf);
  1100. pthread_exit(0);
  1101. }
  1102. /*
  1103. * returns a pointer to the descriptor with the given name
  1104. */
  1105. static struct chan_usbradio_pvt *find_desc(char *dev)
  1106. {
  1107. struct chan_usbradio_pvt *o = NULL;
  1108. if (!dev)
  1109. ast_log(LOG_WARNING, "null dev\n");
  1110. for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
  1111. if (!o)
  1112. {
  1113. ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
  1114. }
  1115. return o;
  1116. }
  1117. static struct chan_usbradio_pvt *find_desc_usb(char *devstr)
  1118. {
  1119. struct chan_usbradio_pvt *o = NULL;
  1120. if (!devstr)
  1121. ast_log(LOG_WARNING, "null dev\n");
  1122. for (o = usbradio_default.next; o && devstr && strcmp(o->devstr, devstr) != 0; o = o->next);
  1123. return o;
  1124. }
  1125. /*
  1126. * split a string in extension-context, returns pointers to malloc'ed
  1127. * strings.
  1128. * If we do not have 'overridecontext' then the last @ is considered as
  1129. * a context separator, and the context is overridden.
  1130. * This is usually not very necessary as you can play with the dialplan,
  1131. * and it is nice not to need it because you have '@' in SIP addresses.
  1132. * Return value is the buffer address.
  1133. */
  1134. #if 0
  1135. static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
  1136. {
  1137. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  1138. if (ext == NULL || ctx == NULL)
  1139. return NULL; /* error */
  1140. *ext = *ctx = NULL;
  1141. if (src && *src != '\0')
  1142. *ext = ast_strdup(src);
  1143. if (*ext == NULL)
  1144. return NULL;
  1145. if (!o->overridecontext) {
  1146. /* parse from the right */
  1147. *ctx = strrchr(*ext, '@');
  1148. if (*ctx)
  1149. *(*ctx)++ = '\0';
  1150. }
  1151. return *ext;
  1152. }
  1153. #endif
  1154. /*
  1155. * Returns the number of blocks used in the audio output channel
  1156. */
  1157. static int used_blocks(struct chan_usbradio_pvt *o)
  1158. {
  1159. struct audio_buf_info info;
  1160. if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
  1161. if (!(o->warned & WARN_used_blocks)) {
  1162. ast_log(LOG_WARNING, "Error reading output space\n");
  1163. o->warned |= WARN_used_blocks;
  1164. }
  1165. return 1;
  1166. }
  1167. if (o->total_blocks == 0) {
  1168. if (0) /* debugging */
  1169. ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
  1170. o->total_blocks = info.fragments;
  1171. }
  1172. return o->total_blocks - info.fragments;
  1173. }
  1174. /* Write an exactly FRAME_SIZE sized frame */
  1175. static int soundcard_writeframe(struct chan_usbradio_pvt *o, short *data)
  1176. {
  1177. int res;
  1178. if (o->sounddev < 0)
  1179. setformat(o, O_RDWR);
  1180. if (o->sounddev < 0)
  1181. return 0; /* not fatal */
  1182. // maw maw sph !!! may or may not be a good thing
  1183. // drop the frame if not transmitting, this keeps from gradually
  1184. // filling the buffer when asterisk clock > usb sound clock
  1185. if(!o->pmrChan->txPttIn && !o->pmrChan->txPttOut)
  1186. {
  1187. //return 0;
  1188. }
  1189. /*
  1190. * Nothing complex to manage the audio device queue.
  1191. * If the buffer is full just drop the extra, otherwise write.
  1192. * XXX in some cases it might be useful to write anyways after
  1193. * a number of failures, to restart the output chain.
  1194. */
  1195. res = used_blocks(o);
  1196. if (res > o->queuesize) { /* no room to write a block */
  1197. // ast_log(LOG_WARNING, "sound device write buffer overflow\n");
  1198. if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
  1199. ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
  1200. return 0;
  1201. }
  1202. o->w_errors = 0;
  1203. return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
  1204. }
  1205. #ifndef NEW_ASTERISK
  1206. /*
  1207. * Handler for 'sound writable' events from the sound thread.
  1208. * Builds a frame from the high level description of the sounds,
  1209. * and passes it to the audio device.
  1210. * The actual sound is made of 1 or more sequences of sound samples
  1211. * (s->datalen, repeated to make s->samplen samples) followed by
  1212. * s->silencelen samples of silence. The position in the sequence is stored
  1213. * in o->sampsent, which goes between 0 .. s->samplen+s->silencelen.
  1214. * In case we fail to write a frame, don't update o->sampsent.
  1215. */
  1216. static void send_sound(struct chan_usbradio_pvt *o)
  1217. {
  1218. short myframe[FRAME_SIZE];
  1219. int ofs, l, start;
  1220. int l_sampsent = o->sampsent;
  1221. struct sound *s;
  1222. if (o->cursound < 0) /* no sound to send */
  1223. return;
  1224. s = &sounds[o->cursound];
  1225. for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
  1226. l = s->samplen - l_sampsent; /* # of available samples */
  1227. if (l > 0) {
  1228. start = l_sampsent % s->datalen; /* source offset */
  1229. if (l > FRAME_SIZE - ofs) /* don't overflow the frame */
  1230. l = FRAME_SIZE - ofs;
  1231. if (l > s->datalen - start) /* don't overflow the source */
  1232. l = s->datalen - start;
  1233. memmove(myframe + ofs, s->data + start, l * 2);
  1234. if (0)
  1235. ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
  1236. l_sampsent += l;
  1237. } else { /* end of samples, maybe some silence */
  1238. static const short silence[FRAME_SIZE] = { 0, };
  1239. l += s->silencelen;
  1240. if (l > 0) {
  1241. if (l > FRAME_SIZE - ofs)
  1242. l = FRAME_SIZE - ofs;
  1243. memmove(myframe + ofs, silence, l * 2);
  1244. l_sampsent += l;
  1245. } else { /* silence is over, restart sound if loop */
  1246. if (s->repeat == 0) { /* last block */
  1247. o->cursound = -1;
  1248. o->nosound = 0; /* allow audio data */
  1249. if (ofs < FRAME_SIZE) /* pad with silence */
  1250. memmove(myframe + ofs, silence, (FRAME_SIZE - ofs) * 2);
  1251. }
  1252. l_sampsent = 0;
  1253. }
  1254. }
  1255. }
  1256. l = soundcard_writeframe(o, myframe);
  1257. if (l > 0)
  1258. o->sampsent = l_sampsent; /* update status */
  1259. }
  1260. static void *sound_thread(void *arg)
  1261. {
  1262. char ign[4096];
  1263. struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
  1264. /*
  1265. * Just in case, kick the driver by trying to read from it.
  1266. * Ignore errors - this read is almost guaranteed to fail.
  1267. */
  1268. read(o->sounddev, ign, sizeof(ign));
  1269. for (;;) {
  1270. struct pollfd pfd[2] = { { .fd = o->sndcmd[0], .events = POLLIN }, { .fd = o->sounddev } };
  1271. int res;
  1272. if (o->cursound > -1 && o->sounddev < 0) {
  1273. setformat(o, O_RDWR); /* need the channel, try to reopen */
  1274. } else if (o->cursound == -1 && o->owner == NULL) {
  1275. setformat(o, O_CLOSE); /* can close */
  1276. }
  1277. if (o->sounddev > -1) {
  1278. if (!o->owner) { /* no one owns the audio, so we must drain it */
  1279. pfd[1].events = POLLIN;
  1280. }
  1281. if (o->cursound > -1) {
  1282. pfd[1].events |= POLLOUT;
  1283. }
  1284. }
  1285. res = ast_poll(pfd, o->sounddev > -1 ? 2 : 1, -1);
  1286. if (res < 1) {
  1287. ast_log(LOG_WARNING, "poll failed: %s\n", strerror(errno));
  1288. sleep(1);
  1289. continue;
  1290. }
  1291. if (pfd[0].revents & POLLIN) {
  1292. /* read which sound to play from the pipe */
  1293. int i, what = -1;
  1294. read(o->sndcmd[0], &what, sizeof(what));
  1295. for (i = 0; sounds[i].ind != -1; i++) {
  1296. if (sounds[i].ind == what) {
  1297. o->cursound = i;
  1298. o->sampsent = 0;
  1299. o->nosound = 1; /* block audio from pbx */
  1300. break;
  1301. }
  1302. }
  1303. if (sounds[i].ind == -1) {
  1304. ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
  1305. }
  1306. }
  1307. if (o->sounddev > -1) {
  1308. if (pfd[1].revents & POLLIN) { /* read and ignore errors */
  1309. read(o->sounddev, ign, sizeof(ign));
  1310. }
  1311. if (pfd[1].revents & POLLOUT) {
  1312. send_sound(o);
  1313. }
  1314. }
  1315. }
  1316. return NULL; /* Never reached */
  1317. }
  1318. #endif
  1319. /*
  1320. * reset and close the device if opened,
  1321. * then open and initialize it in the desired mode,
  1322. * trigger reads and writes so we can start using it.
  1323. */
  1324. static int setformat(struct chan_usbradio_pvt *o, int mode)
  1325. {
  1326. int fmt, desired, res, fd;
  1327. char device[100];
  1328. if (o->sounddev >= 0) {
  1329. ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
  1330. close(o->sounddev);
  1331. o->duplex = M_UNSET;
  1332. o->sounddev = -1;
  1333. }
  1334. if (mode == O_CLOSE) /* we are done */
  1335. return 0;
  1336. o->lastopen = ast_tvnow();
  1337. strcpy(device,"/dev/dsp");
  1338. if (o->devicenum)
  1339. sprintf(device,"/dev/dsp%d",o->devicenum);
  1340. fd = o->sounddev = open(device, mode | O_NONBLOCK);
  1341. if (fd < 0) {
  1342. ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
  1343. return -1;
  1344. }
  1345. if (o->owner)
  1346. o->owner->fds[0] = fd;
  1347. #if __BYTE_ORDER == __LITTLE_ENDIAN
  1348. fmt = AFMT_S16_LE;
  1349. #else
  1350. fmt = AFMT_S16_BE;
  1351. #endif
  1352. res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
  1353. if (res < 0) {
  1354. ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
  1355. return -1;
  1356. }
  1357. switch (mode) {
  1358. case O_RDWR:
  1359. res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
  1360. /* Check to see if duplex set (FreeBSD Bug) */
  1361. res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
  1362. if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
  1363. if (option_verbose > 1)
  1364. ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
  1365. o->duplex = M_FULL;
  1366. };
  1367. break;
  1368. case O_WRONLY:
  1369. o->duplex = M_WRITE;
  1370. break;
  1371. case O_RDONLY:
  1372. o->duplex = M_READ;
  1373. break;
  1374. }
  1375. fmt = 1;
  1376. res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
  1377. if (res < 0) {
  1378. ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
  1379. return -1;
  1380. }
  1381. fmt = desired = 48000; /* 8000 Hz desired */
  1382. res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
  1383. if (res < 0) {
  1384. ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
  1385. return -1;
  1386. }
  1387. if (fmt != desired) {
  1388. if (!(o->warned & WARN_speed)) {
  1389. ast_log(LOG_WARNING,
  1390. "Requested %d Hz, got %d Hz -- sound may be choppy\n",
  1391. desired, fmt);
  1392. o->warned |= WARN_speed;
  1393. }
  1394. }
  1395. /*
  1396. * on Freebsd, SETFRAGMENT does not work very well on some cards.
  1397. * Default to use 256 bytes, let the user override
  1398. */
  1399. if (o->frags) {
  1400. fmt = o->frags;
  1401. res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
  1402. if (res < 0) {
  1403. if (!(o->warned & WARN_frag)) {
  1404. ast_log(LOG_WARNING,
  1405. "Unable to set fragment size -- sound may be choppy\n");
  1406. o->warned |= WARN_frag;
  1407. }
  1408. }
  1409. }
  1410. /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
  1411. res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
  1412. res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
  1413. /* it may fail if we are in half duplex, never mind */
  1414. return 0;
  1415. }
  1416. /*
  1417. * some of the standard methods supported by channels.
  1418. */
  1419. static int usbradio_digit_begin(struct ast_channel *c, char digit)
  1420. {
  1421. return 0;
  1422. }
  1423. static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
  1424. {
  1425. /* no better use for received digits than print them */
  1426. ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
  1427. digit, duration);
  1428. return 0;
  1429. }
  1430. /*
  1431. SETFREQ - sets spi programmable xcvr
  1432. SETCHAN - sets binary parallel xcvr
  1433. */
  1434. static int usbradio_text(struct ast_channel *c, const char *text)
  1435. {
  1436. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  1437. double tx,rx;
  1438. char cnt,rxs[16],txs[16],txpl[16],rxpl[16];
  1439. char pwr,*cmd;
  1440. cmd = alloca(strlen(text) + 10);
  1441. /* print received messages */
  1442. if(o->debuglevel)ast_verbose(" << Console Received usbradio text %s >> \n", text);
  1443. cnt = sscanf(text, "%300s %15s %15s %15s %15s %1c", cmd, rxs, txs, rxpl, txpl, &pwr);
  1444. if (strcmp(cmd,"SETCHAN")==0)
  1445. {
  1446. u8 chan;
  1447. chan=strtod(rxs,NULL);
  1448. ppbinout(chan);
  1449. if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETCHAN cmd: %s chan: %i\n",text,chan);
  1450. return 0;
  1451. }
  1452. if (cnt < 6)
  1453. {
  1454. ast_log(LOG_ERROR,"Cannot parse usbradio text: %s\n",text);
  1455. return 0;
  1456. }
  1457. else
  1458. {
  1459. if(o->debuglevel)ast_verbose(" << %s %s %s %s %s %c >> \n", cmd,rxs,txs,rxpl,txpl,pwr);
  1460. }
  1461. if (strcmp(cmd,"SETFREQ")==0)
  1462. {
  1463. if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETFREQ cmd: %s\n",text);
  1464. tx=strtod(txs,NULL);
  1465. rx=strtod(rxs,NULL);
  1466. o->set_txfreq = round(tx * (double)1000000);
  1467. o->set_rxfreq = round(rx * (double)1000000);
  1468. o->pmrChan->txpower = (pwr == 'H');
  1469. strcpy(o->set_rxctcssfreqs,rxpl);
  1470. strcpy(o->set_txctcssfreqs,txpl);
  1471. o->b.remoted=1;
  1472. xpmr_config(o);
  1473. return 0;
  1474. }
  1475. ast_log(LOG_ERROR,"Cannot parse usbradio cmd: %s\n",text);
  1476. return 0;
  1477. }
  1478. /* Play ringtone 'x' on device 'o' */
  1479. static void ring(struct chan_usbradio_pvt *o, int x)
  1480. {
  1481. #ifndef NEW_ASTERISK
  1482. write(o->sndcmd[1], &x, sizeof(x));
  1483. #endif
  1484. }
  1485. /*
  1486. * handler for incoming calls. Either autoanswer, or start ringing
  1487. */
  1488. static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
  1489. {
  1490. struct chan_usbradio_pvt *o = c->tech_pvt;
  1491. o->stophid = 0;
  1492. time(&o->lasthidtime);
  1493. ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
  1494. ast_setstate(c, AST_STATE_UP);
  1495. return 0;
  1496. }
  1497. /*
  1498. * remote side answered the phone
  1499. */
  1500. static int usbradio_answer(struct ast_channel *c)
  1501. {
  1502. #ifndef NEW_ASTERISK
  1503. struct chan_usbradio_pvt *o = c->tech_pvt;
  1504. #endif
  1505. ast_setstate(c, AST_STATE_UP);
  1506. #ifndef NEW_ASTERISK
  1507. o->cursound = -1;
  1508. o->nosound = 0;
  1509. #endif
  1510. return 0;
  1511. }
  1512. static int usbradio_hangup(struct ast_channel *c)
  1513. {
  1514. struct chan_usbradio_pvt *o = c->tech_pvt;
  1515. //ast_log(LOG_NOTICE, "usbradio_hangup()\n");
  1516. #ifndef NEW_ASTERISK
  1517. o->cursound = -1;
  1518. o->nosound = 0;
  1519. #endif
  1520. c->tech_pvt = NULL;
  1521. o->owner = NULL;
  1522. ast_module_unref(ast_module_info->self);
  1523. if (o->hookstate) {
  1524. if (o->autoanswer || o->autohangup) {
  1525. /* Assume auto-hangup too */
  1526. o->hookstate = 0;
  1527. setformat(o, O_CLOSE);
  1528. } else {
  1529. /* Make congestion noise */
  1530. ring(o, AST_CONTROL_CONGESTION);
  1531. }
  1532. }
  1533. o->stophid = 1;
  1534. pthread_join(o->hidthread,NULL);
  1535. return 0;
  1536. }
  1537. /* used for data coming from the network */
  1538. static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
  1539. {
  1540. struct chan_usbradio_pvt *o = c->tech_pvt;
  1541. traceusb2(("usbradio_write() o->nosound= %i\n",o->nosound));
  1542. #ifndef NEW_ASTERISK
  1543. /* Immediately return if no sound is enabled */
  1544. if (o->nosound)
  1545. return 0;
  1546. /* Stop any currently playing sound */
  1547. o->cursound = -1;
  1548. #endif
  1549. /*
  1550. * we could receive a block which is not a multiple of our
  1551. * FRAME_SIZE, so buffer it locally and write to the device
  1552. * in FRAME_SIZE chunks.
  1553. * Keep the residue stored for future use.
  1554. */
  1555. #if DEBUG_CAPTURES == 1 // to write input data to a file datalen=320
  1556. if (ftxcapraw && o->b.txcapraw)
  1557. {
  1558. i16 i, tbuff[f->datalen];
  1559. for(i=0;i<f->datalen;i+=2)
  1560. {
  1561. tbuff[i]= ((i16*)(f->data.ptr))[i/2];
  1562. tbuff[i+1]= o->txkeyed*M_Q13;
  1563. }
  1564. if (fwrite(tbuff,2,f->datalen,ftxcapraw) != f->datalen) {
  1565. ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
  1566. }
  1567. //fwrite(f->data,1,f->datalen,ftxcapraw);
  1568. }
  1569. #endif
  1570. // maw just take the data from the network and save it for PmrRx processing
  1571. PmrTx(o->pmrChan,(i16*)f->data.ptr);
  1572. return 0;
  1573. }
  1574. static struct ast_frame *usbradio_read(struct ast_channel *c)
  1575. {
  1576. int res, src, datalen, oldpttout;
  1577. int cd,sd;
  1578. struct chan_usbradio_pvt *o = c->tech_pvt;
  1579. struct ast_frame *f = &o->read_f,*f1;
  1580. struct ast_frame wf = { AST_FRAME_CONTROL };
  1581. time_t now;
  1582. traceusb2(("usbradio_read()\n"));
  1583. if (o->lasthidtime)
  1584. {
  1585. time(&now);
  1586. if ((now - o->lasthidtime) > 3)
  1587. {
  1588. ast_log(LOG_ERROR,"HID process has died or something!!\n");
  1589. return NULL;
  1590. }
  1591. }
  1592. /* XXX can be simplified returning &ast_null_frame */
  1593. /* prepare a NULL frame in case we don't have enough data to return */
  1594. memset(f, '\0', sizeof(struct ast_frame));
  1595. f->frametype = AST_FRAME_NULL;
  1596. f->src = usbradio_tech.type;
  1597. res = read(o->sounddev, o->usbradio_read_buf + o->readpos,
  1598. sizeof(o->usbradio_read_buf) - o->readpos);
  1599. if (res < 0) /* audio data not ready, return a NULL frame */
  1600. {
  1601. if (errno != EAGAIN) return NULL;
  1602. if (o->readerrs++ > READERR_THRESHOLD)
  1603. {
  1604. ast_log(LOG_ERROR,"Stuck USB read channel [%s], un-sticking it!\n",o->name);
  1605. o->readerrs = 0;
  1606. return NULL;
  1607. }
  1608. if (o->readerrs == 1)
  1609. ast_log(LOG_WARNING,"Possibly stuck USB read channel. [%s]\n",o->name);
  1610. return f;
  1611. }
  1612. if (o->readerrs) ast_log(LOG_WARNING,"Nope, USB read channel [%s] wasn't stuck after all.\n",o->name);
  1613. o->readerrs = 0;
  1614. o->readpos += res;
  1615. if (o->readpos < sizeof(o->usbradio_read_buf)) /* not enough samples */
  1616. return f;
  1617. if (o->mute)
  1618. return f;
  1619. #if DEBUG_CAPTURES == 1
  1620. 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)) {
  1621. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  1622. }
  1623. #endif
  1624. #if 1
  1625. if(o->txkeyed||o->txtestkey)
  1626. {
  1627. if(!o->pmrChan->txPttIn)
  1628. {
  1629. o->pmrChan->txPttIn=1;
  1630. if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
  1631. }
  1632. }
  1633. else if(o->pmrChan->txPttIn)
  1634. {
  1635. o->pmrChan->txPttIn=0;
  1636. if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
  1637. }
  1638. oldpttout = o->pmrChan->txPttOut;
  1639. PmrRx( o->pmrChan,
  1640. (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
  1641. (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),
  1642. (i16 *)(o->usbradio_write_buf_1));
  1643. if (oldpttout != o->pmrChan->txPttOut)
  1644. {
  1645. if(o->debuglevel) ast_log(LOG_NOTICE,"txPttOut = %i, chan %s\n",o->pmrChan->txPttOut,o->owner->name);
  1646. kickptt(o);
  1647. }
  1648. #if 0 // to write 48KS/s stereo tx data to a file
  1649. if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
  1650. if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,FRAME_SIZE * 2 * 6,ftxoutraw);
  1651. #endif
  1652. #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
  1653. if ((o->b.txcap2 && ftxcaptrace) && (fwrite((o->pmrChan->ptxDebug),1,FRAME_SIZE * 2 * 16,ftxcaptrace) != FRAME_SIZE * 2 * 16)) {
  1654. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  1655. }
  1656. #endif
  1657. // 160 samples * 2 bytes/sample * 2 chan * 6x oversampling to 48KS/s
  1658. datalen = FRAME_SIZE * 24;
  1659. src = 0; /* read position into f->data */
  1660. while (src < datalen)
  1661. {
  1662. /* Compute spare room in the buffer */
  1663. int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
  1664. if (datalen - src >= l)
  1665. {
  1666. /* enough to fill a frame */
  1667. memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
  1668. soundcard_writeframe(o, (short *) o->usbradio_write_buf);
  1669. src += l;
  1670. o->usbradio_write_dst = 0;
  1671. }
  1672. else
  1673. {
  1674. /* copy residue */
  1675. l = datalen - src;
  1676. memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
  1677. src += l; /* but really, we are done */
  1678. o->usbradio_write_dst += l;
  1679. }
  1680. }
  1681. #else
  1682. static FILE *hInput;
  1683. i16 iBuff[FRAME_SIZE*2*6];
  1684. o->pmrChan->b.rxCapture=1;
  1685. if(!hInput)
  1686. {
  1687. hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
  1688. if(!hInput)
  1689. {
  1690. printf(" Input Data File Not Found.\n");
  1691. return 0;
  1692. }
  1693. }
  1694. if(0==fread((void *)iBuff,2,FRAME_SIZE*2*6,hInput))exit;
  1695. PmrRx( o->pmrChan,
  1696. (i16 *)iBuff,
  1697. (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
  1698. #endif
  1699. #if 0
  1700. if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE,"w");
  1701. if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2,frxoutraw);
  1702. #endif
  1703. #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
  1704. if ((frxcaptrace && o->b.rxcap2 && o->pmrChan->b.radioactive) && (fwrite((o->pmrChan->prxDebug),1,FRAME_SIZE * 2 * 16,frxcaptrace) != FRAME_SIZE * 2 * 16 )) {
  1705. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  1706. }
  1707. #endif
  1708. cd = 0;
  1709. if(o->rxcdtype==CD_HID && (o->pmrChan->rxExtCarrierDetect!=o->rxhidsq))
  1710. o->pmrChan->rxExtCarrierDetect=o->rxhidsq;
  1711. if(o->rxcdtype==CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect==o->rxhidsq))
  1712. o->pmrChan->rxExtCarrierDetect=!o->rxhidsq;
  1713. if( (o->rxcdtype==CD_HID && o->rxhidsq) ||
  1714. (o->rxcdtype==CD_HID_INVERT && !o->rxhidsq) ||
  1715. (o->rxcdtype==CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
  1716. (o->rxcdtype==CD_XPMR_VOX && o->pmrChan->rxCarrierDetect)
  1717. )
  1718. {
  1719. if (!o->pmrChan->txPttOut || o->radioduplex)cd=1;
  1720. }
  1721. else
  1722. {
  1723. cd=0;
  1724. }
  1725. if(cd!=o->rxcarrierdetect)
  1726. {
  1727. o->rxcarrierdetect=cd;
  1728. if(o->debuglevel) ast_log(LOG_NOTICE,"rxcarrierdetect = %i, chan %s\n",cd,o->owner->name);
  1729. // printf("rxcarrierdetect = %i, chan %s\n",res,o->owner->name);
  1730. }
  1731. if(o->pmrChan->b.ctcssRxEnable && o->pmrChan->rxCtcss->decode!=o->rxctcssdecode)
  1732. {
  1733. if(o->debuglevel)ast_log(LOG_NOTICE,"rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
  1734. // printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
  1735. o->rxctcssdecode=o->pmrChan->rxCtcss->decode;
  1736. strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
  1737. }
  1738. #ifndef HAVE_XPMRX
  1739. if( !o->pmrChan->b.ctcssRxEnable ||
  1740. ( o->pmrChan->b.ctcssRxEnable &&
  1741. o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
  1742. o->pmrChan->smode==SMODE_CTCSS )
  1743. )
  1744. {
  1745. sd=1;
  1746. }
  1747. else
  1748. {
  1749. sd=0;
  1750. }
  1751. #else
  1752. if( (!o->pmrChan->b.ctcssRxEnable && !o->pmrChan->b.dcsRxEnable && !o->pmrChan->b.lmrRxEnable) ||
  1753. ( o->pmrChan->b.ctcssRxEnable &&
  1754. o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
  1755. o->pmrChan->smode==SMODE_CTCSS ) ||
  1756. ( o->pmrChan->b.dcsRxEnable &&
  1757. o->pmrChan->decDcs->decode > 0 &&
  1758. o->pmrChan->smode==SMODE_DCS )
  1759. )
  1760. {
  1761. sd=1;
  1762. }
  1763. else
  1764. {
  1765. sd=0;
  1766. }
  1767. if(o->pmrChan->decDcs->decode!=o->rxdcsdecode)
  1768. {
  1769. if(o->debuglevel)ast_log(LOG_NOTICE,"rxdcsdecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
  1770. // printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
  1771. o->rxdcsdecode=o->pmrChan->decDcs->decode;
  1772. strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
  1773. }
  1774. if(o->pmrChan->rptnum && (o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed != o->rxlsddecode))
  1775. {
  1776. if(o->debuglevel)ast_log(LOG_NOTICE,"rxLSDecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
  1777. o->rxlsddecode=o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed;
  1778. strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
  1779. }
  1780. if( (o->pmrChan->rptnum>0 && o->pmrChan->smode==SMODE_LSD && o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed)||
  1781. (o->pmrChan->smode==SMODE_DCS && o->pmrChan->decDcs->decode>0) )
  1782. {
  1783. sd=1;
  1784. }
  1785. #endif
  1786. if ( cd && sd )
  1787. {
  1788. //if(!o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
  1789. if(!o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 1, chan %s\n", o->owner->name);
  1790. o->rxkeyed = 1;
  1791. }
  1792. else
  1793. {
  1794. //if(o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
  1795. if(o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 0, chan %s\n",o->owner->name);
  1796. o->rxkeyed = 0;
  1797. }
  1798. // provide rx signal detect conditions
  1799. if (o->lastrx && (!o->rxkeyed))
  1800. {
  1801. o->lastrx = 0;
  1802. //printf("AST_CONTROL_RADIO_UNKEY\n");
  1803. wf.subclass.integer = AST_CONTROL_RADIO_UNKEY;
  1804. ast_queue_frame(o->owner, &wf);
  1805. }
  1806. else if ((!o->lastrx) && (o->rxkeyed))
  1807. {
  1808. o->lastrx = 1;
  1809. //printf("AST_CONTROL_RADIO_KEY\n");
  1810. wf.subclass.integer = AST_CONTROL_RADIO_KEY;
  1811. if(o->rxctcssdecode)
  1812. {
  1813. wf.data.ptr = o->rxctcssfreq;
  1814. wf.datalen = strlen(o->rxctcssfreq) + 1;
  1815. TRACEO(1,("AST_CONTROL_RADIO_KEY text=%s\n",o->rxctcssfreq));
  1816. }
  1817. ast_queue_frame(o->owner, &wf);
  1818. }
  1819. o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */
  1820. if (c->_state != AST_STATE_UP) /* drop data if frame is not up */
  1821. return f;
  1822. /* ok we can build and deliver the frame to the caller */
  1823. f->frametype = AST_FRAME_VOICE;
  1824. f->subclass.codec = AST_FORMAT_SLINEAR;
  1825. f->samples = FRAME_SIZE;
  1826. f->datalen = FRAME_SIZE * 2;
  1827. f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
  1828. if (o->boost != BOOST_SCALE) { /* scale and clip values */
  1829. int i, x;
  1830. int16_t *p = (int16_t *) f->data.ptr;
  1831. for (i = 0; i < f->samples; i++) {
  1832. x = (p[i] * o->boost) / BOOST_SCALE;
  1833. if (x > 32767)
  1834. x = 32767;
  1835. else if (x < -32768)
  1836. x = -32768;
  1837. p[i] = x;
  1838. }
  1839. }
  1840. f->offset = AST_FRIENDLY_OFFSET;
  1841. if (o->dsp)
  1842. {
  1843. f1 = ast_dsp_process(c,o->dsp,f);
  1844. if ((f1->frametype == AST_FRAME_DTMF_END) ||
  1845. (f1->frametype == AST_FRAME_DTMF_BEGIN))
  1846. {
  1847. if ((f1->subclass.integer == 'm') || (f1->subclass.integer == 'u'))
  1848. {
  1849. f1->frametype = AST_FRAME_NULL;
  1850. f1->subclass.integer = 0;
  1851. return(f1);
  1852. }
  1853. if (f1->frametype == AST_FRAME_DTMF_END)
  1854. ast_log(LOG_NOTICE, "Got DTMF char %c\n", f1->subclass.integer);
  1855. return(f1);
  1856. }
  1857. }
  1858. return f;
  1859. }
  1860. static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  1861. {
  1862. struct chan_usbradio_pvt *o = newchan->tech_pvt;
  1863. ast_log(LOG_WARNING,"usbradio_fixup()\n");
  1864. o->owner = newchan;
  1865. return 0;
  1866. }
  1867. static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
  1868. {
  1869. struct chan_usbradio_pvt *o = c->tech_pvt;
  1870. int res = -1;
  1871. switch (cond) {
  1872. case AST_CONTROL_BUSY:
  1873. case AST_CONTROL_CONGESTION:
  1874. case AST_CONTROL_RINGING:
  1875. res = cond;
  1876. break;
  1877. case AST_CONTROL_INCOMPLETE:
  1878. res = AST_CONTROL_CONGESTION;
  1879. break;
  1880. case -1:
  1881. #ifndef NEW_ASTERISK
  1882. o->cursound = -1;
  1883. o->nosound = 0; /* when cursound is -1 nosound must be 0 */
  1884. #endif
  1885. return 0;
  1886. case AST_CONTROL_VIDUPDATE:
  1887. res = -1;
  1888. break;
  1889. case AST_CONTROL_HOLD:
  1890. ast_verbose(" << Console Has Been Placed on Hold >> \n");
  1891. ast_moh_start(c, data, o->mohinterpret);
  1892. break;
  1893. case AST_CONTROL_UNHOLD:
  1894. ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
  1895. ast_moh_stop(c);
  1896. break;
  1897. case AST_CONTROL_PROCEEDING:
  1898. ast_verbose(" << Call Proceeding... >> \n");
  1899. ast_moh_stop(c);
  1900. break;
  1901. case AST_CONTROL_PROGRESS:
  1902. ast_verbose(" << Call Progress... >> \n");
  1903. ast_moh_stop(c);
  1904. break;
  1905. case AST_CONTROL_RADIO_KEY:
  1906. o->txkeyed = 1;
  1907. if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_KEY Radio Transmit On. >> \n");
  1908. break;
  1909. case AST_CONTROL_RADIO_UNKEY:
  1910. o->txkeyed = 0;
  1911. if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_UNKEY Radio Transmit Off. >> \n");
  1912. break;
  1913. default:
  1914. ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
  1915. return -1;
  1916. }
  1917. if (res > -1)
  1918. ring(o, res);
  1919. return 0;
  1920. }
  1921. /*
  1922. * allocate a new channel.
  1923. */
  1924. static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state, const char *linkedid)
  1925. {
  1926. struct ast_channel *c;
  1927. c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, linkedid, 0, "Radio/%s", o->name);
  1928. if (c == NULL)
  1929. return NULL;
  1930. c->tech = &usbradio_tech;
  1931. if (o->sounddev < 0)
  1932. setformat(o, O_RDWR);
  1933. c->fds[0] = o->sounddev; /* -1 if device closed, override later */
  1934. c->nativeformats = AST_FORMAT_SLINEAR;
  1935. c->readformat = AST_FORMAT_SLINEAR;
  1936. c->writeformat = AST_FORMAT_SLINEAR;
  1937. c->tech_pvt = o;
  1938. if (!ast_strlen_zero(o->language))
  1939. ast_string_field_set(c, language, o->language);
  1940. /* Don't use ast_set_callerid() here because it will
  1941. * generate a needless NewCallerID event */
  1942. if (!ast_strlen_zero(o->cid_num)) {
  1943. c->caller.ani.number.valid = 1;
  1944. c->caller.ani.number.str = ast_strdup(o->cid_num);
  1945. }
  1946. if (!ast_strlen_zero(ext)) {
  1947. c->dialed.number.str = ast_strdup(ext);
  1948. }
  1949. o->owner = c;
  1950. ast_module_ref(ast_module_info->self);
  1951. ast_jb_configure(c, &global_jbconf);
  1952. if (state != AST_STATE_DOWN) {
  1953. if (ast_pbx_start(c)) {
  1954. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
  1955. ast_hangup(c);
  1956. o->owner = c = NULL;
  1957. /* XXX what about the channel itself ? */
  1958. /* XXX what about usecnt ? */
  1959. }
  1960. }
  1961. return c;
  1962. }
  1963. /*
  1964. */
  1965. static struct ast_channel *usbradio_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
  1966. {
  1967. struct ast_channel *c;
  1968. struct chan_usbradio_pvt *o = find_desc(data);
  1969. TRACEO(1,("usbradio_request()\n"));
  1970. if (0)
  1971. {
  1972. ast_log(LOG_WARNING, "usbradio_request type <%s> data 0x%p <%s>\n", type, data, (char *) data);
  1973. }
  1974. if (o == NULL) {
  1975. ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
  1976. /* XXX we could default to 'dsp' perhaps ? */
  1977. return NULL;
  1978. }
  1979. if ((format & AST_FORMAT_SLINEAR) == 0) {
  1980. ast_log(LOG_NOTICE, "Format 0x%" PRIx64 " unsupported\n", format);
  1981. return NULL;
  1982. }
  1983. if (o->owner) {
  1984. ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
  1985. *cause = AST_CAUSE_BUSY;
  1986. return NULL;
  1987. }
  1988. c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
  1989. if (c == NULL) {
  1990. ast_log(LOG_WARNING, "Unable to create new usb channel\n");
  1991. return NULL;
  1992. }
  1993. o->b.remoted=0;
  1994. xpmr_config(o);
  1995. return c;
  1996. }
  1997. /*
  1998. */
  1999. static int console_key(int fd, int argc, char *argv[])
  2000. {
  2001. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2002. if (argc != 2)
  2003. return RESULT_SHOWUSAGE;
  2004. o->txtestkey = 1;
  2005. return RESULT_SUCCESS;
  2006. }
  2007. /*
  2008. */
  2009. static int console_unkey(int fd, int argc, char *argv[])
  2010. {
  2011. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2012. if (argc != 2)
  2013. return RESULT_SHOWUSAGE;
  2014. o->txtestkey = 0;
  2015. return RESULT_SUCCESS;
  2016. }
  2017. static int radio_tune(int fd, int argc, char *argv[])
  2018. {
  2019. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2020. int i=0;
  2021. if ((argc < 2) || (argc > 4))
  2022. return RESULT_SHOWUSAGE;
  2023. if (argc == 2) /* just show stuff */
  2024. {
  2025. ast_cli(fd,"Active radio interface is [%s]\n",usbradio_active);
  2026. ast_cli(fd,"Output A is currently set to ");
  2027. if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
  2028. else if (o->txmixa==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
  2029. else if (o->txmixa==TX_OUT_LSD)ast_cli(fd,"tone.\n");
  2030. else if (o->txmixa==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
  2031. else ast_cli(fd,"off.\n");
  2032. ast_cli(fd,"Output B is currently set to ");
  2033. if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
  2034. else if (o->txmixb==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
  2035. else if (o->txmixb==TX_OUT_LSD)ast_cli(fd,"tone.\n");
  2036. else if (o->txmixb==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
  2037. else ast_cli(fd,"off.\n");
  2038. ast_cli(fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
  2039. ast_cli(fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
  2040. ast_cli(fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
  2041. ast_cli(fd,"Device String is %s\n",o->devstr);
  2042. return RESULT_SHOWUSAGE;
  2043. }
  2044. o->pmrChan->b.tuning=1;
  2045. if (!strcasecmp(argv[2],"rxnoise")) tune_rxinput(fd,o);
  2046. else if (!strcasecmp(argv[2],"rxvoice")) tune_rxvoice(fd,o);
  2047. else if (!strcasecmp(argv[2],"rxtone")) tune_rxctcss(fd,o);
  2048. else if (!strcasecmp(argv[2],"rxsquelch"))
  2049. {
  2050. if (argc == 3)
  2051. {
  2052. ast_cli(fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
  2053. ast_cli(fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
  2054. //ast_cli(fd,"Current Raw RSSI is %d\n",o->pmrChan->rxRssi);
  2055. //ast_cli(fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
  2056. } else {
  2057. i = atoi(argv[3]);
  2058. if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
  2059. ast_cli(fd,"Changed Squelch setting to %d\n",i);
  2060. o->rxsquelchadj = i;
  2061. *(o->pmrChan->prxSquelchAdjust)= ((999 - i) * 32767) / 1000;
  2062. }
  2063. }
  2064. else if (!strcasecmp(argv[2],"txvoice")) {
  2065. i = 0;
  2066. if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
  2067. (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
  2068. )
  2069. {
  2070. ast_log(LOG_ERROR,"No txvoice output configured.\n");
  2071. }
  2072. else if (argc == 3)
  2073. {
  2074. if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
  2075. ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
  2076. else
  2077. ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
  2078. }
  2079. else
  2080. {
  2081. i = atoi(argv[3]);
  2082. if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
  2083. if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
  2084. {
  2085. o->txmixaset=i;
  2086. ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
  2087. }
  2088. else
  2089. {
  2090. o->txmixbset=i;
  2091. ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
  2092. }
  2093. mixer_write(o);
  2094. mult_set(o);
  2095. ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
  2096. }
  2097. o->pmrChan->b.txCtcssInhibit=1;
  2098. tune_txoutput(o,i,fd);
  2099. o->pmrChan->b.txCtcssInhibit=0;
  2100. }
  2101. else if (!strcasecmp(argv[2],"txall")) {
  2102. i = 0;
  2103. if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
  2104. (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
  2105. )
  2106. {
  2107. ast_log(LOG_ERROR,"No txvoice output configured.\n");
  2108. }
  2109. else if (argc == 3)
  2110. {
  2111. if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
  2112. ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
  2113. else
  2114. ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
  2115. }
  2116. else
  2117. {
  2118. i = atoi(argv[3]);
  2119. if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
  2120. if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
  2121. {
  2122. o->txmixaset=i;
  2123. ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
  2124. }
  2125. else
  2126. {
  2127. o->txmixbset=i;
  2128. ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
  2129. }
  2130. mixer_write(o);
  2131. mult_set(o);
  2132. ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
  2133. }
  2134. tune_txoutput(o,i,fd);
  2135. }
  2136. else if (!strcasecmp(argv[2],"auxvoice")) {
  2137. i = 0;
  2138. if( (o->txmixa!=TX_OUT_AUX) && (o->txmixb!=TX_OUT_AUX))
  2139. {
  2140. ast_log(LOG_WARNING,"No auxvoice output configured.\n");
  2141. }
  2142. else if (argc == 3)
  2143. {
  2144. if(o->txmixa==TX_OUT_AUX)
  2145. ast_cli(fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
  2146. else
  2147. ast_cli(fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
  2148. }
  2149. else
  2150. {
  2151. i = atoi(argv[3]);
  2152. if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
  2153. if(o->txmixa==TX_OUT_AUX)
  2154. {
  2155. o->txmixbset=i;
  2156. ast_cli(fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
  2157. }
  2158. else
  2159. {
  2160. o->txmixbset=i;
  2161. ast_cli(fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
  2162. }
  2163. mixer_write(o);
  2164. mult_set(o);
  2165. }
  2166. //tune_auxoutput(o,i);
  2167. }
  2168. else if (!strcasecmp(argv[2],"txtone"))
  2169. {
  2170. if (argc == 3)
  2171. ast_cli(fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
  2172. else
  2173. {
  2174. i = atoi(argv[3]);
  2175. if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
  2176. o->txctcssadj = i;
  2177. set_txctcss_level(o);
  2178. ast_cli(fd,"Changed Tx CTCSS modulation setting to %i\n",i);
  2179. }
  2180. o->txtestkey=1;
  2181. usleep(5000000);
  2182. o->txtestkey=0;
  2183. }
  2184. else if (!strcasecmp(argv[2],"dump")) pmrdump(o);
  2185. else if (!strcasecmp(argv[2],"nocap"))
  2186. {
  2187. ast_cli(fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
  2188. ast_cli(fd,"File capture (raw) was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
  2189. o->b.rxcapraw=o->b.txcapraw=o->b.rxcap2=o->b.txcap2=o->pmrChan->b.rxCapture=o->pmrChan->b.txCapture=0;
  2190. if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
  2191. if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
  2192. if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
  2193. if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
  2194. if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
  2195. if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
  2196. }
  2197. else if (!strcasecmp(argv[2],"rxtracecap"))
  2198. {
  2199. if (!frxcaptrace) frxcaptrace= fopen(RX_CAP_TRACE_FILE,"w");
  2200. ast_cli(fd,"Trace rx on.\n");
  2201. o->b.rxcap2=o->pmrChan->b.rxCapture=1;
  2202. }
  2203. else if (!strcasecmp(argv[2],"txtracecap"))
  2204. {
  2205. if (!ftxcaptrace) ftxcaptrace= fopen(TX_CAP_TRACE_FILE,"w");
  2206. ast_cli(fd,"Trace tx on.\n");
  2207. o->b.txcap2=o->pmrChan->b.txCapture=1;
  2208. }
  2209. else if (!strcasecmp(argv[2],"rxcap"))
  2210. {
  2211. if (!frxcapraw) frxcapraw = fopen(RX_CAP_RAW_FILE,"w");
  2212. ast_cli(fd,"cap rx raw on.\n");
  2213. o->b.rxcapraw=1;
  2214. }
  2215. else if (!strcasecmp(argv[2],"txcap"))
  2216. {
  2217. if (!ftxcapraw) ftxcapraw = fopen(TX_CAP_RAW_FILE,"w");
  2218. ast_cli(fd,"cap tx raw on.\n");
  2219. o->b.txcapraw=1;
  2220. }
  2221. else if (!strcasecmp(argv[2],"save"))
  2222. {
  2223. tune_write(o);
  2224. ast_cli(fd,"Saved radio tuning settings to usbradio_tune_%s.conf\n",o->name);
  2225. }
  2226. else if (!strcasecmp(argv[2],"load"))
  2227. {
  2228. ast_mutex_lock(&o->eepromlock);
  2229. while(o->eepromctl)
  2230. {
  2231. ast_mutex_unlock(&o->eepromlock);
  2232. usleep(10000);
  2233. ast_mutex_lock(&o->eepromlock);
  2234. }
  2235. o->eepromctl = 1; /* request a load */
  2236. ast_mutex_unlock(&o->eepromlock);
  2237. ast_cli(fd,"Requesting loading of tuning settings from EEPROM for channel %s\n",o->name);
  2238. }
  2239. else
  2240. {
  2241. o->pmrChan->b.tuning=0;
  2242. return RESULT_SHOWUSAGE;
  2243. }
  2244. o->pmrChan->b.tuning=0;
  2245. return RESULT_SUCCESS;
  2246. }
  2247. /*
  2248. set transmit ctcss modulation level
  2249. adjust mixer output or internal gain depending on output type
  2250. setting range is 0.0 to 0.9
  2251. */
  2252. static int set_txctcss_level(struct chan_usbradio_pvt *o)
  2253. {
  2254. if (o->txmixa == TX_OUT_LSD)
  2255. {
  2256. // o->txmixaset=(151*o->txctcssadj) / 1000;
  2257. o->txmixaset=o->txctcssadj;
  2258. mixer_write(o);
  2259. mult_set(o);
  2260. }
  2261. else if (o->txmixb == TX_OUT_LSD)
  2262. {
  2263. // o->txmixbset=(151*o->txctcssadj) / 1000;
  2264. o->txmixbset=o->txctcssadj;
  2265. mixer_write(o);
  2266. mult_set(o);
  2267. }
  2268. else
  2269. {
  2270. *o->pmrChan->ptxCtcssAdjust=(o->txctcssadj * M_Q8) / 1000;
  2271. }
  2272. return 0;
  2273. }
  2274. /*
  2275. CLI debugging on and off
  2276. */
  2277. static int radio_set_debug(int fd, int argc, char *argv[])
  2278. {
  2279. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2280. o->debuglevel=1;
  2281. ast_cli(fd,"usbradio debug on.\n");
  2282. return RESULT_SUCCESS;
  2283. }
  2284. static int radio_set_debug_off(int fd, int argc, char *argv[])
  2285. {
  2286. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2287. o->debuglevel=0;
  2288. ast_cli(fd,"usbradio debug off.\n");
  2289. return RESULT_SUCCESS;
  2290. }
  2291. static int radio_active(int fd, int argc, char *argv[])
  2292. {
  2293. if (argc == 2)
  2294. ast_cli(fd, "active (command) USB Radio device is [%s]\n", usbradio_active);
  2295. else if (argc != 3)
  2296. return RESULT_SHOWUSAGE;
  2297. else {
  2298. struct chan_usbradio_pvt *o;
  2299. if (strcmp(argv[2], "show") == 0) {
  2300. for (o = usbradio_default.next; o; o = o->next)
  2301. ast_cli(fd, "device [%s] exists\n", o->name);
  2302. return RESULT_SUCCESS;
  2303. }
  2304. o = find_desc(argv[2]);
  2305. if (o == NULL)
  2306. ast_cli(fd, "No device [%s] exists\n", argv[2]);
  2307. else
  2308. {
  2309. struct chan_usbradio_pvt *ao;
  2310. for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
  2311. usbradio_active = o->name;
  2312. o->pmrChan->b.radioactive=1;
  2313. }
  2314. }
  2315. return RESULT_SUCCESS;
  2316. }
  2317. /*
  2318. CLI debugging on and off
  2319. */
  2320. static int radio_set_xpmr_debug(int fd, int argc, char *argv[])
  2321. {
  2322. struct chan_usbradio_pvt *o = find_desc(usbradio_active);
  2323. if (argc == 4)
  2324. {
  2325. int i;
  2326. i = atoi(argv[3]);
  2327. if ((i >= 0) && (i <= 100))
  2328. {
  2329. o->pmrChan->tracelevel=i;
  2330. }
  2331. }
  2332. // add ability to set it for a number of frames after which it reverts
  2333. ast_cli(fd,"usbradio xdebug on tracelevel %i\n",o->pmrChan->tracelevel);
  2334. return RESULT_SUCCESS;
  2335. }
  2336. static char key_usage[] =
  2337. "Usage: radio key\n"
  2338. " Simulates COR active.\n";
  2339. static char unkey_usage[] =
  2340. "Usage: radio unkey\n"
  2341. " Simulates COR un-active.\n";
  2342. static char active_usage[] =
  2343. "Usage: radio active [device-name]\n"
  2344. " If used without a parameter, displays which device is the current\n"
  2345. "one being commanded. If a device is specified, the commanded radio device is changed\n"
  2346. "to the device specified.\n";
  2347. /*
  2348. radio tune 6 3000 measured tx value
  2349. */
  2350. static char radio_tune_usage[] =
  2351. "Usage: radio tune <function>\n"
  2352. " rxnoise\n"
  2353. " rxvoice\n"
  2354. " rxtone\n"
  2355. " rxsquelch [newsetting]\n"
  2356. " txvoice [newsetting]\n"
  2357. " txtone [newsetting]\n"
  2358. " auxvoice [newsetting]\n"
  2359. " save (settings to tuning file)\n"
  2360. " load (tuning settings from EEPROM)\n"
  2361. "\n All [newsetting]'s are values 0-999\n\n";
  2362. #ifndef NEW_ASTERISK
  2363. static struct ast_cli_entry cli_usbradio[] = {
  2364. { { "radio", "key", NULL },
  2365. console_key, "Simulate Rx Signal Present",
  2366. key_usage, NULL, NULL},
  2367. { { "radio", "unkey", NULL },
  2368. console_unkey, "Simulate Rx Signal Lusb",
  2369. unkey_usage, NULL, NULL },
  2370. { { "radio", "tune", NULL },
  2371. radio_tune, "Radio Tune",
  2372. radio_tune_usage, NULL, NULL },
  2373. { { "radio", "set", "debug", NULL },
  2374. radio_set_debug, "Radio Debug",
  2375. radio_tune_usage, NULL, NULL },
  2376. { { "radio", "set", "debug", "off", NULL },
  2377. radio_set_debug_off, "Radio Debug",
  2378. radio_tune_usage, NULL, NULL },
  2379. { { "radio", "active", NULL },
  2380. radio_active, "Change commanded device",
  2381. active_usage, NULL, NULL },
  2382. { { "radio", "set", "xdebug", NULL },
  2383. radio_set_xpmr_debug, "Radio set xpmr debug level",
  2384. active_usage, NULL, NULL },
  2385. };
  2386. #endif
  2387. /*
  2388. * store the callerid components
  2389. */
  2390. #if 0
  2391. static void store_callerid(struct chan_usbradio_pvt *o, char *s)
  2392. {
  2393. ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
  2394. }
  2395. #endif
  2396. static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
  2397. {
  2398. if (!strcasecmp(s,"no")){
  2399. o->rxdemod = RX_AUDIO_NONE;
  2400. }
  2401. else if (!strcasecmp(s,"speaker")){
  2402. o->rxdemod = RX_AUDIO_SPEAKER;
  2403. }
  2404. else if (!strcasecmp(s,"flat")){
  2405. o->rxdemod = RX_AUDIO_FLAT;
  2406. }
  2407. else {
  2408. ast_log(LOG_WARNING,"Unrecognized rxdemod parameter: %s\n",s);
  2409. }
  2410. //ast_log(LOG_WARNING, "set rxdemod = %s\n", s);
  2411. }
  2412. static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
  2413. {
  2414. if (!strcasecmp(s,"no")){
  2415. o->txmixa = TX_OUT_OFF;
  2416. }
  2417. else if (!strcasecmp(s,"voice")){
  2418. o->txmixa = TX_OUT_VOICE;
  2419. }
  2420. else if (!strcasecmp(s,"tone")){
  2421. o->txmixa = TX_OUT_LSD;
  2422. }
  2423. else if (!strcasecmp(s,"composite")){
  2424. o->txmixa = TX_OUT_COMPOSITE;
  2425. }
  2426. else if (!strcasecmp(s,"auxvoice")){
  2427. o->txmixa = TX_OUT_AUX;
  2428. }
  2429. else {
  2430. ast_log(LOG_WARNING,"Unrecognized txmixa parameter: %s\n",s);
  2431. }
  2432. //ast_log(LOG_WARNING, "set txmixa = %s\n", s);
  2433. }
  2434. static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
  2435. {
  2436. if (!strcasecmp(s,"no")){
  2437. o->txmixb = TX_OUT_OFF;
  2438. }
  2439. else if (!strcasecmp(s,"voice")){
  2440. o->txmixb = TX_OUT_VOICE;
  2441. }
  2442. else if (!strcasecmp(s,"tone")){
  2443. o->txmixb = TX_OUT_LSD;
  2444. }
  2445. else if (!strcasecmp(s,"composite")){
  2446. o->txmixb = TX_OUT_COMPOSITE;
  2447. }
  2448. else if (!strcasecmp(s,"auxvoice")){
  2449. o->txmixb = TX_OUT_AUX;
  2450. }
  2451. else {
  2452. ast_log(LOG_WARNING,"Unrecognized txmixb parameter: %s\n",s);
  2453. }
  2454. //ast_log(LOG_WARNING, "set txmixb = %s\n", s);
  2455. }
  2456. /*
  2457. */
  2458. static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
  2459. {
  2460. if (!strcasecmp(s,"no")){
  2461. o->rxcdtype = CD_IGNORE;
  2462. }
  2463. else if (!strcasecmp(s,"usb")){
  2464. o->rxcdtype = CD_HID;
  2465. }
  2466. else if (!strcasecmp(s,"dsp")){
  2467. o->rxcdtype = CD_XPMR_NOISE;
  2468. }
  2469. else if (!strcasecmp(s,"vox")){
  2470. o->rxcdtype = CD_XPMR_VOX;
  2471. }
  2472. else if (!strcasecmp(s,"usbinvert")){
  2473. o->rxcdtype = CD_HID_INVERT;
  2474. }
  2475. else {
  2476. ast_log(LOG_WARNING,"Unrecognized rxcdtype parameter: %s\n",s);
  2477. }
  2478. //ast_log(LOG_WARNING, "set rxcdtype = %s\n", s);
  2479. }
  2480. /*
  2481. */
  2482. static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
  2483. {
  2484. if (!strcasecmp(s,"no") || !strcasecmp(s,"SD_IGNORE")){
  2485. o->rxsdtype = SD_IGNORE;
  2486. }
  2487. else if (!strcasecmp(s,"usb") || !strcasecmp(s,"SD_HID")){
  2488. o->rxsdtype = SD_HID;
  2489. }
  2490. else if (!strcasecmp(s,"usbinvert") || !strcasecmp(s,"SD_HID_INVERT")){
  2491. o->rxsdtype = SD_HID_INVERT;
  2492. }
  2493. else if (!strcasecmp(s,"software") || !strcasecmp(s,"SD_XPMR")){
  2494. o->rxsdtype = SD_XPMR;
  2495. }
  2496. else {
  2497. ast_log(LOG_WARNING,"Unrecognized rxsdtype parameter: %s\n",s);
  2498. }
  2499. //ast_log(LOG_WARNING, "set rxsdtype = %s\n", s);
  2500. }
  2501. /*
  2502. */
  2503. static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
  2504. {
  2505. float f;
  2506. sscanf(s, "%30f", &f);
  2507. o->rxgain = f;
  2508. //ast_log(LOG_WARNING, "set rxgain = %f\n", f);
  2509. }
  2510. /*
  2511. */
  2512. static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
  2513. {
  2514. float f;
  2515. sscanf(s, "%30f", &f);
  2516. o->rxvoiceadj = f;
  2517. //ast_log(LOG_WARNING, "set rxvoiceadj = %f\n", f);
  2518. }
  2519. /*
  2520. */
  2521. static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
  2522. {
  2523. float f;
  2524. sscanf(s, "%30f", &f);
  2525. o->rxctcssadj = f;
  2526. //ast_log(LOG_WARNING, "set rxctcssadj = %f\n", f);
  2527. }
  2528. /*
  2529. */
  2530. static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
  2531. {
  2532. if (!strcasecmp(s,"no") || !strcasecmp(s,"TOC_NONE")){
  2533. o->txtoctype = TOC_NONE;
  2534. }
  2535. else if (!strcasecmp(s,"phase") || !strcasecmp(s,"TOC_PHASE")){
  2536. o->txtoctype = TOC_PHASE;
  2537. }
  2538. else if (!strcasecmp(s,"notone") || !strcasecmp(s,"TOC_NOTONE")){
  2539. o->txtoctype = TOC_NOTONE;
  2540. }
  2541. else {
  2542. ast_log(LOG_WARNING,"Unrecognized txtoctype parameter: %s\n",s);
  2543. }
  2544. }
  2545. /*
  2546. */
  2547. static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd)
  2548. {
  2549. o->txtestkey=1;
  2550. o->pmrChan->txPttIn=1;
  2551. TxTestTone(o->pmrChan, 1); // generate 1KHz tone at 7200 peak
  2552. if (fd > 0) ast_cli(fd,"Tone output starting on channel %s...\n",o->name);
  2553. usleep(5000000);
  2554. TxTestTone(o->pmrChan, 0);
  2555. if (fd > 0) ast_cli(fd,"Tone output ending on channel %s...\n",o->name);
  2556. o->pmrChan->txPttIn=0;
  2557. o->txtestkey=0;
  2558. }
  2559. /*
  2560. */
  2561. static void tune_rxinput(int fd, struct chan_usbradio_pvt *o)
  2562. {
  2563. const int target=23000;
  2564. const int tolerance=2000;
  2565. const int settingmin=1;
  2566. const int settingstart=2;
  2567. const int maxtries=12;
  2568. float settingmax;
  2569. int setting=0, tries=0, tmpdiscfactor, meas;
  2570. int tunetype=0;
  2571. settingmax = o->micmax;
  2572. if(o->pmrChan->rxDemod)tunetype=1;
  2573. o->pmrChan->b.tuning=1;
  2574. setting = settingstart;
  2575. ast_cli(fd,"tune rxnoise maxtries=%i, target=%i, tolerance=%i\n",maxtries,target,tolerance);
  2576. while(tries<maxtries)
  2577. {
  2578. setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,setting,0);
  2579. setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
  2580. usleep(100000);
  2581. if(o->rxcdtype!=CD_XPMR_NOISE || o->rxdemod==RX_AUDIO_SPEAKER)
  2582. {
  2583. // printf("Measure Direct Input\n");
  2584. o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
  2585. o->pmrChan->spsMeasure->discfactor=2000;
  2586. o->pmrChan->spsMeasure->enabled=1;
  2587. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  2588. usleep(400000);
  2589. meas=o->pmrChan->spsMeasure->apeak;
  2590. o->pmrChan->spsMeasure->enabled=0;
  2591. }
  2592. else
  2593. {
  2594. // printf("Measure HF Noise\n");
  2595. tmpdiscfactor=o->pmrChan->spsRx->discfactor;
  2596. o->pmrChan->spsRx->discfactor=(i16)2000;
  2597. o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
  2598. o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
  2599. usleep(200000);
  2600. meas=o->pmrChan->rxRssi;
  2601. o->pmrChan->spsRx->discfactor=tmpdiscfactor;
  2602. o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
  2603. o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
  2604. }
  2605. if(!meas)meas++;
  2606. ast_cli(fd,"tries=%i, setting=%i, meas=%i\n",tries,setting,meas);
  2607. if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
  2608. setting=setting*target/meas;
  2609. }
  2610. else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
  2611. {
  2612. break;
  2613. }
  2614. if(setting<settingmin)setting=settingmin;
  2615. else if(setting>settingmax)setting=settingmax;
  2616. tries++;
  2617. }
  2618. ast_cli(fd,"DONE tries=%i, setting=%i, meas=%i\n",tries,
  2619. (setting * 1000) / o->micmax,meas);
  2620. if( meas<(target-tolerance) || meas>(target+tolerance) ){
  2621. ast_cli(fd,"ERROR: RX INPUT ADJUST FAILED.\n");
  2622. }else{
  2623. ast_cli(fd,"INFO: RX INPUT ADJUST SUCCESS.\n");
  2624. o->rxmixerset=(setting * 1000) / o->micmax;
  2625. }
  2626. o->pmrChan->b.tuning=0;
  2627. }
  2628. /*
  2629. */
  2630. static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o)
  2631. {
  2632. const int target=7200; // peak
  2633. const int tolerance=360; // peak to peak
  2634. const float settingmin=0.1;
  2635. const float settingmax=4;
  2636. const float settingstart=1;
  2637. const int maxtries=12;
  2638. float setting;
  2639. int tries=0, meas;
  2640. ast_cli(fd,"INFO: RX VOICE ADJUST START.\n");
  2641. ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
  2642. o->pmrChan->b.tuning=1;
  2643. if(!o->pmrChan->spsMeasure)
  2644. ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
  2645. if(!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
  2646. ast_cli(fd,"ERROR: NO SOURCE OR MEASURE SETTING.\n");
  2647. o->pmrChan->spsMeasure->source=o->pmrChan->spsRxOut->sink;
  2648. o->pmrChan->spsMeasure->enabled=1;
  2649. o->pmrChan->spsMeasure->discfactor=1000;
  2650. setting=settingstart;
  2651. // ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
  2652. while(tries<maxtries)
  2653. {
  2654. *(o->pmrChan->prxVoiceAdjust)=setting*M_Q8;
  2655. usleep(10000);
  2656. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  2657. usleep(1000000);
  2658. meas = o->pmrChan->spsMeasure->apeak;
  2659. ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
  2660. if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
  2661. setting=setting*target/meas;
  2662. }
  2663. else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
  2664. {
  2665. break;
  2666. }
  2667. if(setting<settingmin)setting=settingmin;
  2668. else if(setting>settingmax)setting=settingmax;
  2669. tries++;
  2670. }
  2671. o->pmrChan->spsMeasure->enabled=0;
  2672. ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
  2673. if( meas<(target-tolerance) || meas>(target+tolerance) ){
  2674. ast_cli(fd,"ERROR: RX VOICE GAIN ADJUST FAILED.\n");
  2675. }else{
  2676. ast_cli(fd,"INFO: RX VOICE GAIN ADJUST SUCCESS.\n");
  2677. o->rxvoiceadj=setting;
  2678. }
  2679. o->pmrChan->b.tuning=0;
  2680. }
  2681. /*
  2682. */
  2683. static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o)
  2684. {
  2685. const int target=2400; // was 4096 pre 20080205
  2686. const int tolerance=100;
  2687. const float settingmin=0.1;
  2688. const float settingmax=8;
  2689. const float settingstart=1;
  2690. const int maxtries=12;
  2691. float setting;
  2692. int tries=0, meas;
  2693. ast_cli(fd,"INFO: RX CTCSS ADJUST START.\n");
  2694. ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
  2695. o->pmrChan->b.tuning=1;
  2696. o->pmrChan->spsMeasure->source=o->pmrChan->prxCtcssMeasure;
  2697. o->pmrChan->spsMeasure->discfactor=400;
  2698. o->pmrChan->spsMeasure->enabled=1;
  2699. setting=settingstart;
  2700. while(tries<maxtries)
  2701. {
  2702. *(o->pmrChan->prxCtcssAdjust)=setting*M_Q8;
  2703. usleep(10000);
  2704. o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
  2705. usleep(500000);
  2706. meas = o->pmrChan->spsMeasure->apeak;
  2707. ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
  2708. if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
  2709. setting=setting*target/meas;
  2710. }
  2711. else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
  2712. {
  2713. break;
  2714. }
  2715. if(setting<settingmin)setting=settingmin;
  2716. else if(setting>settingmax)setting=settingmax;
  2717. tries++;
  2718. }
  2719. o->pmrChan->spsMeasure->enabled=0;
  2720. ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
  2721. if( meas<(target-tolerance) || meas>(target+tolerance) ){
  2722. ast_cli(fd,"ERROR: RX CTCSS GAIN ADJUST FAILED.\n");
  2723. }else{
  2724. ast_cli(fd,"INFO: RX CTCSS GAIN ADJUST SUCCESS.\n");
  2725. o->rxctcssadj=setting;
  2726. }
  2727. o->pmrChan->b.tuning=0;
  2728. }
  2729. /*
  2730. after radio tune is performed data is serialized here
  2731. */
  2732. static void tune_write(struct chan_usbradio_pvt *o)
  2733. {
  2734. FILE *fp;
  2735. char fname[200];
  2736. snprintf(fname,sizeof(fname) - 1,"/etc/asterisk/usbradio_tune_%s.conf",o->name);
  2737. fp = fopen(fname,"w");
  2738. fprintf(fp,"[%s]\n",o->name);
  2739. fprintf(fp,"; name=%s\n",o->name);
  2740. fprintf(fp,"; devicenum=%i\n",o->devicenum);
  2741. fprintf(fp,"devstr=%s\n",o->devstr);
  2742. fprintf(fp,"rxmixerset=%i\n",o->rxmixerset);
  2743. fprintf(fp,"txmixaset=%i\n",o->txmixaset);
  2744. fprintf(fp,"txmixbset=%i\n",o->txmixbset);
  2745. fprintf(fp,"rxvoiceadj=%f\n",o->rxvoiceadj);
  2746. fprintf(fp,"rxctcssadj=%f\n",o->rxctcssadj);
  2747. fprintf(fp,"txctcssadj=%i\n",o->txctcssadj);
  2748. fprintf(fp,"rxsquelchadj=%i\n",o->rxsquelchadj);
  2749. fclose(fp);
  2750. if(o->wanteeprom)
  2751. {
  2752. ast_mutex_lock(&o->eepromlock);
  2753. while(o->eepromctl)
  2754. {
  2755. ast_mutex_unlock(&o->eepromlock);
  2756. usleep(10000);
  2757. ast_mutex_lock(&o->eepromlock);
  2758. }
  2759. o->eeprom[EEPROM_RXMIXERSET] = o->rxmixerset;
  2760. o->eeprom[EEPROM_TXMIXASET] = o->txmixaset;
  2761. o->eeprom[EEPROM_TXMIXBSET] = o->txmixbset;
  2762. memcpy(&o->eeprom[EEPROM_RXVOICEADJ],&o->rxvoiceadj,sizeof(float));
  2763. memcpy(&o->eeprom[EEPROM_RXCTCSSADJ],&o->rxctcssadj,sizeof(float));
  2764. o->eeprom[EEPROM_TXCTCSSADJ] = o->txctcssadj;
  2765. o->eeprom[EEPROM_RXSQUELCHADJ] = o->rxsquelchadj;
  2766. o->eepromctl = 2; /* request a write */
  2767. ast_mutex_unlock(&o->eepromlock);
  2768. }
  2769. }
  2770. //
  2771. static void mixer_write(struct chan_usbradio_pvt *o)
  2772. {
  2773. setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_SW,0,0);
  2774. setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_VOL,0,0);
  2775. setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_SW,1,0);
  2776. setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL,
  2777. o->txmixaset * o->spkrmax / 1000,
  2778. o->txmixbset * o->spkrmax / 1000);
  2779. setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,
  2780. o->rxmixerset * o->micmax / 1000,0);
  2781. setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
  2782. setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_SW,1,0);
  2783. }
  2784. /*
  2785. adjust dsp multiplier to add resolution to tx level adjustment
  2786. */
  2787. static void mult_set(struct chan_usbradio_pvt *o)
  2788. {
  2789. if(o->pmrChan->spsTxOutA) {
  2790. o->pmrChan->spsTxOutA->outputGain =
  2791. mult_calc((o->txmixaset * 152) / 1000);
  2792. }
  2793. if(o->pmrChan->spsTxOutB){
  2794. o->pmrChan->spsTxOutB->outputGain =
  2795. mult_calc((o->txmixbset * 152) / 1000);
  2796. }
  2797. }
  2798. //
  2799. // input 0 - 151 outputs are pot and multiplier
  2800. //
  2801. static int mult_calc(int value)
  2802. {
  2803. const int multx=M_Q8;
  2804. int pot,mult;
  2805. pot=((int)(value/4)*4)+2;
  2806. mult = multx-( ( multx * (3-(value%4)) ) / (pot+2) );
  2807. return(mult);
  2808. }
  2809. #define pd(x) {printf(#x" = %d\n",x);}
  2810. #define pp(x) {printf(#x" = %p\n",x);}
  2811. #define ps(x) {printf(#x" = %s\n",x);}
  2812. #define pf(x) {printf(#x" = %f\n",x);}
  2813. #if 0
  2814. /*
  2815. do hid output if only requirement is ptt out
  2816. this give fastest performance with least overhead
  2817. where gpio inputs are not required.
  2818. */
  2819. static int usbhider(struct chan_usbradio_pvt *o, int opt)
  2820. {
  2821. unsigned char buf[4];
  2822. char lastrx, txtmp;
  2823. if(opt)
  2824. {
  2825. struct usb_device *usb_dev;
  2826. usb_dev = hid_device_init(o->devstr);
  2827. if (usb_dev == NULL) {
  2828. ast_log(LOG_ERROR,"USB HID device not found\n");
  2829. return -1;
  2830. }
  2831. o->usb_handle = usb_open(usb_dev);
  2832. if (o->usb_handle == NULL) {
  2833. ast_log(LOG_ERROR,"Not able to open USB device\n");
  2834. return -1;
  2835. }
  2836. if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0)
  2837. {
  2838. if (usb_detach_kernel_driver_np(o->usb_handle,C108_HID_INTERFACE) < 0) {
  2839. ast_log(LOG_ERROR,"Not able to detach the USB device\n");
  2840. return -1;
  2841. }
  2842. if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0) {
  2843. ast_log(LOG_ERROR,"Not able to claim the USB device\n");
  2844. return -1;
  2845. }
  2846. }
  2847. memset(buf,0,sizeof(buf));
  2848. buf[2] = o->hid_gpio_ctl;
  2849. buf[1] = 0;
  2850. hid_set_outputs(o->usb_handle,buf);
  2851. memcpy(bufsave,buf,sizeof(buf));
  2852. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  2853. o->lasttx=0;
  2854. }
  2855. /* if change in tx state as controlled by xpmr */
  2856. txtmp=o->pmrChan->txPttOut;
  2857. if (o->lasttx != txtmp)
  2858. {
  2859. o->pmrChan->txPttHid=o->lasttx = txtmp;
  2860. if(o->debuglevel)printf("usbhid: tx set to %d\n",txtmp);
  2861. buf[o->hid_gpio_loc] = 0;
  2862. if (!o->invertptt)
  2863. {
  2864. if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
  2865. }
  2866. else
  2867. {
  2868. if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
  2869. }
  2870. buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
  2871. hid_set_outputs(o->usb_handle,buf);
  2872. }
  2873. return(0);
  2874. }
  2875. #endif
  2876. /*
  2877. */
  2878. static void pmrdump(struct chan_usbradio_pvt *o)
  2879. {
  2880. t_pmr_chan *p;
  2881. int i;
  2882. p=o->pmrChan;
  2883. printf("\nodump()\n");
  2884. pd(o->devicenum);
  2885. ps(o->devstr);
  2886. pd(o->micmax);
  2887. pd(o->spkrmax);
  2888. pd(o->rxdemod);
  2889. pd(o->rxcdtype);
  2890. pd(o->rxsdtype);
  2891. pd(o->txtoctype);
  2892. pd(o->rxmixerset);
  2893. pd(o->rxboostset);
  2894. pf(o->rxvoiceadj);
  2895. pf(o->rxctcssadj);
  2896. pd(o->rxsquelchadj);
  2897. ps(o->txctcssdefault);
  2898. ps(o->txctcssfreq);
  2899. pd(o->numrxctcssfreqs);
  2900. if(o->numrxctcssfreqs>0)
  2901. {
  2902. for(i=0;i<o->numrxctcssfreqs;i++)
  2903. {
  2904. printf(" %i = %s %s\n",i,o->rxctcss[i],o->txctcss[i]);
  2905. }
  2906. }
  2907. pd(o->b.rxpolarity);
  2908. pd(o->b.txpolarity);
  2909. pd(o->txprelim);
  2910. pd(o->txmixa);
  2911. pd(o->txmixb);
  2912. pd(o->txmixaset);
  2913. pd(o->txmixbset);
  2914. printf("\npmrdump()\n");
  2915. pd(p->devicenum);
  2916. printf("prxSquelchAdjust=%i\n",*(o->pmrChan->prxSquelchAdjust));
  2917. pd(p->rxCarrierPoint);
  2918. pd(p->rxCarrierHyst);
  2919. pd(*p->prxVoiceAdjust);
  2920. pd(*p->prxCtcssAdjust);
  2921. pd(p->rxfreq);
  2922. pd(p->txfreq);
  2923. pd(p->rxCtcss->relax);
  2924. //pf(p->rxCtcssFreq);
  2925. pd(p->numrxcodes);
  2926. if(o->pmrChan->numrxcodes>0)
  2927. {
  2928. for(i=0;i<o->pmrChan->numrxcodes;i++)
  2929. {
  2930. printf(" %i = %s\n",i,o->pmrChan->pRxCode[i]);
  2931. }
  2932. }
  2933. pd(p->txTocType);
  2934. ps(p->pTxCodeDefault);
  2935. pd(p->txcodedefaultsmode);
  2936. pd(p->numtxcodes);
  2937. if(o->pmrChan->numtxcodes>0)
  2938. {
  2939. for(i=0;i<o->pmrChan->numtxcodes;i++)
  2940. {
  2941. printf(" %i = %s\n",i,o->pmrChan->pTxCode[i]);
  2942. }
  2943. }
  2944. pd(p->b.rxpolarity);
  2945. pd(p->b.txpolarity);
  2946. pd(p->b.dcsrxpolarity);
  2947. pd(p->b.dcstxpolarity);
  2948. pd(p->b.lsdrxpolarity);
  2949. pd(p->b.lsdtxpolarity);
  2950. pd(p->txMixA);
  2951. pd(p->txMixB);
  2952. pd(p->rxDeEmpEnable);
  2953. pd(p->rxCenterSlicerEnable);
  2954. pd(p->rxCtcssDecodeEnable);
  2955. pd(p->rxDcsDecodeEnable);
  2956. pd(p->b.ctcssRxEnable);
  2957. pd(p->b.dcsRxEnable);
  2958. pd(p->b.lmrRxEnable);
  2959. pd(p->b.dstRxEnable);
  2960. pd(p->smode);
  2961. pd(p->txHpfEnable);
  2962. pd(p->txLimiterEnable);
  2963. pd(p->txPreEmpEnable);
  2964. pd(p->txLpfEnable);
  2965. if(p->spsTxOutA)pd(p->spsTxOutA->outputGain);
  2966. if(p->spsTxOutB)pd(p->spsTxOutB->outputGain);
  2967. pd(p->txPttIn);
  2968. pd(p->txPttOut);
  2969. pd(p->tracetype);
  2970. return;
  2971. }
  2972. /*
  2973. takes data from a chan_usbradio_pvt struct (e.g. o->)
  2974. and configures the xpmr radio layer
  2975. */
  2976. static int xpmr_config(struct chan_usbradio_pvt *o)
  2977. {
  2978. //ast_log(LOG_NOTICE,"xpmr_config()\n");
  2979. TRACEO(1,("xpmr_config()\n"));
  2980. if(o->pmrChan==NULL)
  2981. {
  2982. ast_log(LOG_ERROR,"pmr channel structure NULL\n");
  2983. return 1;
  2984. }
  2985. o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
  2986. o->pmrChan->txpower=0;
  2987. if(o->b.remoted)
  2988. {
  2989. o->pmrChan->pTxCodeDefault = o->set_txctcssdefault;
  2990. o->pmrChan->pRxCodeSrc=o->set_rxctcssfreqs;
  2991. o->pmrChan->pTxCodeSrc=o->set_txctcssfreqs;
  2992. o->pmrChan->rxfreq=o->set_rxfreq;
  2993. o->pmrChan->txfreq=o->set_txfreq;
  2994. /* printf(" remoted %s %s --> %s \n",o->pmrChan->txctcssdefault,
  2995. o->pmrChan->txctcssfreq,o->pmrChan->rxctcssfreq); */
  2996. }
  2997. else
  2998. {
  2999. // set xpmr pointers to source strings
  3000. o->pmrChan->pTxCodeDefault = o->txctcssdefault;
  3001. o->pmrChan->pRxCodeSrc = o->rxctcssfreqs;
  3002. o->pmrChan->pTxCodeSrc = o->txctcssfreqs;
  3003. o->pmrChan->rxfreq = o->rxfreq;
  3004. o->pmrChan->txfreq = o->txfreq;
  3005. }
  3006. code_string_parse(o->pmrChan);
  3007. if(o->pmrChan->rxfreq) o->pmrChan->b.reprog=1;
  3008. return 0;
  3009. }
  3010. /*
  3011. * grab fields from the config file, init the descriptor and open the device.
  3012. */
  3013. static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
  3014. {
  3015. struct ast_variable *v;
  3016. struct chan_usbradio_pvt *o;
  3017. struct ast_config *cfg1;
  3018. int i;
  3019. char fname[200];
  3020. #ifdef NEW_ASTERISK
  3021. struct ast_flags zeroflag = {0};
  3022. #endif
  3023. if (ctg == NULL) {
  3024. traceusb1((" store_config() ctg == NULL\n"));
  3025. o = &usbradio_default;
  3026. ctg = "general";
  3027. } else {
  3028. /* "general" is also the default thing */
  3029. if (strcmp(ctg, "general") == 0) {
  3030. o = &usbradio_default;
  3031. } else {
  3032. // ast_log(LOG_NOTICE,"ast_calloc for chan_usbradio_pvt of %s\n",ctg);
  3033. if (!(o = ast_calloc(1, sizeof(*o))))
  3034. return NULL;
  3035. *o = usbradio_default;
  3036. o->name = ast_strdup(ctg);
  3037. if (!usbradio_active)
  3038. usbradio_active = o->name;
  3039. }
  3040. }
  3041. ast_mutex_init(&o->eepromlock);
  3042. strcpy(o->mohinterpret, "default");
  3043. /* fill other fields from configuration */
  3044. for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
  3045. M_START((char *)v->name, (char *)v->value);
  3046. /* handle jb conf */
  3047. if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
  3048. continue;
  3049. #if 0
  3050. M_BOOL("autoanswer", o->autoanswer)
  3051. M_BOOL("autohangup", o->autohangup)
  3052. M_BOOL("overridecontext", o->overridecontext)
  3053. M_STR("context", o->ctx)
  3054. M_STR("language", o->language)
  3055. M_STR("mohinterpret", o->mohinterpret)
  3056. M_STR("extension", o->ext)
  3057. M_F("callerid", store_callerid(o, v->value))
  3058. #endif
  3059. M_UINT("frags", o->frags)
  3060. M_UINT("queuesize",o->queuesize)
  3061. #if 0
  3062. M_UINT("devicenum",o->devicenum)
  3063. #endif
  3064. M_UINT("debug", usbradio_debug)
  3065. M_BOOL("rxcpusaver",o->rxcpusaver)
  3066. M_BOOL("txcpusaver",o->txcpusaver)
  3067. M_BOOL("invertptt",o->invertptt)
  3068. M_F("rxdemod",store_rxdemod(o,(char *)v->value))
  3069. M_BOOL("txprelim",o->txprelim);
  3070. M_F("txmixa",store_txmixa(o,(char *)v->value))
  3071. M_F("txmixb",store_txmixb(o,(char *)v->value))
  3072. M_F("carrierfrom",store_rxcdtype(o,(char *)v->value))
  3073. M_F("rxsdtype",store_rxsdtype(o,(char *)v->value))
  3074. M_UINT("rxsqvox",o->rxsqvoxadj)
  3075. M_STR("txctcssdefault",o->txctcssdefault)
  3076. M_STR("rxctcssfreqs",o->rxctcssfreqs)
  3077. M_STR("txctcssfreqs",o->txctcssfreqs)
  3078. M_UINT("rxfreq",o->rxfreq)
  3079. M_UINT("txfreq",o->txfreq)
  3080. M_F("rxgain",store_rxgain(o,(char *)v->value))
  3081. M_BOOL("rxboost",o->rxboostset)
  3082. M_UINT("rxctcssrelax",o->rxctcssrelax)
  3083. M_F("txtoctype",store_txtoctype(o,(char *)v->value))
  3084. M_UINT("hdwtype",o->hdwtype)
  3085. M_UINT("eeprom",o->wanteeprom)
  3086. M_UINT("duplex",o->radioduplex)
  3087. M_UINT("txsettletime",o->txsettletime)
  3088. M_BOOL("rxpolarity",o->b.rxpolarity)
  3089. M_BOOL("txpolarity",o->b.txpolarity)
  3090. M_BOOL("dcsrxpolarity",o->b.dcsrxpolarity)
  3091. M_BOOL("dcstxpolarity",o->b.dcstxpolarity)
  3092. M_BOOL("lsdrxpolarity",o->b.lsdrxpolarity)
  3093. M_BOOL("lsdtxpolarity",o->b.lsdtxpolarity)
  3094. M_BOOL("loopback",o->b.loopback)
  3095. M_BOOL("radioactive",o->b.radioactive)
  3096. M_UINT("rptnum",o->rptnum)
  3097. M_UINT("idleinterval",o->idleinterval)
  3098. M_UINT("turnoffs",o->turnoffs)
  3099. M_UINT("tracetype",o->tracetype)
  3100. M_UINT("tracelevel",o->tracelevel)
  3101. M_UINT("area",o->area)
  3102. M_STR("ukey",o->ukey)
  3103. M_END(;
  3104. );
  3105. }
  3106. o->debuglevel=0;
  3107. if (o == &usbradio_default) /* we are done with the default */
  3108. return NULL;
  3109. snprintf(fname,sizeof(fname) - 1,config1,o->name);
  3110. #ifdef NEW_ASTERISK
  3111. cfg1 = ast_config_load(fname,zeroflag);
  3112. #else
  3113. cfg1 = ast_config_load(fname);
  3114. #endif
  3115. o->rxmixerset = 500;
  3116. o->txmixaset = 500;
  3117. o->txmixbset = 500;
  3118. o->rxvoiceadj = 0.5;
  3119. o->rxctcssadj = 0.5;
  3120. o->txctcssadj = 200;
  3121. o->rxsquelchadj = 500;
  3122. o->devstr[0] = 0;
  3123. if (cfg1 && cfg1 != CONFIG_STATUS_FILEINVALID) {
  3124. for (v = ast_variable_browse(cfg1, o->name); v; v = v->next) {
  3125. M_START((char *)v->name, (char *)v->value);
  3126. M_UINT("rxmixerset", o->rxmixerset)
  3127. M_UINT("txmixaset", o->txmixaset)
  3128. M_UINT("txmixbset", o->txmixbset)
  3129. M_F("rxvoiceadj",store_rxvoiceadj(o,(char *)v->value))
  3130. M_F("rxctcssadj",store_rxctcssadj(o,(char *)v->value))
  3131. M_UINT("txctcssadj",o->txctcssadj);
  3132. M_UINT("rxsquelchadj", o->rxsquelchadj)
  3133. M_STR("devstr", o->devstr)
  3134. M_END(;
  3135. );
  3136. }
  3137. ast_config_destroy(cfg1);
  3138. } else ast_log(LOG_WARNING,"File %s not found, using default parameters.\n",fname);
  3139. if(o->wanteeprom)
  3140. {
  3141. ast_mutex_lock(&o->eepromlock);
  3142. while(o->eepromctl)
  3143. {
  3144. ast_mutex_unlock(&o->eepromlock);
  3145. usleep(10000);
  3146. ast_mutex_lock(&o->eepromlock);
  3147. }
  3148. o->eepromctl = 1; /* request a load */
  3149. ast_mutex_unlock(&o->eepromlock);
  3150. }
  3151. /* if our specified one exists in the list */
  3152. if ((!usb_list_check(o->devstr)) || find_desc_usb(o->devstr))
  3153. {
  3154. char *s;
  3155. for(s = usb_device_list; *s; s += strlen(s) + 1)
  3156. {
  3157. if (!find_desc_usb(s)) break;
  3158. }
  3159. if (!*s)
  3160. {
  3161. ast_log(LOG_WARNING,"Unable to assign USB device for channel %s\n",o->name);
  3162. goto error;
  3163. }
  3164. ast_log(LOG_NOTICE,"Assigned USB device %s to usbradio channel %s\n",s,o->name);
  3165. strcpy(o->devstr,s);
  3166. }
  3167. i = usb_get_usbdev(o->devstr);
  3168. if (i < 0)
  3169. {
  3170. ast_log(LOG_ERROR,"Not able to find alsa USB device\n");
  3171. goto error;
  3172. }
  3173. o->devicenum = i;
  3174. o->micmax = amixer_max(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL);
  3175. o->spkrmax = amixer_max(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL);
  3176. o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
  3177. o->dsp = ast_dsp_new();
  3178. if (o->dsp)
  3179. {
  3180. #ifdef NEW_ASTERISK
  3181. ast_dsp_set_features(o->dsp,DSP_FEATURE_DIGIT_DETECT);
  3182. ast_dsp_set_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
  3183. #else
  3184. ast_dsp_set_features(o->dsp,DSP_FEATURE_DTMF_DETECT);
  3185. ast_dsp_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
  3186. #endif
  3187. }
  3188. if(o->pmrChan==NULL)
  3189. {
  3190. t_pmr_chan tChan;
  3191. // ast_log(LOG_NOTICE,"createPmrChannel() %s\n",o->name);
  3192. memset(&tChan,0,sizeof(t_pmr_chan));
  3193. tChan.pTxCodeDefault = o->txctcssdefault;
  3194. tChan.pRxCodeSrc = o->rxctcssfreqs;
  3195. tChan.pTxCodeSrc = o->txctcssfreqs;
  3196. tChan.rxDemod=o->rxdemod;
  3197. tChan.rxCdType=o->rxcdtype;
  3198. tChan.rxSqVoxAdj=o->rxsqvoxadj;
  3199. if (o->txprelim)
  3200. tChan.txMod = 2;
  3201. tChan.txMixA = o->txmixa;
  3202. tChan.txMixB = o->txmixb;
  3203. tChan.rxCpuSaver=o->rxcpusaver;
  3204. tChan.txCpuSaver=o->txcpusaver;
  3205. tChan.b.rxpolarity=o->b.rxpolarity;
  3206. tChan.b.txpolarity=o->b.txpolarity;
  3207. tChan.b.dcsrxpolarity=o->b.dcsrxpolarity;
  3208. tChan.b.dcstxpolarity=o->b.dcstxpolarity;
  3209. tChan.b.lsdrxpolarity=o->b.lsdrxpolarity;
  3210. tChan.b.lsdtxpolarity=o->b.lsdtxpolarity;
  3211. tChan.tracetype=o->tracetype;
  3212. tChan.tracelevel=o->tracelevel;
  3213. tChan.rptnum=o->rptnum;
  3214. tChan.idleinterval=o->idleinterval;
  3215. tChan.turnoffs=o->turnoffs;
  3216. tChan.area=o->area;
  3217. tChan.ukey=o->ukey;
  3218. tChan.name=o->name;
  3219. o->pmrChan=createPmrChannel(&tChan,FRAME_SIZE);
  3220. o->pmrChan->radioDuplex=o->radioduplex;
  3221. o->pmrChan->b.loopback=0;
  3222. o->pmrChan->txsettletime=o->txsettletime;
  3223. o->pmrChan->rxCpuSaver=o->rxcpusaver;
  3224. o->pmrChan->txCpuSaver=o->txcpusaver;
  3225. *(o->pmrChan->prxSquelchAdjust) =
  3226. ((999 - o->rxsquelchadj) * 32767) / 1000;
  3227. *(o->pmrChan->prxVoiceAdjust)=o->rxvoiceadj*M_Q8;
  3228. *(o->pmrChan->prxCtcssAdjust)=o->rxctcssadj*M_Q8;
  3229. o->pmrChan->rxCtcss->relax=o->rxctcssrelax;
  3230. o->pmrChan->txTocType = o->txtoctype;
  3231. if ( (o->txmixa == TX_OUT_LSD) ||
  3232. (o->txmixa == TX_OUT_COMPOSITE) ||
  3233. (o->txmixb == TX_OUT_LSD) ||
  3234. (o->txmixb == TX_OUT_COMPOSITE))
  3235. {
  3236. set_txctcss_level(o);
  3237. }
  3238. if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
  3239. (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
  3240. )
  3241. {
  3242. ast_log(LOG_ERROR,"No txvoice output configured.\n");
  3243. }
  3244. if( o->txctcssfreq[0] &&
  3245. o->txmixa!=TX_OUT_LSD && o->txmixa!=TX_OUT_COMPOSITE &&
  3246. o->txmixb!=TX_OUT_LSD && o->txmixb!=TX_OUT_COMPOSITE
  3247. )
  3248. {
  3249. ast_log(LOG_ERROR,"No txtone output configured.\n");
  3250. }
  3251. if(o->b.radioactive)
  3252. {
  3253. // 20080328 sphenke asdf maw !!!
  3254. // this diagnostic option was working but now appears broken
  3255. // it's not required for operation so I'll fix it later.
  3256. //struct chan_usbradio_pvt *ao;
  3257. //for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
  3258. usbradio_active = o->name;
  3259. // o->pmrChan->b.radioactive=1;
  3260. //o->b.radioactive=0;
  3261. //o->pmrChan->b.radioactive=0;
  3262. ast_log(LOG_NOTICE,"radio active set to [%s]\n",o->name);
  3263. }
  3264. }
  3265. xpmr_config(o);
  3266. TRACEO(1,("store_config() 120\n"));
  3267. mixer_write(o);
  3268. TRACEO(1,("store_config() 130\n"));
  3269. mult_set(o);
  3270. TRACEO(1,("store_config() 140\n"));
  3271. hidhdwconfig(o);
  3272. TRACEO(1,("store_config() 200\n"));
  3273. #ifndef NEW_ASTERISK
  3274. if (pipe(o->sndcmd) != 0) {
  3275. ast_log(LOG_ERROR, "Unable to create pipe\n");
  3276. goto error;
  3277. }
  3278. ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
  3279. #endif
  3280. /* link into list of devices */
  3281. if (o != &usbradio_default) {
  3282. o->next = usbradio_default.next;
  3283. usbradio_default.next = o;
  3284. }
  3285. TRACEO(1,("store_config() complete\n"));
  3286. return o;
  3287. error:
  3288. if (o != &usbradio_default)
  3289. free(o);
  3290. return NULL;
  3291. }
  3292. #if DEBUG_FILETEST == 1
  3293. /*
  3294. Test It on a File
  3295. */
  3296. int RxTestIt(struct chan_usbradio_pvt *o)
  3297. {
  3298. const int numSamples = SAMPLES_PER_BLOCK;
  3299. const int numChannels = 16;
  3300. i16 sample,i,ii;
  3301. i32 txHangTime;
  3302. i16 txEnable;
  3303. t_pmr_chan tChan;
  3304. t_pmr_chan *pChan;
  3305. FILE *hInput=NULL, *hOutput=NULL, *hOutputTx=NULL;
  3306. i16 iBuff[numSamples*2*6], oBuff[numSamples];
  3307. printf("RxTestIt()\n");
  3308. pChan=o->pmrChan;
  3309. pChan->b.txCapture=1;
  3310. pChan->b.rxCapture=1;
  3311. txEnable = 0;
  3312. hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
  3313. if(!hInput){
  3314. printf(" RxTestIt() File Not Found.\n");
  3315. return 0;
  3316. }
  3317. hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm","w");
  3318. printf(" RxTestIt() Working...\n");
  3319. while(!feof(hInput))
  3320. {
  3321. fread((void *)iBuff,2,numSamples*2*6,hInput);
  3322. if(txHangTime)txHangTime-=numSamples;
  3323. if(txHangTime<0)txHangTime=0;
  3324. if(pChan->rxCtcss->decode)txHangTime=(8000/1000*2000);
  3325. if(pChan->rxCtcss->decode && !txEnable)
  3326. {
  3327. txEnable=1;
  3328. //pChan->inputBlanking=(8000/1000*200);
  3329. }
  3330. else if(!pChan->rxCtcss->decode && txEnable)
  3331. {
  3332. txEnable=0;
  3333. }
  3334. PmrRx(pChan,iBuff,oBuff);
  3335. if (fwrite((void *)pChan->prxDebug,2,numSamples*numChannels,hOutput) != numSamples * numChannels) {
  3336. ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
  3337. }
  3338. }
  3339. pChan->b.txCapture=0;
  3340. pChan->b.rxCapture=0;
  3341. if(hInput)fclose(hInput);
  3342. if(hOutput)fclose(hOutput);
  3343. printf(" RxTestIt() Complete.\n");
  3344. return 0;
  3345. }
  3346. #endif
  3347. #ifdef NEW_ASTERISK
  3348. static char *res2cli(int r)
  3349. {
  3350. switch (r)
  3351. {
  3352. case RESULT_SUCCESS:
  3353. return(CLI_SUCCESS);
  3354. case RESULT_SHOWUSAGE:
  3355. return(CLI_SHOWUSAGE);
  3356. default:
  3357. return(CLI_FAILURE);
  3358. }
  3359. }
  3360. static char *handle_console_key(struct ast_cli_entry *e,
  3361. int cmd, struct ast_cli_args *a)
  3362. {
  3363. char *argv[] = { "radio", "key", NULL };
  3364. switch (cmd) {
  3365. case CLI_INIT:
  3366. e->command = "radio key";
  3367. e->usage = key_usage;
  3368. return NULL;
  3369. case CLI_GENERATE:
  3370. return NULL;
  3371. }
  3372. return res2cli(console_key(a->fd, 2, argv));
  3373. }
  3374. static char *handle_console_unkey(struct ast_cli_entry *e,
  3375. int cmd, struct ast_cli_args *a)
  3376. {
  3377. char *argv[] = { "radio", "unkey", NULL };
  3378. switch (cmd) {
  3379. case CLI_INIT:
  3380. e->command = "radio unkey";
  3381. e->usage = unkey_usage;
  3382. return NULL;
  3383. case CLI_GENERATE:
  3384. return NULL;
  3385. }
  3386. return res2cli(console_unkey(a->fd, 2, argv));
  3387. }
  3388. static char *handle_radio_tune(struct ast_cli_entry *e,
  3389. int cmd, struct ast_cli_args *a)
  3390. {
  3391. char *argv[5] = { "radio", "tune", a->argc > 2 ? (char *) a->argv[2] : NULL, a->argc > 3 ? (char *) a->argv[3] : NULL };
  3392. switch (cmd) {
  3393. case CLI_INIT:
  3394. e->command = "radio tune";
  3395. e->usage = radio_tune_usage;
  3396. return NULL;
  3397. case CLI_GENERATE:
  3398. return NULL;
  3399. }
  3400. return res2cli(radio_tune(a->fd, a->argc, argv));
  3401. }
  3402. static char *handle_radio_debug(struct ast_cli_entry *e,
  3403. int cmd, struct ast_cli_args *a)
  3404. {
  3405. switch (cmd) {
  3406. case CLI_INIT:
  3407. e->command = "radio debug";
  3408. e->usage = radio_tune_usage;
  3409. return NULL;
  3410. case CLI_GENERATE:
  3411. return NULL;
  3412. }
  3413. return res2cli(radio_set_debug(a->fd, a->argc, NULL /* ignored */));
  3414. }
  3415. static char *handle_radio_debug_off(struct ast_cli_entry *e,
  3416. int cmd, struct ast_cli_args *a)
  3417. {
  3418. switch (cmd) {
  3419. case CLI_INIT:
  3420. e->command = "radio debug off";
  3421. e->usage = radio_tune_usage;
  3422. return NULL;
  3423. case CLI_GENERATE:
  3424. return NULL;
  3425. }
  3426. return res2cli(radio_set_debug_off(a->fd, a->argc, NULL /* ignored */));
  3427. }
  3428. static char *handle_radio_active(struct ast_cli_entry *e,
  3429. int cmd, struct ast_cli_args *a)
  3430. {
  3431. char *argv[4] = { "radio", "active", a->argc > 2 ? (char *) a->argv[2] : NULL, };
  3432. switch (cmd) {
  3433. case CLI_INIT:
  3434. e->command = "radio active";
  3435. e->usage = active_usage;
  3436. return NULL;
  3437. case CLI_GENERATE:
  3438. return NULL;
  3439. }
  3440. return res2cli(radio_active(a->fd, a->argc, argv));
  3441. }
  3442. static char *handle_set_xdebug(struct ast_cli_entry *e,
  3443. int cmd, struct ast_cli_args *a)
  3444. {
  3445. char *argv[5] = { "radio", "set", "xdebug", a->argc == 4 ? (char *) a->argv[3] : NULL, };
  3446. switch (cmd) {
  3447. case CLI_INIT:
  3448. e->command = "radio set xdebug";
  3449. e->usage = active_usage;
  3450. return NULL;
  3451. case CLI_GENERATE:
  3452. return NULL;
  3453. }
  3454. return res2cli(radio_set_xpmr_debug(a->fd, a->argc, argv));
  3455. }
  3456. static struct ast_cli_entry cli_usbradio[] = {
  3457. AST_CLI_DEFINE(handle_console_key,"Simulate Rx Signal Present"),
  3458. AST_CLI_DEFINE(handle_console_unkey,"Simulate Rx Signal Loss"),
  3459. AST_CLI_DEFINE(handle_radio_tune,"Radio Tune"),
  3460. AST_CLI_DEFINE(handle_radio_debug,"Radio Debug On"),
  3461. AST_CLI_DEFINE(handle_radio_debug_off,"Radio Debug Off"),
  3462. AST_CLI_DEFINE(handle_radio_active,"Change commanded device"),
  3463. AST_CLI_DEFINE(handle_set_xdebug,"Radio set xpmr debug level")
  3464. };
  3465. #endif
  3466. #include "./xpmr/xpmr.c"
  3467. #ifdef HAVE_XPMRX
  3468. #include "./xpmrx/xpmrx.c"
  3469. #endif
  3470. /*
  3471. */
  3472. static int load_module(void)
  3473. {
  3474. struct ast_config *cfg = NULL;
  3475. char *ctg = NULL;
  3476. #ifdef NEW_ASTERISK
  3477. struct ast_flags zeroflag = {0};
  3478. #endif
  3479. if (hid_device_mklist()) {
  3480. ast_log(LOG_NOTICE, "Unable to make hid list\n");
  3481. return AST_MODULE_LOAD_DECLINE;
  3482. }
  3483. usb_list_check("");
  3484. usbradio_active = NULL;
  3485. /* Copy the default jb config over global_jbconf */
  3486. memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
  3487. /* load config file */
  3488. #ifdef NEW_ASTERISK
  3489. if (!(cfg = ast_config_load(config,zeroflag)) || cfg == CONFIG_STATUS_FILEINVALID) {
  3490. #else
  3491. if (!(cfg = ast_config_load(config))) || cfg == CONFIG_STATUS_FILEINVALID {
  3492. #endif
  3493. ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
  3494. return AST_MODULE_LOAD_DECLINE;
  3495. }
  3496. do {
  3497. store_config(cfg, ctg);
  3498. } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
  3499. ast_config_destroy(cfg);
  3500. if (find_desc(usbradio_active) == NULL) {
  3501. ast_log(LOG_NOTICE, "radio active device %s not found\n", usbradio_active);
  3502. /* XXX we could default to 'dsp' perhaps ? */
  3503. /* XXX should cleanup allocated memory etc. */
  3504. return AST_MODULE_LOAD_DECLINE;
  3505. }
  3506. if (ast_channel_register(&usbradio_tech)) {
  3507. ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
  3508. return AST_MODULE_LOAD_DECLINE;
  3509. }
  3510. ast_cli_register_multiple(cli_usbradio, ARRAY_LEN(cli_usbradio));
  3511. return AST_MODULE_LOAD_SUCCESS;
  3512. }
  3513. /*
  3514. */
  3515. static int unload_module(void)
  3516. {
  3517. struct chan_usbradio_pvt *o;
  3518. ast_log(LOG_WARNING, "unload_module() called\n");
  3519. ast_channel_unregister(&usbradio_tech);
  3520. ast_cli_unregister_multiple(cli_usbradio, ARRAY_LEN(cli_usbradio));
  3521. for (o = usbradio_default.next; o; o = o->next) {
  3522. ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
  3523. if(o->pmrChan)destroyPmrChannel(o->pmrChan);
  3524. #if DEBUG_CAPTURES == 1
  3525. if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
  3526. if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
  3527. if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
  3528. if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
  3529. if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
  3530. if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
  3531. #endif
  3532. close(o->sounddev);
  3533. #ifndef NEW_ASTERISK
  3534. if (o->sndcmd[0] > 0) {
  3535. close(o->sndcmd[0]);
  3536. close(o->sndcmd[1]);
  3537. }
  3538. #endif
  3539. if (o->dsp) ast_dsp_free(o->dsp);
  3540. if (o->owner)
  3541. ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
  3542. if (o->owner) /* XXX how ??? */
  3543. return -1;
  3544. /* XXX what about the thread ? */
  3545. /* XXX what about the memory allocated ? */
  3546. }
  3547. return 0;
  3548. }
  3549. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
  3550. /* end of file */