app_rpt.c 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138
  1. /** @file app_rpt.c
  2. *
  3. * Asterisk -- A telephony toolkit for Linux.
  4. *
  5. * Radio Repeater / Remote Base program
  6. * version 0.17 9/13/04
  7. *
  8. * See http://www.zapatatelephony.org/app_rpt.html
  9. *
  10. * Copyright (C) 2002-2004, Jim Dixon, WB6NIL
  11. *
  12. * Jim Dixon, WB6NIL <jim@lambdatel.com>
  13. * Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License
  17. *
  18. * Repeater / Remote Functions:
  19. * "Simple" Mode: * - autopatch access, # - autopatch hangup
  20. * Normal mode:
  21. * See the function list in rpt.conf
  22. *
  23. * To send an asterisk (*) while dialing or talking on phone,
  24. * use the autopatch acess code.
  25. *
  26. *
  27. * status cmds:
  28. *
  29. * 1 - Force ID
  30. * 2 - Give Time of Day
  31. * 3 - Give software Version
  32. *
  33. * cop (control operator) cmds:
  34. *
  35. * 1 - System warm boot
  36. * 2 - System enable
  37. * 3 - System disable
  38. *
  39. * ilink cmds:
  40. *
  41. * 1 - Disconnect specified link
  42. * 2 - Connect specified link -- monitor only
  43. * 3 - Connect specified link -- tranceive
  44. * 4 - Enter command mode on specified link
  45. * 5 - System status
  46. * 6 - Disconnect all links
  47. *
  48. * remote cmds:
  49. *
  50. * 0 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf)
  51. * 1 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset)
  52. * 2 - Set Rx PL Tone HHH*D*
  53. * 3 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1)
  54. * 5 - Link Status
  55. * 100 - RX PL off (Default)
  56. * 101 - RX PL On
  57. * 102 - TX PL Off (Default)
  58. * 103 - TX PL On
  59. * 104 - Low Power
  60. * 105 - Med Power
  61. * 106 - Hi Power
  62. *
  63. *
  64. */
  65. /* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
  66. #define MAXDTMF 32
  67. #define DTMF_TIMEOUT 3
  68. #define MAXREMSTR 15
  69. #define NODES "nodes"
  70. #define MEMORY "memory"
  71. #define FUNCTIONS "functions"
  72. #define TELEMETRY "telemetry"
  73. #define MORSE "morse"
  74. #define FUNCCHAR '*'
  75. #define ENDCHAR '#'
  76. #define DEFAULT_IOBASE 0x378
  77. #define MAXCONNECTTIME 5000
  78. #define MAXNODESTR 300
  79. #define ACTIONSIZE 32
  80. #define TELEPARAMSIZE 32
  81. enum {REM_OFF,REM_MONITOR,REM_TX};
  82. enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
  83. CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
  84. STATS_VERSION, IDTALKOVER, ARB_ALPHA};
  85. enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
  86. enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
  87. enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE};
  88. enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT};
  89. enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM};
  90. #include <asterisk/utils.h>
  91. #include <asterisk/lock.h>
  92. #include <asterisk/file.h>
  93. #include <asterisk/logger.h>
  94. #include <asterisk/channel.h>
  95. #include <asterisk/callerid.h>
  96. #include <asterisk/pbx.h>
  97. #include <asterisk/module.h>
  98. #include <asterisk/translate.h>
  99. #include <asterisk/options.h>
  100. #include <asterisk/config.h>
  101. #include <asterisk/say.h>
  102. #include <asterisk/localtime.h>
  103. #include <stdio.h>
  104. #include <unistd.h>
  105. #include <string.h>
  106. #include <stdlib.h>
  107. #include <search.h>
  108. #include <sys/types.h>
  109. #include <sys/stat.h>
  110. #include <errno.h>
  111. #include <dirent.h>
  112. #include <ctype.h>
  113. #include <sys/stat.h>
  114. #include <sys/time.h>
  115. #include <sys/file.h>
  116. #include <sys/ioctl.h>
  117. #include <sys/io.h>
  118. #include <math.h>
  119. #include <tonezone.h>
  120. #include <linux/zaptel.h>
  121. static char *tdesc = "Radio Repeater / Remote Base version 0.17 09/13/2004";
  122. static char *app = "Rpt";
  123. static char *synopsis = "Radio Repeater/Remote Base Control System";
  124. static char *descrip =
  125. " Rpt(sysname): Radio Remote Link or Remote Base Link Endpoint Process.\n";
  126. static int debug = 0; /* Set this >0 for extra debug output */
  127. static int nrpts = 0;
  128. struct ast_config *cfg;
  129. STANDARD_LOCAL_USER;
  130. LOCAL_USER_DECL;
  131. #define MSWAIT 200
  132. #define HANGTIME 5000
  133. #define TOTIME 180000
  134. #define IDTIME 300000
  135. #define MAXRPTS 20
  136. #define POLITEID 30000
  137. #define FUNCTDELAY 1500
  138. static pthread_t rpt_master_thread;
  139. struct rpt;
  140. struct rpt_link
  141. {
  142. struct rpt_link *next;
  143. struct rpt_link *prev;
  144. char mode; /* 1 if in tx mode */
  145. char isremote;
  146. char name[MAXNODESTR]; /* identifier (routing) string */
  147. char lasttx;
  148. char lastrx;
  149. char connected;
  150. char outbound;
  151. long elaptime;
  152. struct ast_channel *chan;
  153. struct ast_channel *pchan;
  154. } ;
  155. struct rpt_tele
  156. {
  157. struct rpt_tele *next;
  158. struct rpt_tele *prev;
  159. struct rpt *rpt;
  160. struct ast_channel *chan;
  161. int mode;
  162. struct rpt_link mylink;
  163. char param[TELEPARAMSIZE];
  164. pthread_t threadid;
  165. } ;
  166. struct function_table_tag
  167. {
  168. char action[ACTIONSIZE];
  169. int (*function)(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  170. } ;
  171. /* Used to store the morse code patterns */
  172. struct morse_bits
  173. {
  174. int len;
  175. int ddcomb;
  176. } ;
  177. struct telem_defaults
  178. {
  179. char name[20];
  180. char value[80];
  181. } ;
  182. static struct rpt
  183. {
  184. char *name;
  185. ast_mutex_t lock;
  186. char *rxchanname;
  187. char *txchanname;
  188. char *ourcontext;
  189. char *ourcallerid;
  190. char *acctcode;
  191. char *ident;
  192. char *tonezone;
  193. char *functions;
  194. char *link_functions;
  195. struct rpt_link links;
  196. int hangtime;
  197. int totime;
  198. int idtime;
  199. char exttx;
  200. char localtx;
  201. char remoterx;
  202. char remotetx;
  203. char remoteon;
  204. char simple;
  205. char *remote;
  206. char tounkeyed;
  207. char tonotify;
  208. char enable;
  209. char dtmfbuf[MAXDTMF];
  210. char rem_dtmfbuf[MAXDTMF];
  211. char cmdnode[50];
  212. struct ast_channel *rxchannel,*txchannel;
  213. struct ast_channel *pchannel,*txpchannel, *remchannel;
  214. struct rpt_tele tele;
  215. pthread_t rpt_call_thread,rpt_thread;
  216. time_t rem_dtmf_time,dtmf_time_rem;
  217. int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx;
  218. int mustid;
  219. int politeid;
  220. int dtmfidx,rem_dtmfidx;
  221. char mydtmf;
  222. int iobase;
  223. char exten[AST_MAX_EXTENSION];
  224. char freq[MAXREMSTR],rxpl[MAXREMSTR],txpl[MAXREMSTR];
  225. char offset;
  226. char powerlevel;
  227. char txplon;
  228. char rxplon;
  229. char funcchar;
  230. char endchar;
  231. int link_longestfunc;
  232. int longestfunc;
  233. int longestnode;
  234. } rpt_vars[MAXRPTS];
  235. static struct telem_defaults tele_defs[] = {
  236. {"ct1","|t(350,0,100,3072)(500,0,100,3072)(660,0,100,3072)"},
  237. {"ct2","|t(660,880,150,3072)"},
  238. {"ct3","|t(440,0,150,3072)"},
  239. {"ct4","|t(550,0,150,3072)"},
  240. {"ct5","|t(660,0,150,3072)"},
  241. {"ct6","|t(880,0,150,3072)"},
  242. {"ct7","|t(660,440,150,3072)"},
  243. {"ct8","|t(700,1100,150,3072)"},
  244. {"remotemon","|t(1600,0,75,2048)"},
  245. {"remotetx","|t(2000,0,75,2048)(0,0,75,0)(1600,0,75,2048)"},
  246. {"cmdmode","|t(900,904,200,2048)"},
  247. {"functcomplete","|t(1000,0,100,2048)(0,0,100,0)(1000,0,100,2048)"}
  248. } ;
  249. /*
  250. * Forward decl's - these suppress compiler warnings when funcs coded further down the file than thier invokation
  251. */
  252. static int setrbi(struct rpt *myrpt);
  253. /*
  254. * Define function protos for function table here
  255. */
  256. static int function_ilink(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  257. static int function_autopatchup(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  258. static int function_autopatchdn(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  259. static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  260. static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  261. static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source);
  262. /*
  263. * Function table
  264. */
  265. static struct function_table_tag function_table[] = {
  266. {"cop", function_cop},
  267. {"autopatchup", function_autopatchup},
  268. {"autopatchdn", function_autopatchdn},
  269. {"ilink", function_ilink},
  270. {"status", function_status},
  271. {"remote", function_remote}
  272. } ;
  273. static int myatoi(char *str)
  274. {
  275. int ret;
  276. if (str == NULL) return -1;
  277. if (sscanf(str,"%i",&ret) != 1) return -1;
  278. return ret;
  279. }
  280. static int play_tone_pair(struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
  281. {
  282. return ast_tonepair(chan, f1, f2, duration, amplitude);
  283. }
  284. static int play_tone(struct ast_channel *chan, int freq, int duration, int amplitude)
  285. {
  286. return play_tone_pair(chan, freq, 0, duration, amplitude);
  287. }
  288. static int play_silence(struct ast_channel *chan, int duration)
  289. {
  290. return play_tone_pair(chan, 0, 0, duration, 0);
  291. }
  292. static int send_morse(struct ast_channel *chan, char *string, int speed, int freq, int amplitude)
  293. {
  294. static struct morse_bits mbits[] = {
  295. {0, 0}, /* SPACE */
  296. {0, 0},
  297. {6, 18},/* " */
  298. {0, 0},
  299. {7, 72},/* $ */
  300. {0, 0},
  301. {0, 0},
  302. {6, 30},/* ' */
  303. {5, 13},/* ( */
  304. {6, 29},/* ) */
  305. {0, 0},
  306. {5, 10},/* + */
  307. {6, 51},/* , */
  308. {6, 33},/* - */
  309. {6, 42},/* . */
  310. {5, 9}, /* / */
  311. {5, 31},/* 0 */
  312. {5, 30},/* 1 */
  313. {5, 28},/* 2 */
  314. {5, 24},/* 3 */
  315. {5, 16},/* 4 */
  316. {5, 0}, /* 5 */
  317. {5, 1}, /* 6 */
  318. {5, 3}, /* 7 */
  319. {5, 7}, /* 8 */
  320. {5, 15},/* 9 */
  321. {6, 7}, /* : */
  322. {6, 21},/* ; */
  323. {0, 0},
  324. {5, 33},/* = */
  325. {0, 0},
  326. {6, 12},/* ? */
  327. {0, 0},
  328. {2, 2}, /* A */
  329. {4, 1}, /* B */
  330. {4, 5}, /* C */
  331. {3, 1}, /* D */
  332. {1, 0}, /* E */
  333. {4, 4}, /* F */
  334. {3, 3}, /* G */
  335. {4, 0}, /* H */
  336. {2, 0}, /* I */
  337. {4, 14},/* J */
  338. {3, 5}, /* K */
  339. {4, 2}, /* L */
  340. {2, 3}, /* M */
  341. {2, 1}, /* N */
  342. {3, 7}, /* O */
  343. {4, 6}, /* P */
  344. {4, 11},/* Q */
  345. {3, 2}, /* R */
  346. {3, 0}, /* S */
  347. {1, 1}, /* T */
  348. {3, 4}, /* U */
  349. {4, 8}, /* V */
  350. {3, 6}, /* W */
  351. {4, 9}, /* X */
  352. {4, 13},/* Y */
  353. {4, 3} /* Z */
  354. };
  355. int dottime;
  356. int dashtime;
  357. int intralettertime;
  358. int interlettertime;
  359. int interwordtime;
  360. int len, ddcomb;
  361. int res;
  362. int c;
  363. res = 0;
  364. /* Approximate the dot time from the speed arg. */
  365. dottime = 900/speed;
  366. /* Establish timing releationships */
  367. dashtime = 3 * dottime;
  368. intralettertime = dottime;
  369. interlettertime = dottime * 4 ;
  370. interwordtime = dottime * 7;
  371. for(;(*string) && (!res); string++){
  372. c = *string;
  373. /* Convert lower case to upper case */
  374. if((c >= 'a') && (c <= 'z'))
  375. c -= 0x20;
  376. /* Can't deal with any char code greater than Z, skip it */
  377. if(c > 'Z')
  378. continue;
  379. /* If space char, wait the inter word time */
  380. if(c == ' '){
  381. if(!res)
  382. res = play_silence(chan, interwordtime);
  383. continue;
  384. }
  385. /* Subtract out control char offset to match our table */
  386. c -= 0x20;
  387. /* Get the character data */
  388. len = mbits[c].len;
  389. ddcomb = mbits[c].ddcomb;
  390. /* Send the character */
  391. for(; len ; len--){
  392. if(!res)
  393. res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
  394. if(!res)
  395. res = play_silence(chan, intralettertime);
  396. ddcomb >>= 1;
  397. }
  398. /* Wait the interletter time */
  399. if(!res)
  400. res = play_silence(chan, interlettertime - intralettertime);
  401. }
  402. /* Wait for all the frames to be sent */
  403. if (!res)
  404. res = ast_waitstream(chan, "");
  405. ast_stopstream(chan);
  406. return res;
  407. }
  408. static int send_tone_telemetry(struct ast_channel *chan, char *tonestring)
  409. {
  410. char *stringp;
  411. char *tonesubset;
  412. int f1,f2;
  413. int duration;
  414. int amplitude;
  415. int res;
  416. res = 0;
  417. stringp = ast_strdupa(tonestring);
  418. for(;tonestring;){
  419. tonesubset = strsep(&stringp,")");
  420. if(!tonesubset)
  421. break;
  422. if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &amplitude) != 4)
  423. break;
  424. res = play_tone_pair(chan, f1, f2, duration, amplitude);
  425. if(res)
  426. break;
  427. }
  428. if(!res)
  429. res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
  430. if (!res)
  431. res = ast_waitstream(chan, "");
  432. ast_stopstream(chan);
  433. return res;
  434. }
  435. static int sayfile(struct ast_channel *mychannel,char *fname)
  436. {
  437. int res;
  438. res = ast_streamfile(mychannel, fname, mychannel->language);
  439. if (!res)
  440. res = ast_waitstream(mychannel, "");
  441. else
  442. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  443. ast_stopstream(mychannel);
  444. return res;
  445. }
  446. static int saycharstr(struct ast_channel *mychannel,char *str)
  447. {
  448. int res;
  449. res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
  450. if (!res)
  451. res = ast_waitstream(mychannel, "");
  452. else
  453. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  454. ast_stopstream(mychannel);
  455. return res;
  456. }
  457. /* Retrieve an int from a config file */
  458. static int retrieve_astcfgint(char *category, char *name, int min, int max, int defl)
  459. {
  460. char *var;
  461. int ret;
  462. var = ast_variable_retrieve(cfg, category, name);
  463. if(var){
  464. ret = myatoi(var);
  465. if(ret < min)
  466. ret = min;
  467. if(ret > max)
  468. ret = max;
  469. }
  470. else
  471. ret = defl;
  472. return ret;
  473. }
  474. static int telem_any(struct ast_channel *chan, char *entry)
  475. {
  476. int res;
  477. char c;
  478. static int morsespeed;
  479. static int morsefreq;
  480. static int morseampl;
  481. static int morseidfreq = 0;
  482. static int morseidampl;
  483. static char mcat[] = MORSE;
  484. res = 0;
  485. if(!morseidfreq){ /* Get the morse parameters if not already loaded */
  486. morsespeed = retrieve_astcfgint( mcat, "speed", 5, 20, 20);
  487. morsefreq = retrieve_astcfgint( mcat, "frequency", 300, 3000, 800);
  488. morseampl = retrieve_astcfgint( mcat, "amplitude", 200, 8192, 4096);
  489. morseidampl = retrieve_astcfgint( mcat, "idamplitude", 200, 8192, 2048);
  490. morseidfreq = retrieve_astcfgint( mcat, "idfrequency", 300, 3000, 330);
  491. }
  492. /* Is it a file, or a tone sequence? */
  493. if(entry[0] == '|'){
  494. c = entry[1];
  495. if((c >= 'a')&&(c <= 'z'))
  496. c -= 0x20;
  497. switch(c){
  498. case 'I': /* Morse ID */
  499. res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
  500. break;
  501. case 'M': /* Morse Message */
  502. res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
  503. break;
  504. case 'T': /* Tone sequence */
  505. res = send_tone_telemetry(chan, entry + 2);
  506. break;
  507. default:
  508. res = -1;
  509. }
  510. }
  511. else
  512. res = sayfile(chan, entry); /* File */
  513. return res;
  514. }
  515. /*
  516. * This function looks up a telemetry name in the config file, and does a telemetry response as configured.
  517. *
  518. * 4 types of telemtry are handled: Morse ID, Morse Message, Tone Sequence, and a File containing a recording.
  519. */
  520. static int telem_lookup(struct ast_channel *chan, char *node, char *name)
  521. {
  522. int res;
  523. int i;
  524. char *entry;
  525. char *telemetry;
  526. char *telemetry_save;
  527. res = 0;
  528. telemetry_save = NULL;
  529. entry = NULL;
  530. /* Retrieve the section name for telemetry from the node section */
  531. telemetry = ast_variable_retrieve(cfg, node, TELEMETRY);
  532. if(telemetry){
  533. telemetry_save = ast_strdupa(telemetry);
  534. if(!telemetry_save){
  535. ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
  536. return res;
  537. }
  538. entry = ast_variable_retrieve(cfg, telemetry_save, name);
  539. }
  540. /* Try to look up the telemetry name */
  541. if(!entry){
  542. /* Telemetry name wasn't found in the config file, use the default */
  543. for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
  544. if(!strcasecmp(tele_defs[i].name, name))
  545. entry = tele_defs[i].value;
  546. }
  547. }
  548. if(entry)
  549. telem_any(chan, entry);
  550. else{
  551. ast_log(LOG_WARNING, "Telemetry name not found: %s\n", name);
  552. res = -1;
  553. }
  554. return res;
  555. }
  556. /*
  557. * Wait a configurable interval of time
  558. */
  559. static void wait_interval(struct rpt *myrpt, int type)
  560. {
  561. int interval;
  562. char *wait_times;
  563. char *wait_times_save;
  564. wait_times_save = NULL;
  565. wait_times = ast_variable_retrieve(cfg, myrpt->name, "wait_times");
  566. if(wait_times){
  567. wait_times_save = ast_strdupa(wait_times);
  568. if(!wait_times_save){
  569. ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
  570. wait_times = NULL;
  571. }
  572. }
  573. switch(type){
  574. case DLY_TELEM:
  575. if(wait_times)
  576. interval = retrieve_astcfgint(wait_times_save, "telemwait", 500, 5000, 1000);
  577. else
  578. interval = 1000;
  579. break;
  580. case DLY_ID:
  581. if(wait_times)
  582. interval = retrieve_astcfgint(wait_times_save, "idwait",250,5000,500);
  583. else
  584. interval = 500;
  585. break;
  586. case DLY_UNKEY:
  587. if(wait_times)
  588. interval = retrieve_astcfgint(wait_times_save, "unkeywait",500,5000,1000);
  589. else
  590. interval = 1000;
  591. break;
  592. case DLY_CALLTERM:
  593. if(wait_times)
  594. interval = retrieve_astcfgint(wait_times_save, "calltermwait",500,5000,1500);
  595. else
  596. interval = 1500;
  597. break;
  598. default:
  599. return;
  600. }
  601. usleep(1000 * interval);
  602. return;
  603. }
  604. static void *rpt_tele_thread(void *this)
  605. {
  606. ZT_CONFINFO ci; /* conference info */
  607. int res = 0,hastx,imdone = 0;
  608. struct rpt_tele *mytele = (struct rpt_tele *)this;
  609. struct rpt *myrpt;
  610. struct rpt_link *l,*m,linkbase;
  611. struct ast_channel *mychannel;
  612. int vmajor, vminor;
  613. char *p,*ct,*ct_copy,*ident, *nodename;
  614. time_t t;
  615. struct tm localtm;
  616. /* get a pointer to myrpt */
  617. myrpt = mytele->rpt;
  618. /* Snag copies of a few key myrpt variables */
  619. ast_mutex_lock(&myrpt->lock);
  620. nodename = ast_strdupa(myrpt->name);
  621. ident = ast_strdupa(myrpt->ident);
  622. ast_mutex_unlock(&myrpt->lock);
  623. /* allocate a pseudo-channel thru asterisk */
  624. mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  625. if (!mychannel)
  626. {
  627. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  628. remque((struct qelem *)mytele);
  629. ast_mutex_unlock(&myrpt->lock);
  630. free(mytele);
  631. pthread_exit(NULL);
  632. }
  633. ast_mutex_lock(&myrpt->lock);
  634. mytele->chan = mychannel; /* Save a copy of the channel so we can access it externally if need be */
  635. ast_mutex_unlock(&myrpt->lock);
  636. /* make a conference for the tx */
  637. ci.chan = 0;
  638. /* If there's an ID queued, only connect the ID audio to the local tx conference so
  639. linked systems can't hear it */
  640. ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY)) ?
  641. myrpt->txconf : myrpt->conf);
  642. ci.confmode = ZT_CONF_CONFANN;
  643. /* first put the channel on the conference in announce mode */
  644. if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
  645. {
  646. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  647. ast_mutex_lock(&myrpt->lock);
  648. remque((struct qelem *)mytele);
  649. ast_mutex_unlock(&myrpt->lock);
  650. free(mytele);
  651. ast_hangup(mychannel);
  652. pthread_exit(NULL);
  653. }
  654. ast_stopstream(mychannel);
  655. switch(mytele->mode)
  656. {
  657. case ID:
  658. case ID1:
  659. /* wait a bit */
  660. wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM);
  661. res = telem_any(mychannel, ident);
  662. imdone=1;
  663. break;
  664. case IDTALKOVER:
  665. p = ast_variable_retrieve(cfg, nodename, "idtalkover");
  666. if(p)
  667. res = telem_any(mychannel, p);
  668. imdone=1;
  669. break;
  670. case PROC:
  671. /* wait a little bit longer */
  672. wait_interval(myrpt, DLY_TELEM);
  673. res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
  674. break;
  675. case TERM:
  676. /* wait a little bit longer */
  677. wait_interval(myrpt, DLY_CALLTERM);
  678. res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
  679. break;
  680. case COMPLETE:
  681. /* wait a little bit */
  682. wait_interval(myrpt, DLY_TELEM);
  683. res = telem_lookup(mychannel, myrpt->name, "functcomplete");
  684. break;
  685. case UNKEY:
  686. /* wait a little bit */
  687. wait_interval(myrpt, DLY_UNKEY);
  688. hastx = 0;
  689. l = myrpt->links.next;
  690. if (l != &myrpt->links)
  691. {
  692. ast_mutex_lock(&myrpt->lock);
  693. while(l != &myrpt->links)
  694. {
  695. if (l->mode) hastx++;
  696. l = l->next;
  697. }
  698. ast_mutex_unlock(&myrpt->lock);
  699. res = telem_lookup(mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
  700. if(res)
  701. ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
  702. /* if in remote cmd mode, indicate it */
  703. if (myrpt->cmdnode[0])
  704. {
  705. ast_safe_sleep(mychannel,200);
  706. res = telem_lookup(mychannel, myrpt->name, "cmdmode");
  707. if(res)
  708. ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
  709. ast_stopstream(mychannel);
  710. }
  711. }
  712. else if((ct = ast_variable_retrieve(cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
  713. ct_copy = ast_strdupa(ct);
  714. res = telem_lookup(mychannel, myrpt->name, ct_copy);
  715. if(res)
  716. ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
  717. }
  718. imdone = 1;
  719. break;
  720. case REMDISC:
  721. /* wait a little bit */
  722. wait_interval(myrpt, DLY_TELEM);
  723. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  724. if (!res)
  725. res = ast_waitstream(mychannel, "");
  726. else
  727. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  728. ast_stopstream(mychannel);
  729. ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
  730. res = ast_streamfile(mychannel, ((mytele->mylink.connected) ?
  731. "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language);
  732. break;
  733. case REMALREADY:
  734. /* wait a little bit */
  735. wait_interval(myrpt, DLY_TELEM);
  736. res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
  737. break;
  738. case REMNOTFOUND:
  739. /* wait a little bit */
  740. wait_interval(myrpt, DLY_TELEM);
  741. res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
  742. break;
  743. case REMGO:
  744. /* wait a little bit */
  745. wait_interval(myrpt, DLY_TELEM);
  746. res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
  747. break;
  748. case CONNECTED:
  749. /* wait a little bit */
  750. wait_interval(myrpt, DLY_TELEM);
  751. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  752. if (!res)
  753. res = ast_waitstream(mychannel, "");
  754. else
  755. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  756. ast_stopstream(mychannel);
  757. ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
  758. res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
  759. break;
  760. case CONNFAIL:
  761. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  762. if (!res)
  763. res = ast_waitstream(mychannel, "");
  764. else
  765. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  766. ast_stopstream(mychannel);
  767. ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
  768. res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language);
  769. break;
  770. case STATUS:
  771. /* wait a little bit */
  772. wait_interval(myrpt, DLY_TELEM);
  773. hastx = 0;
  774. linkbase.next = &linkbase;
  775. linkbase.prev = &linkbase;
  776. ast_mutex_lock(&myrpt->lock);
  777. /* make our own list of links */
  778. l = myrpt->links.next;
  779. while(l != &myrpt->links)
  780. {
  781. m = malloc(sizeof(struct rpt_link));
  782. if (!m)
  783. {
  784. ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
  785. pthread_exit(NULL);
  786. }
  787. memcpy(m,l,sizeof(struct rpt_link));
  788. m->next = m->prev = NULL;
  789. insque((struct qelem *)m,(struct qelem *)linkbase.next);
  790. l = l->next;
  791. }
  792. ast_mutex_unlock(&myrpt->lock);
  793. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  794. if (!res)
  795. res = ast_waitstream(mychannel, "");
  796. else
  797. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  798. ast_stopstream(mychannel);
  799. ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
  800. if (!res)
  801. res = ast_waitstream(mychannel, "");
  802. else
  803. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  804. ast_stopstream(mychannel);
  805. if (myrpt->callmode)
  806. {
  807. hastx = 1;
  808. res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
  809. if (!res)
  810. res = ast_waitstream(mychannel, "");
  811. else
  812. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  813. ast_stopstream(mychannel);
  814. }
  815. l = linkbase.next;
  816. while(l != &linkbase)
  817. {
  818. hastx = 1;
  819. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  820. if (!res)
  821. res = ast_waitstream(mychannel, "");
  822. else
  823. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  824. ast_stopstream(mychannel);
  825. ast_say_character_str(mychannel,l->name,NULL,mychannel->language);
  826. if (!res)
  827. res = ast_waitstream(mychannel, "");
  828. else
  829. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  830. ast_stopstream(mychannel);
  831. res = ast_streamfile(mychannel, ((l->mode) ?
  832. "rpt/tranceive" : "rpt/monitor"), mychannel->language);
  833. if (!res)
  834. res = ast_waitstream(mychannel, "");
  835. else
  836. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  837. ast_stopstream(mychannel);
  838. l = l->next;
  839. }
  840. if (!hastx)
  841. {
  842. res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
  843. if (!res)
  844. res = ast_waitstream(mychannel, "");
  845. else
  846. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  847. ast_stopstream(mychannel);
  848. }
  849. /* destroy our local link queue */
  850. l = linkbase.next;
  851. while(l != &linkbase)
  852. {
  853. m = l;
  854. l = l->next;
  855. remque((struct qelem *)m);
  856. free(m);
  857. }
  858. imdone = 1;
  859. break;
  860. case TIMEOUT:
  861. res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
  862. if (!res)
  863. res = ast_waitstream(mychannel, "");
  864. else
  865. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  866. ast_stopstream(mychannel);
  867. ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
  868. res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
  869. break;
  870. case STATS_TIME:
  871. wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
  872. t = time(NULL);
  873. localtime_r(&t, &localtm);
  874. /* Say the phase of the day is before the time */
  875. if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
  876. p = "rpt/goodmorning";
  877. else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
  878. p = "rpt/goodafternoon";
  879. else
  880. p = "rpt/goodevening";
  881. if (sayfile(mychannel,p) == -1)
  882. {
  883. imdone = 1;
  884. break;
  885. }
  886. /* Say the time is ... */
  887. if (sayfile(mychannel,"rpt/thetimeis") == -1)
  888. {
  889. imdone = 1;
  890. break;
  891. }
  892. /* Say the time */
  893. res = ast_say_time(mychannel, t, "", mychannel->language);
  894. if (!res)
  895. res = ast_waitstream(mychannel, "");
  896. ast_stopstream(mychannel);
  897. imdone = 1;
  898. break;
  899. case STATS_VERSION:
  900. p = strstr(tdesc, "version");
  901. if(!p)
  902. break;
  903. if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
  904. break;
  905. wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
  906. /* Say "version" */
  907. if (sayfile(mychannel,"rpt/version") == -1)
  908. {
  909. imdone = 1;
  910. break;
  911. }
  912. if(!res) /* Say "X" */
  913. ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
  914. if (!res)
  915. res = ast_waitstream(mychannel, "");
  916. ast_stopstream(mychannel);
  917. if (saycharstr(mychannel,".") == -1)
  918. {
  919. imdone = 1;
  920. break;
  921. }
  922. if(!res) /* Say "Y" */
  923. ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
  924. if (!res){
  925. res = ast_waitstream(mychannel, "");
  926. ast_stopstream(mychannel);
  927. }
  928. else
  929. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  930. imdone = 1;
  931. break;
  932. case ARB_ALPHA:
  933. wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
  934. if(mytele->param)
  935. saycharstr(mychannel, mytele->param);
  936. imdone = 1;
  937. break;
  938. default:
  939. break;
  940. }
  941. if (!imdone)
  942. {
  943. if (!res)
  944. res = ast_waitstream(mychannel, "");
  945. else {
  946. ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
  947. res = 0;
  948. }
  949. }
  950. ast_stopstream(mychannel);
  951. ast_mutex_lock(&myrpt->lock);
  952. remque((struct qelem *)mytele);
  953. ast_mutex_unlock(&myrpt->lock);
  954. free(mytele);
  955. ast_hangup(mychannel);
  956. pthread_exit(NULL);
  957. }
  958. static void rpt_telemetry(struct rpt *myrpt,int mode, void *data)
  959. {
  960. struct rpt_tele *tele;
  961. struct rpt_link *mylink = (struct rpt_link *) data;
  962. pthread_attr_t attr;
  963. tele = malloc(sizeof(struct rpt_tele));
  964. if (!tele)
  965. {
  966. ast_log(LOG_WARNING, "Unable to allocate memory\n");
  967. pthread_exit(NULL);
  968. return;
  969. }
  970. /* zero it out */
  971. memset((char *)tele,0,sizeof(struct rpt_tele));
  972. tele->rpt = myrpt;
  973. tele->mode = mode;
  974. ast_mutex_lock(&myrpt->lock);
  975. if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED)){
  976. memset(&tele->mylink,0,sizeof(struct rpt_link));
  977. if (mylink){
  978. memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
  979. }
  980. }
  981. else if (mode == ARB_ALPHA){
  982. strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
  983. tele->param[TELEPARAMSIZE - 1] = 0;
  984. }
  985. insque((struct qelem *)tele,(struct qelem *)myrpt->tele.next);
  986. ast_mutex_unlock(&myrpt->lock);
  987. pthread_attr_init(&attr);
  988. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  989. ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
  990. return;
  991. }
  992. static void *rpt_call(void *this)
  993. {
  994. ZT_CONFINFO ci; /* conference info */
  995. struct rpt *myrpt = (struct rpt *)this;
  996. int res;
  997. struct ast_frame *f,wf;
  998. int stopped,congstarted;
  999. struct ast_channel *mychannel,*genchannel;
  1000. myrpt->mydtmf = 0;
  1001. /* allocate a pseudo-channel thru asterisk */
  1002. mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  1003. if (!mychannel)
  1004. {
  1005. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  1006. pthread_exit(NULL);
  1007. }
  1008. ci.chan = 0;
  1009. ci.confno = myrpt->conf; /* use the pseudo conference */
  1010. ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
  1011. | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
  1012. /* first put the channel on the conference */
  1013. if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
  1014. {
  1015. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  1016. ast_hangup(mychannel);
  1017. myrpt->callmode = 0;
  1018. pthread_exit(NULL);
  1019. }
  1020. /* allocate a pseudo-channel thru asterisk */
  1021. genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  1022. if (!genchannel)
  1023. {
  1024. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  1025. ast_hangup(mychannel);
  1026. pthread_exit(NULL);
  1027. }
  1028. ci.chan = 0;
  1029. ci.confno = myrpt->conf;
  1030. ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
  1031. | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
  1032. /* first put the channel on the conference */
  1033. if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1)
  1034. {
  1035. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  1036. ast_hangup(mychannel);
  1037. ast_hangup(genchannel);
  1038. myrpt->callmode = 0;
  1039. pthread_exit(NULL);
  1040. }
  1041. if (myrpt->tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->tonezone) == -1))
  1042. {
  1043. ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone);
  1044. ast_hangup(mychannel);
  1045. ast_hangup(genchannel);
  1046. myrpt->callmode = 0;
  1047. pthread_exit(NULL);
  1048. }
  1049. if (myrpt->tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->tonezone) == -1))
  1050. {
  1051. ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone);
  1052. ast_hangup(mychannel);
  1053. ast_hangup(genchannel);
  1054. myrpt->callmode = 0;
  1055. pthread_exit(NULL);
  1056. }
  1057. /* start dialtone */
  1058. if (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0)
  1059. {
  1060. ast_log(LOG_WARNING, "Cannot start dialtone\n");
  1061. ast_hangup(mychannel);
  1062. ast_hangup(genchannel);
  1063. myrpt->callmode = 0;
  1064. pthread_exit(NULL);
  1065. }
  1066. stopped = 0;
  1067. congstarted = 0;
  1068. while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
  1069. {
  1070. if ((myrpt->callmode == 1) && (myrpt->cidx > 0) && (!stopped))
  1071. {
  1072. stopped = 1;
  1073. /* stop dial tone */
  1074. tone_zone_play_tone(mychannel->fds[0],-1);
  1075. }
  1076. if ((myrpt->callmode == 4) && (!congstarted))
  1077. {
  1078. congstarted = 1;
  1079. /* start congestion tone */
  1080. tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION);
  1081. }
  1082. res = ast_waitfor(mychannel, MSWAIT);
  1083. if (res < 0)
  1084. {
  1085. ast_hangup(mychannel);
  1086. ast_hangup(genchannel);
  1087. ast_mutex_lock(&myrpt->lock);
  1088. myrpt->callmode = 0;
  1089. ast_mutex_unlock(&myrpt->lock);
  1090. pthread_exit(NULL);
  1091. }
  1092. if (res == 0) continue;
  1093. f = ast_read(mychannel);
  1094. if (f == NULL)
  1095. {
  1096. ast_hangup(mychannel);
  1097. ast_hangup(genchannel);
  1098. ast_mutex_lock(&myrpt->lock);
  1099. myrpt->callmode = 0;
  1100. ast_mutex_unlock(&myrpt->lock);
  1101. pthread_exit(NULL);
  1102. }
  1103. if ((f->frametype == AST_FRAME_CONTROL) &&
  1104. (f->subclass == AST_CONTROL_HANGUP))
  1105. {
  1106. ast_frfree(f);
  1107. ast_hangup(mychannel);
  1108. ast_hangup(genchannel);
  1109. ast_mutex_lock(&myrpt->lock);
  1110. myrpt->callmode = 0;
  1111. ast_mutex_unlock(&myrpt->lock);
  1112. pthread_exit(NULL);
  1113. }
  1114. ast_frfree(f);
  1115. }
  1116. /* stop any tone generation */
  1117. tone_zone_play_tone(mychannel->fds[0],-1);
  1118. /* end if done */
  1119. if (!myrpt->callmode)
  1120. {
  1121. ast_hangup(mychannel);
  1122. ast_hangup(genchannel);
  1123. ast_mutex_lock(&myrpt->lock);
  1124. myrpt->callmode = 0;
  1125. ast_mutex_unlock(&myrpt->lock);
  1126. pthread_exit(NULL);
  1127. }
  1128. if (myrpt->ourcallerid && *myrpt->ourcallerid)
  1129. {
  1130. if (mychannel->callerid) free(mychannel->callerid);
  1131. mychannel->callerid = strdup(myrpt->ourcallerid);
  1132. }
  1133. strncpy(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
  1134. strncpy(mychannel->context, myrpt->ourcontext, sizeof(mychannel->context) - 1);
  1135. if (myrpt->acctcode)
  1136. strncpy(mychannel->accountcode, myrpt->acctcode, sizeof(mychannel->accountcode) - 1);
  1137. mychannel->priority = 1;
  1138. ast_channel_undefer_dtmf(mychannel);
  1139. if (ast_pbx_start(mychannel) < 0)
  1140. {
  1141. ast_log(LOG_WARNING, "Unable to start PBX!!\n");
  1142. ast_hangup(mychannel);
  1143. ast_hangup(genchannel);
  1144. ast_mutex_lock(&myrpt->lock);
  1145. myrpt->callmode = 0;
  1146. ast_mutex_unlock(&myrpt->lock);
  1147. pthread_exit(NULL);
  1148. }
  1149. ast_mutex_lock(&myrpt->lock);
  1150. myrpt->callmode = 3;
  1151. while(myrpt->callmode)
  1152. {
  1153. if ((!mychannel->pvt) && (myrpt->callmode != 4))
  1154. {
  1155. myrpt->callmode = 4;
  1156. ast_mutex_unlock(&myrpt->lock);
  1157. /* start congestion tone */
  1158. tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION);
  1159. ast_mutex_lock(&myrpt->lock);
  1160. }
  1161. if (myrpt->mydtmf)
  1162. {
  1163. wf.frametype = AST_FRAME_DTMF;
  1164. wf.subclass = myrpt->mydtmf;
  1165. wf.offset = 0;
  1166. wf.mallocd = 0;
  1167. wf.data = NULL;
  1168. wf.datalen = 0;
  1169. wf.samples = 0;
  1170. ast_mutex_unlock(&myrpt->lock);
  1171. ast_write(genchannel,&wf);
  1172. ast_mutex_lock(&myrpt->lock);
  1173. myrpt->mydtmf = 0;
  1174. }
  1175. ast_mutex_unlock(&myrpt->lock);
  1176. usleep(25000);
  1177. ast_mutex_lock(&myrpt->lock);
  1178. }
  1179. ast_mutex_unlock(&myrpt->lock);
  1180. tone_zone_play_tone(genchannel->fds[0],-1);
  1181. if (mychannel->pvt) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
  1182. ast_hangup(genchannel);
  1183. ast_mutex_lock(&myrpt->lock);
  1184. myrpt->callmode = 0;
  1185. ast_mutex_unlock(&myrpt->lock);
  1186. pthread_exit(NULL);
  1187. }
  1188. static void send_link_dtmf(struct rpt *myrpt,char c)
  1189. {
  1190. char str[300];
  1191. struct ast_frame wf;
  1192. struct rpt_link *l;
  1193. snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c);
  1194. wf.frametype = AST_FRAME_TEXT;
  1195. wf.subclass = 0;
  1196. wf.offset = 0;
  1197. wf.mallocd = 1;
  1198. wf.datalen = strlen(str) + 1;
  1199. wf.samples = 0;
  1200. l = myrpt->links.next;
  1201. /* first, see if our dude is there */
  1202. while(l != &myrpt->links)
  1203. {
  1204. /* if we found it, write it and were done */
  1205. if (!strcmp(l->name,myrpt->cmdnode))
  1206. {
  1207. wf.data = strdup(str);
  1208. ast_write(l->chan,&wf);
  1209. return;
  1210. }
  1211. l = l->next;
  1212. }
  1213. l = myrpt->links.next;
  1214. /* if not, give it to everyone */
  1215. while(l != &myrpt->links)
  1216. {
  1217. wf.data = strdup(str);
  1218. ast_write(l->chan,&wf);
  1219. l = l->next;
  1220. }
  1221. return;
  1222. }
  1223. /*
  1224. * Internet linking function
  1225. */
  1226. static int function_ilink(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1227. {
  1228. char *val, *s, *s1, *tele;
  1229. char tmp[300], deststr[300] = "";
  1230. struct rpt_link *l;
  1231. ZT_CONFINFO ci; /* conference info */
  1232. if(!param)
  1233. return DC_ERROR;
  1234. if (!myrpt->enable)
  1235. return DC_ERROR;
  1236. if(debug)
  1237. printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
  1238. switch(myatoi(param)){
  1239. case 1: /* Link off */
  1240. val = ast_variable_retrieve(cfg, NODES, digitbuf);
  1241. if (!val){
  1242. if(strlen(digitbuf) >= myrpt->longestnode)
  1243. return DC_ERROR;
  1244. break;
  1245. }
  1246. strncpy(tmp,val,sizeof(tmp) - 1);
  1247. s = tmp;
  1248. s1 = strsep(&s,",");
  1249. ast_mutex_lock(&myrpt->lock);
  1250. l = myrpt->links.next;
  1251. /* try to find this one in queue */
  1252. while(l != &myrpt->links){
  1253. /* if found matching string */
  1254. if (!strcmp(l->name, digitbuf))
  1255. break;
  1256. l = l->next;
  1257. }
  1258. if (l != &myrpt->links){ /* if found */
  1259. ast_mutex_unlock(&myrpt->lock);
  1260. ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
  1261. rpt_telemetry(myrpt, COMPLETE, NULL);
  1262. return DC_COMPLETE;
  1263. }
  1264. ast_mutex_unlock(&myrpt->lock);
  1265. return DC_COMPLETE;
  1266. case 2: /* Link Monitor */
  1267. val = ast_variable_retrieve(cfg, NODES, digitbuf);
  1268. if (!val){
  1269. if(strlen(digitbuf) >= myrpt->longestnode)
  1270. return DC_ERROR;
  1271. break;
  1272. }
  1273. strncpy(tmp,val,sizeof(tmp) - 1);
  1274. s = tmp;
  1275. s1 = strsep(&s,",");
  1276. ast_mutex_lock(&myrpt->lock);
  1277. l = myrpt->links.next;
  1278. /* try to find this one in queue */
  1279. while(l != &myrpt->links){
  1280. /* if found matching string */
  1281. if (!strcmp(l->name, digitbuf))
  1282. break;
  1283. l = l->next;
  1284. }
  1285. /* if found */
  1286. if (l != &myrpt->links)
  1287. {
  1288. /* if already in this mode, just ignore */
  1289. if (!l->mode) {
  1290. ast_mutex_unlock(&myrpt->lock);
  1291. rpt_telemetry(myrpt,REMALREADY,NULL);
  1292. return DC_COMPLETE;
  1293. }
  1294. ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
  1295. }
  1296. ast_mutex_unlock(&myrpt->lock);
  1297. /* establish call in monitor mode */
  1298. l = malloc(sizeof(struct rpt_link));
  1299. if (!l){
  1300. ast_log(LOG_WARNING, "Unable to malloc\n");
  1301. pthread_exit(NULL);
  1302. }
  1303. /* zero the silly thing */
  1304. memset((char *)l,0,sizeof(struct rpt_link));
  1305. snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
  1306. tele = strchr(deststr,'/');
  1307. if (!tele){
  1308. fprintf(stderr,"link2:Dial number (%s) must be in format tech/number\n",deststr);
  1309. pthread_exit(NULL);
  1310. }
  1311. *tele++ = 0;
  1312. l->isremote = (s && ast_true(s));
  1313. strncpy(l->name, digitbuf, MAXNODESTR - 1);
  1314. l->chan = ast_request(deststr,AST_FORMAT_SLINEAR,tele);
  1315. if (l->chan){
  1316. ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
  1317. ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
  1318. l->chan->whentohangup = 0;
  1319. l->chan->appl = "Apprpt";
  1320. l->chan->data = "(Remote Rx)";
  1321. if (option_verbose > 2)
  1322. ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n",
  1323. deststr,tele,l->chan->name);
  1324. l->chan->callerid = strdup(myrpt->name);
  1325. ast_call(l->chan,tele,0);
  1326. }
  1327. else
  1328. {
  1329. free(l);
  1330. if (option_verbose > 2)
  1331. ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
  1332. deststr,tele,l->chan->name);
  1333. return DC_ERROR;
  1334. }
  1335. /* allocate a pseudo-channel thru asterisk */
  1336. l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  1337. if (!l->pchan){
  1338. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  1339. pthread_exit(NULL);
  1340. }
  1341. ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
  1342. ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
  1343. /* make a conference for the pseudo-one */
  1344. ci.chan = 0;
  1345. ci.confno = myrpt->conf;
  1346. ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
  1347. /* first put the channel on the conference in proper mode */
  1348. if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1)
  1349. {
  1350. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  1351. pthread_exit(NULL);
  1352. }
  1353. ast_mutex_lock(&myrpt->lock);
  1354. /* insert at end of queue */
  1355. insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
  1356. ast_mutex_unlock(&myrpt->lock);
  1357. rpt_telemetry(myrpt,COMPLETE,NULL);
  1358. return DC_COMPLETE;
  1359. case 3: /* Link transceive */
  1360. val = ast_variable_retrieve(cfg, NODES, digitbuf);
  1361. if (!val){
  1362. if(strlen(digitbuf) >= myrpt->longestnode)
  1363. return DC_ERROR;
  1364. break;
  1365. }
  1366. strncpy(tmp,val,sizeof(tmp) - 1);
  1367. s = tmp;
  1368. s1 = strsep(&s,",");
  1369. ast_mutex_lock(&myrpt->lock);
  1370. l = myrpt->links.next;
  1371. /* try to find this one in queue */
  1372. while(l != &myrpt->links){
  1373. /* if found matching string */
  1374. if (!strcmp(l->name, digitbuf))
  1375. break;
  1376. l = l->next;
  1377. }
  1378. /* if found */
  1379. if (l != &myrpt->links){
  1380. /* if already in this mode, just ignore */
  1381. if (l->mode){
  1382. ast_mutex_unlock(&myrpt->lock);
  1383. rpt_telemetry(myrpt, REMALREADY, NULL);
  1384. return DC_COMPLETE;
  1385. }
  1386. ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
  1387. }
  1388. ast_mutex_unlock(&myrpt->lock);
  1389. /* establish call in tranceive mode */
  1390. l = malloc(sizeof(struct rpt_link));
  1391. if (!l){
  1392. ast_log(LOG_WARNING, "Unable to malloc\n");
  1393. pthread_exit(NULL);
  1394. }
  1395. /* zero the silly thing */
  1396. memset((char *)l,0,sizeof(struct rpt_link));
  1397. l->mode = 1;
  1398. strncpy(l->name, digitbuf, MAXNODESTR - 1);
  1399. l->isremote = (s && ast_true(s));
  1400. snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
  1401. tele = strchr(deststr, '/');
  1402. if (!tele){
  1403. fprintf(stderr,"link3:Dial number (%s) must be in format tech/number\n",deststr);
  1404. pthread_exit(NULL);
  1405. }
  1406. *tele++ = 0;
  1407. l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele);
  1408. if (l->chan){
  1409. ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
  1410. ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
  1411. l->chan->whentohangup = 0;
  1412. l->chan->appl = "Apprpt";
  1413. l->chan->data = "(Remote Rx)";
  1414. if (option_verbose > 2)
  1415. ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n",
  1416. deststr, tele, l->chan->name);
  1417. l->chan->callerid = strdup(myrpt->name);
  1418. ast_call(l->chan,tele,999);
  1419. }
  1420. else{
  1421. free(l);
  1422. if (option_verbose > 2)
  1423. ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
  1424. deststr,tele,l->chan->name);
  1425. return DC_ERROR;
  1426. }
  1427. /* allocate a pseudo-channel thru asterisk */
  1428. l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  1429. if (!l->pchan){
  1430. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  1431. pthread_exit(NULL);
  1432. }
  1433. ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
  1434. ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
  1435. /* make a conference for the tx */
  1436. ci.chan = 0;
  1437. ci.confno = myrpt->conf;
  1438. ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
  1439. /* first put the channel on the conference in proper mode */
  1440. if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1)
  1441. {
  1442. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  1443. pthread_exit(NULL);
  1444. }
  1445. ast_mutex_lock(&myrpt->lock);
  1446. /* insert at end of queue */
  1447. insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
  1448. ast_mutex_unlock(&myrpt->lock);
  1449. rpt_telemetry(myrpt,COMPLETE,NULL);
  1450. return DC_COMPLETE;
  1451. case 4: /* Enter Command Mode */
  1452. /* if doesnt allow link cmd, or no links active, return */
  1453. if ((command_source != SOURCE_RPT) || (myrpt->links.next == &myrpt->links))
  1454. return DC_COMPLETE;
  1455. /* if already in cmd mode, or selected self, fughetabahtit */
  1456. if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
  1457. rpt_telemetry(myrpt, REMALREADY, NULL);
  1458. return DC_COMPLETE;
  1459. }
  1460. /* node must at least exist in list */
  1461. val = ast_variable_retrieve(cfg, NODES, digitbuf);
  1462. if (!val){
  1463. if(strlen(digitbuf) >= myrpt->longestnode)
  1464. return DC_ERROR;
  1465. break;
  1466. }
  1467. ast_mutex_lock(&myrpt->lock);
  1468. strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
  1469. ast_mutex_unlock(&myrpt->lock);
  1470. rpt_telemetry(myrpt, REMGO, NULL);
  1471. return DC_COMPLETE;
  1472. case 5: /* Status */
  1473. rpt_telemetry(myrpt, STATUS, NULL);
  1474. return DC_COMPLETE;
  1475. case 6: /* All Links Off */
  1476. l = myrpt->links.next;
  1477. while(l != &myrpt->links){
  1478. ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); /* Hang 'em up */
  1479. l = l->next;
  1480. }
  1481. rpt_telemetry(myrpt, COMPLETE, NULL);
  1482. break;
  1483. default:
  1484. return DC_ERROR;
  1485. }
  1486. return DC_INDETERMINATE;
  1487. }
  1488. /*
  1489. * Autopatch up
  1490. */
  1491. static int function_autopatchup(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1492. {
  1493. pthread_attr_t attr;
  1494. if (!myrpt->enable)
  1495. return DC_ERROR;
  1496. if(debug)
  1497. printf("@@@@ Autopatch up\n");
  1498. ast_mutex_lock(&myrpt->lock);
  1499. /* if on call, force * into current audio stream */
  1500. if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
  1501. myrpt->mydtmf = myrpt->funcchar;
  1502. ast_mutex_unlock(&myrpt->lock);
  1503. }
  1504. if (myrpt->callmode){
  1505. ast_mutex_unlock(&myrpt->lock);
  1506. return DC_COMPLETE;
  1507. }
  1508. myrpt->callmode = 1;
  1509. myrpt->cidx = 0;
  1510. myrpt->exten[myrpt->cidx] = 0;
  1511. ast_mutex_unlock(&myrpt->lock);
  1512. pthread_attr_init(&attr);
  1513. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  1514. ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
  1515. return DC_COMPLETE;
  1516. }
  1517. /*
  1518. * Autopatch down
  1519. */
  1520. static int function_autopatchdn(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1521. {
  1522. if (!myrpt->enable)
  1523. return DC_ERROR;
  1524. if(debug)
  1525. printf("@@@@ Autopatch down\n");
  1526. ast_mutex_lock(&myrpt->lock);
  1527. if (!myrpt->callmode){
  1528. ast_mutex_unlock(&myrpt->lock);
  1529. return DC_COMPLETE;
  1530. }
  1531. myrpt->callmode = 0;
  1532. ast_mutex_unlock(&myrpt->lock);
  1533. rpt_telemetry(myrpt, TERM, NULL);
  1534. return DC_COMPLETE;
  1535. }
  1536. /*
  1537. * Status
  1538. */
  1539. static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1540. {
  1541. if(!param)
  1542. return DC_ERROR;
  1543. if (!myrpt->enable)
  1544. return DC_ERROR;
  1545. if(debug)
  1546. printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
  1547. switch(myatoi(param)){
  1548. case 1: /* System ID */
  1549. rpt_telemetry(myrpt, ID1, NULL);
  1550. return DC_COMPLETE;
  1551. case 2: /* System Time */
  1552. rpt_telemetry(myrpt, STATS_TIME, NULL);
  1553. return DC_COMPLETE;
  1554. case 3: /* app_rpt.c version */
  1555. rpt_telemetry(myrpt, STATS_VERSION, NULL);
  1556. default:
  1557. return DC_ERROR;
  1558. }
  1559. return DC_INDETERMINATE;
  1560. }
  1561. /*
  1562. * COP - Control operator
  1563. */
  1564. static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1565. {
  1566. if(!param)
  1567. return DC_ERROR;
  1568. switch(myatoi(param)){
  1569. case 1: /* System reset */
  1570. system("killall -9 asterisk"); /* FIXME to drastic? */
  1571. return DC_COMPLETE;
  1572. case 2:
  1573. myrpt->enable = 1;
  1574. rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
  1575. return DC_COMPLETE;
  1576. case 3:
  1577. myrpt->enable = 0;
  1578. return DC_COMPLETE;
  1579. }
  1580. return DC_INDETERMINATE;
  1581. }
  1582. /*
  1583. * Remote base function
  1584. */
  1585. static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source)
  1586. {
  1587. char *s,*s1,*s2,*val;
  1588. int i,j,k,l,res,offset,offsave;
  1589. char oc;
  1590. char tmp[20], freq[20] = "", savestr[20] = "";
  1591. struct ast_channel *mychannel;
  1592. if((!param) || (command_source != SOURCE_RMT))
  1593. return DC_ERROR;
  1594. mychannel = myrpt->remchannel;
  1595. switch(myatoi(param)){
  1596. case 1: /* retrieve memory */
  1597. if(strlen(digitbuf) < 2) /* needs 2 digits */
  1598. break;
  1599. for(i = 0 ; i < 2 ; i++){
  1600. if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
  1601. return DC_ERROR;
  1602. }
  1603. val = ast_variable_retrieve(cfg, MEMORY, digitbuf);
  1604. if (!val){
  1605. if (ast_safe_sleep(mychannel,1000) == -1)
  1606. return DC_ERROR;
  1607. sayfile(mychannel,"rpt/memory_notfound");
  1608. return DC_COMPLETE;
  1609. }
  1610. strncpy(tmp,val,sizeof(tmp) - 1);
  1611. s = strchr(tmp,',');
  1612. if (!s)
  1613. return DC_ERROR;
  1614. *s++ = 0;
  1615. s1 = strchr(s,',');
  1616. if (!s1)
  1617. return DC_ERROR;
  1618. *s1++ = 0;
  1619. strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1);
  1620. strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1);
  1621. myrpt->offset = REM_SIMPLEX;
  1622. myrpt->powerlevel = REM_MEDPWR;
  1623. myrpt->rxplon = 0;
  1624. myrpt->txplon = 0;
  1625. while(*s1)
  1626. {
  1627. switch(*s1++){
  1628. case 'L':
  1629. case 'l':
  1630. myrpt->powerlevel = REM_LOWPWR;
  1631. break;
  1632. case 'H':
  1633. case 'h':
  1634. myrpt->powerlevel = REM_HIPWR;
  1635. break;
  1636. case 'M':
  1637. case 'm':
  1638. myrpt->powerlevel = REM_MEDPWR;
  1639. break;
  1640. case '-':
  1641. myrpt->offset = REM_MINUS;
  1642. break;
  1643. case '+':
  1644. myrpt->offset = REM_PLUS;
  1645. break;
  1646. case 'S':
  1647. case 's':
  1648. myrpt->offset = REM_SIMPLEX;
  1649. break;
  1650. case 'T':
  1651. case 't':
  1652. myrpt->txplon = 1;
  1653. break;
  1654. case 'R':
  1655. case 'r':
  1656. myrpt->rxplon = 1;
  1657. break;
  1658. }
  1659. }
  1660. if (setrbi(myrpt) == -1)
  1661. return DC_ERROR;
  1662. return DC_COMPLETE;
  1663. case 2: /* set freq + offset */
  1664. for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N+*N */
  1665. if(digitbuf[i] == '*'){
  1666. j++;
  1667. continue;
  1668. }
  1669. if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
  1670. return DC_ERROR;
  1671. else{
  1672. if(j == 0)
  1673. l++;
  1674. if(j == 1)
  1675. k++;
  1676. }
  1677. }
  1678. i = strlen(digitbuf) - 1;
  1679. if((j > 2) || (l > 5) || (k > 3))
  1680. return DC_ERROR; /* &$@^! */
  1681. if((j < 2) || (digitbuf[i] == '*'))
  1682. break; /* Not yet */
  1683. strncpy(tmp, digitbuf ,sizeof(tmp) - 1);
  1684. s = tmp;
  1685. s1 = strsep(&s, "*"); /* Pick off MHz */
  1686. s2 = strsep(&s,"*"); /* Pick off KHz */
  1687. oc = *s; /* Pick off offset */
  1688. switch(strlen(s2)){ /* Allow partial entry of khz digits for laziness support */
  1689. case 1:
  1690. k = 100 * atoi(s2);
  1691. break;
  1692. case 2:
  1693. k = 10 * atoi(s2);
  1694. break;
  1695. case 3:
  1696. if((s2[2] != '0')&&(s2[2] != '5'))
  1697. return DC_ERROR;
  1698. k = atoi(s2);
  1699. break;
  1700. default:
  1701. return DC_ERROR;
  1702. }
  1703. snprintf(freq, sizeof(freq), "%s.%03d", s1, k);
  1704. offset = REM_SIMPLEX;
  1705. if (oc){
  1706. switch(oc){
  1707. case '1':
  1708. offset = REM_MINUS;
  1709. break;
  1710. case '2':
  1711. offset = REM_SIMPLEX;
  1712. break;
  1713. case '3':
  1714. offset = REM_PLUS;
  1715. break;
  1716. default:
  1717. return DC_ERROR;
  1718. }
  1719. }
  1720. offsave = myrpt->offset;
  1721. strncpy(savestr, myrpt->freq, sizeof(savestr) - 1);
  1722. strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
  1723. if(debug)
  1724. printf("@@@@ Frequency entered: %s\n", myrpt->freq);
  1725. strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
  1726. myrpt->offset = offset;
  1727. if (setrbi(myrpt) == -1){
  1728. myrpt->offset = offsave;
  1729. strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1);
  1730. return DC_ERROR;
  1731. }
  1732. return DC_COMPLETE;
  1733. case 3: /* set rx PL tone */
  1734. for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
  1735. if(digitbuf[i] == '*'){
  1736. j++;
  1737. continue;
  1738. }
  1739. if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
  1740. return DC_ERROR;
  1741. else{
  1742. if(j)
  1743. l++;
  1744. else
  1745. k++;
  1746. }
  1747. }
  1748. if((j > 1) || (k > 3) || (l > 1))
  1749. return DC_ERROR; /* &$@^! */
  1750. i = strlen(digitbuf) - 1;
  1751. if((j != 1) || (k < 2)|| (l != 1))
  1752. break; /* Not yet */
  1753. if(debug)
  1754. printf("PL digits entered %s\n", digitbuf);
  1755. strncpy(tmp, digitbuf, sizeof(tmp) - 1);
  1756. /* see if we have at least 1 */
  1757. s = strchr(tmp,'*');
  1758. if(s)
  1759. *s = '.';
  1760. strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1);
  1761. strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1);
  1762. if (setrbi(myrpt) == -1){
  1763. strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1);
  1764. return DC_ERROR;
  1765. }
  1766. return DC_COMPLETE;
  1767. case 100: /* other stuff */
  1768. case 101:
  1769. case 102:
  1770. case 103:
  1771. case 104:
  1772. case 105:
  1773. case 106:
  1774. switch(myatoi(param)){
  1775. case 100: /* RX PL Off */
  1776. myrpt->rxplon = 0;
  1777. break;
  1778. case 101: /* RX PL On */
  1779. myrpt->rxplon = 1;
  1780. break;
  1781. case 102: /* TX PL Off */
  1782. myrpt->txplon = 0;
  1783. break;
  1784. case 103: /* TX PL On */
  1785. myrpt->txplon = 1;
  1786. break;
  1787. case 104: /* Low Power */
  1788. myrpt->powerlevel = REM_LOWPWR;
  1789. break;
  1790. case 105: /* Medium Power */
  1791. myrpt->powerlevel = REM_MEDPWR;
  1792. break;
  1793. case 106: /* Hi Power */
  1794. myrpt->powerlevel = REM_HIPWR;
  1795. break;
  1796. default:
  1797. return DC_ERROR;
  1798. }
  1799. if (setrbi(myrpt) == -1)
  1800. return DC_ERROR;
  1801. return DC_COMPLETE;
  1802. case 5: /* Status */
  1803. myrpt->remotetx = 0;
  1804. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
  1805. if (!myrpt->remoterx){
  1806. ast_indicate(mychannel,AST_CONTROL_RADIO_KEY);
  1807. }
  1808. if (ast_safe_sleep(mychannel,1000) == -1)
  1809. return DC_ERROR;
  1810. if ((sayfile(mychannel,"rpt/node") == -1) ||
  1811. (saycharstr(mychannel,myrpt->name) == -1) ||
  1812. (sayfile(mychannel,"rpt/frequency") == -1) ||
  1813. (saycharstr(mychannel,myrpt->freq) == -1)){
  1814. if (!myrpt->remoterx){
  1815. ast_indicate(mychannel,AST_CONTROL_RADIO_UNKEY);
  1816. }
  1817. return DC_ERROR;
  1818. }
  1819. switch(myrpt->offset){
  1820. case REM_MINUS:
  1821. res = sayfile(mychannel,"rpt/minus");
  1822. break;
  1823. case REM_SIMPLEX:
  1824. res = sayfile(mychannel,"rpt/simplex");
  1825. break;
  1826. case REM_PLUS:
  1827. res = sayfile(mychannel,"rpt/plus");
  1828. break;
  1829. default:
  1830. return DC_ERROR;
  1831. }
  1832. if (res == -1){
  1833. if (!myrpt->remoterx){
  1834. ast_indicate(mychannel,AST_CONTROL_RADIO_UNKEY);
  1835. }
  1836. return -1;
  1837. }
  1838. switch(myrpt->powerlevel){
  1839. case REM_LOWPWR:
  1840. res = sayfile(mychannel,"rpt/lopwr") ;
  1841. break;
  1842. case REM_MEDPWR:
  1843. res = sayfile(mychannel,"rpt/medpwr");
  1844. break;
  1845. case REM_HIPWR:
  1846. res = sayfile(mychannel,"rpt/hipwr");
  1847. break;
  1848. }
  1849. if (res || (sayfile(mychannel,"rpt/rxpl") == -1) ||
  1850. (sayfile(mychannel,"rpt/frequency") == -1) ||
  1851. (saycharstr(mychannel,myrpt->rxpl) == -1) ||
  1852. (sayfile(mychannel,"rpt/txpl") == -1) ||
  1853. (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1) ||
  1854. (sayfile(mychannel,"rpt/rxpl") == -1) ||
  1855. (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1)){
  1856. if (!myrpt->remoterx){
  1857. ast_indicate(mychannel,AST_CONTROL_RADIO_UNKEY);
  1858. }
  1859. return -1;
  1860. }
  1861. if (!myrpt->remoterx){
  1862. ast_indicate(mychannel,AST_CONTROL_RADIO_UNKEY);
  1863. }
  1864. return DC_COMPLETE;
  1865. default:
  1866. return DC_ERROR;
  1867. }
  1868. return DC_INDETERMINATE;
  1869. }
  1870. /*
  1871. * Collect digits one by one until something matches
  1872. */
  1873. static int collect_function_digits(struct rpt *myrpt, char *digits, int command_source)
  1874. {
  1875. int i;
  1876. char *stringp,*action,*param,*functiondigits;
  1877. char function_table_name[30] = "";
  1878. char workstring[80];
  1879. struct ast_variable *vp;
  1880. if(debug)
  1881. printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source);
  1882. if (command_source == SOURCE_LNK)
  1883. strncpy(function_table_name, myrpt->link_functions, sizeof(function_table_name) - 1);
  1884. else
  1885. strncpy(function_table_name, myrpt->functions, sizeof(function_table_name) - 1);
  1886. vp = ast_variable_browse(cfg, function_table_name);
  1887. while(vp) {
  1888. if(!strncasecmp(vp->name, digits, strlen(vp->name)))
  1889. break;
  1890. vp = vp->next;
  1891. }
  1892. if(!vp) {
  1893. if(strlen(digits) >= ((command_source == SOURCE_LNK) ?
  1894. myrpt->link_longestfunc : myrpt->longestfunc)) /* Get out of function mode if longes func length reached */
  1895. return DC_ERROR;
  1896. else
  1897. return DC_INDETERMINATE;
  1898. }
  1899. /* Found a match, retrieve value part and parse */
  1900. strncpy(workstring, vp->value, sizeof(workstring) - 1 );
  1901. stringp = workstring;
  1902. action = strsep(&stringp, ",");
  1903. param = stringp;
  1904. if(debug)
  1905. printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)");
  1906. /* Look up the action */
  1907. for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){
  1908. if(!strncasecmp(action, function_table[i].action, strlen(action)))
  1909. break;
  1910. }
  1911. if(debug)
  1912. printf("@@@@ table index i = %d\n",i);
  1913. if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){
  1914. /* Error, action not in table */
  1915. return DC_ERROR;
  1916. }
  1917. if(function_table[i].function == NULL){
  1918. /* Error, function undefined */
  1919. if(debug)
  1920. printf("@@@@ NULL for action: %s\n",action);
  1921. return DC_ERROR;
  1922. }
  1923. functiondigits = digits + strlen(vp->name);
  1924. return (*function_table[i].function)(myrpt, param, functiondigits, command_source);
  1925. }
  1926. static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink,
  1927. char *str)
  1928. {
  1929. char tmp[300],cmd[300] = "",dest[300],src[300],c;
  1930. int seq, res;
  1931. struct rpt_link *l;
  1932. struct ast_frame wf;
  1933. wf.frametype = AST_FRAME_TEXT;
  1934. wf.subclass = 0;
  1935. wf.offset = 0;
  1936. wf.mallocd = 1;
  1937. wf.datalen = strlen(str) + 1;
  1938. wf.samples = 0;
  1939. /* put string in our buffer */
  1940. strncpy(tmp,str,sizeof(tmp) - 1);
  1941. if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
  1942. {
  1943. ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
  1944. return;
  1945. }
  1946. if (strcmp(cmd,"D"))
  1947. {
  1948. ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
  1949. return;
  1950. }
  1951. /* if not for me, redistribute to all links */
  1952. if (strcmp(dest,myrpt->name))
  1953. {
  1954. l = myrpt->links.next;
  1955. /* see if this is one in list */
  1956. while(l != &myrpt->links)
  1957. {
  1958. /* dont send back from where it came */
  1959. if ((l == mylink) || (!strcmp(l->name,mylink->name)))
  1960. {
  1961. l = l->next;
  1962. continue;
  1963. }
  1964. /* if it is, send it and we're done */
  1965. if (!strcmp(l->name,dest))
  1966. {
  1967. /* send, but not to src */
  1968. if (strcmp(l->name,src)) {
  1969. wf.data = strdup(str);
  1970. ast_write(l->chan,&wf);
  1971. }
  1972. return;
  1973. }
  1974. l = l->next;
  1975. }
  1976. l = myrpt->links.next;
  1977. /* otherwise, send it to all of em */
  1978. while(l != &myrpt->links)
  1979. {
  1980. /* dont send back from where it came */
  1981. if ((l == mylink) || (!strcmp(l->name,mylink->name)))
  1982. {
  1983. l = l->next;
  1984. continue;
  1985. }
  1986. /* send, but not to src */
  1987. if (strcmp(l->name,src)) {
  1988. wf.data = strdup(str);
  1989. ast_write(l->chan,&wf);
  1990. }
  1991. l = l->next;
  1992. }
  1993. return;
  1994. }
  1995. ast_mutex_lock(&myrpt->lock);
  1996. if (myrpt->callmode == 1)
  1997. {
  1998. myrpt->exten[myrpt->cidx++] = c;
  1999. myrpt->exten[myrpt->cidx] = 0;
  2000. /* if this exists */
  2001. if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
  2002. {
  2003. myrpt->callmode = 2;
  2004. rpt_telemetry(myrpt,PROC,NULL);
  2005. }
  2006. /* if can continue, do so */
  2007. if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
  2008. {
  2009. /* call has failed, inform user */
  2010. myrpt->callmode = 4;
  2011. }
  2012. }
  2013. if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
  2014. {
  2015. myrpt->mydtmf = c;
  2016. }
  2017. if (c == myrpt->funcchar)
  2018. {
  2019. myrpt->rem_dtmfidx = 0;
  2020. myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
  2021. time(&myrpt->rem_dtmf_time);
  2022. ast_mutex_unlock(&myrpt->lock);
  2023. return;
  2024. }
  2025. else if ((c != myrpt->endchar) && (myrpt->rem_dtmfidx >= 0))
  2026. {
  2027. time(&myrpt->rem_dtmf_time);
  2028. if (myrpt->rem_dtmfidx < MAXDTMF)
  2029. {
  2030. myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
  2031. myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
  2032. ast_mutex_unlock(&myrpt->lock);
  2033. strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
  2034. res = collect_function_digits(myrpt, cmd, SOURCE_LNK);
  2035. ast_mutex_lock(&myrpt->lock);
  2036. switch(res){
  2037. case DC_INDETERMINATE:
  2038. break;
  2039. case DC_REQ_FLUSH:
  2040. myrpt->rem_dtmfidx = 0;
  2041. myrpt->rem_dtmfbuf[0] = 0;
  2042. break;
  2043. case DC_COMPLETE:
  2044. myrpt->rem_dtmfbuf[0] = 0;
  2045. myrpt->rem_dtmfidx = -1;
  2046. myrpt->rem_dtmf_time = 0;
  2047. break;
  2048. case DC_ERROR:
  2049. default:
  2050. myrpt->rem_dtmfbuf[0] = 0;
  2051. myrpt->rem_dtmfidx = -1;
  2052. myrpt->rem_dtmf_time = 0;
  2053. break;
  2054. }
  2055. }
  2056. }
  2057. ast_mutex_unlock(&myrpt->lock);
  2058. return;
  2059. }
  2060. /* Doug Hall RBI-1 serial data definitions:
  2061. *
  2062. * Byte 0: Expansion external outputs
  2063. * Byte 1:
  2064. * Bits 0-3 are BAND as follows:
  2065. * Bits 4-5 are POWER bits as follows:
  2066. * 00 - Low Power
  2067. * 01 - Hi Power
  2068. * 02 - Med Power
  2069. * Bits 6-7 are always set
  2070. * Byte 2:
  2071. * Bits 0-3 MHZ in BCD format
  2072. * Bits 4-5 are offset as follows:
  2073. * 00 - minus
  2074. * 01 - plus
  2075. * 02 - simplex
  2076. * 03 - minus minus (whatever that is)
  2077. * Bit 6 is the 0/5 KHZ bit
  2078. * Bit 7 is always set
  2079. * Byte 3:
  2080. * Bits 0-3 are 10 KHZ in BCD format
  2081. * Bits 4-7 are 100 KHZ in BCD format
  2082. * Byte 4: PL Tone code and encode/decode enable bits
  2083. * Bits 0-5 are PL tone code (comspec binary codes)
  2084. * Bit 6 is encode enable/disable
  2085. * Bit 7 is decode enable/disable
  2086. */
  2087. /* take the frequency from the 10 mhz digits (and up) and convert it
  2088. to a band number */
  2089. static int rbi_mhztoband(char *str)
  2090. {
  2091. int i;
  2092. i = atoi(str) / 10; /* get the 10's of mhz */
  2093. switch(i)
  2094. {
  2095. case 2:
  2096. return 10;
  2097. case 5:
  2098. return 11;
  2099. case 14:
  2100. return 2;
  2101. case 22:
  2102. return 3;
  2103. case 44:
  2104. return 4;
  2105. case 124:
  2106. return 0;
  2107. case 125:
  2108. return 1;
  2109. case 126:
  2110. return 8;
  2111. case 127:
  2112. return 5;
  2113. case 128:
  2114. return 6;
  2115. case 129:
  2116. return 7;
  2117. default:
  2118. break;
  2119. }
  2120. return -1;
  2121. }
  2122. /* take a PL frequency and turn it into a code */
  2123. static int rbi_pltocode(char *str)
  2124. {
  2125. int i;
  2126. char *s;
  2127. s = strchr(str,'.');
  2128. i = 0;
  2129. if (s) i = atoi(s + 1);
  2130. i += atoi(str) * 10;
  2131. switch(i)
  2132. {
  2133. case 670:
  2134. return 0;
  2135. case 719:
  2136. return 1;
  2137. case 744:
  2138. return 2;
  2139. case 770:
  2140. return 3;
  2141. case 797:
  2142. return 4;
  2143. case 825:
  2144. return 5;
  2145. case 854:
  2146. return 6;
  2147. case 885:
  2148. return 7;
  2149. case 915:
  2150. return 8;
  2151. case 948:
  2152. return 9;
  2153. case 974:
  2154. return 10;
  2155. case 1000:
  2156. return 11;
  2157. case 1035:
  2158. return 12;
  2159. case 1072:
  2160. return 13;
  2161. case 1109:
  2162. return 14;
  2163. case 1148:
  2164. return 15;
  2165. case 1188:
  2166. return 16;
  2167. case 1230:
  2168. return 17;
  2169. case 1273:
  2170. return 18;
  2171. case 1318:
  2172. return 19;
  2173. case 1365:
  2174. return 20;
  2175. case 1413:
  2176. return 21;
  2177. case 1462:
  2178. return 22;
  2179. case 1514:
  2180. return 23;
  2181. case 1567:
  2182. return 24;
  2183. case 1622:
  2184. return 25;
  2185. case 1679:
  2186. return 26;
  2187. case 1738:
  2188. return 27;
  2189. case 1799:
  2190. return 28;
  2191. case 1862:
  2192. return 29;
  2193. case 1928:
  2194. return 30;
  2195. case 2035:
  2196. return 31;
  2197. case 2107:
  2198. return 32;
  2199. case 2181:
  2200. return 33;
  2201. case 2257:
  2202. return 34;
  2203. case 2336:
  2204. return 35;
  2205. case 2418:
  2206. return 36;
  2207. case 2503:
  2208. return 37;
  2209. }
  2210. return -1;
  2211. }
  2212. /*
  2213. * Shift out a formatted serial bit stream
  2214. */
  2215. static void rbi_out(struct rpt *myrpt,unsigned char *data)
  2216. {
  2217. int i,j;
  2218. unsigned char od,d;
  2219. static volatile long long delayvar;
  2220. for(i = 0 ; i < 5 ; i++){
  2221. od = *data++;
  2222. for(j = 0 ; j < 8 ; j++){
  2223. d = od & 1;
  2224. outb(d,myrpt->iobase);
  2225. /* >= 15 us */
  2226. for(delayvar = 1; delayvar < 15000; delayvar++);
  2227. od >>= 1;
  2228. outb(d | 2,myrpt->iobase);
  2229. /* >= 30 us */
  2230. for(delayvar = 1; delayvar < 30000; delayvar++);
  2231. outb(d,myrpt->iobase);
  2232. /* >= 10 us */
  2233. for(delayvar = 1; delayvar < 10000; delayvar++);
  2234. }
  2235. }
  2236. /* >= 50 us */
  2237. for(delayvar = 1; delayvar < 50000; delayvar++);
  2238. }
  2239. static int setrbi(struct rpt *myrpt)
  2240. {
  2241. char tmp[MAXREMSTR] = "",rbicmd[5],*s;
  2242. int band,txoffset = 0,txpower = 0,rxpl;
  2243. /* must be a remote system */
  2244. if (!myrpt->remote) return(0);
  2245. /* must have rbi hardware */
  2246. if (strncmp(myrpt->remote,"rbi",3)) return(0);
  2247. strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
  2248. s = strchr(tmp,'.');
  2249. /* if no decimal, is invalid */
  2250. if (s == NULL){
  2251. if(debug)
  2252. printf("@@@@ Frequency needs a decimal\n");
  2253. return -1;
  2254. }
  2255. *s++ = 0;
  2256. if (strlen(tmp) < 2){
  2257. if(debug)
  2258. printf("@@@@ Bad MHz digits: %s\n", tmp);
  2259. return -1;
  2260. }
  2261. if (strlen(s) < 3){
  2262. if(debug)
  2263. printf("@@@@ Bad KHz digits: %s\n", s);
  2264. return -1;
  2265. }
  2266. if ((s[2] != '0') && (s[2] != '5')){
  2267. if(debug)
  2268. printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
  2269. return -1;
  2270. }
  2271. band = rbi_mhztoband(tmp);
  2272. if (band == -1){
  2273. if(debug)
  2274. printf("@@@@ Bad Band: %s\n", tmp);
  2275. return -1;
  2276. }
  2277. rxpl = rbi_pltocode(myrpt->rxpl);
  2278. if (rxpl == -1){
  2279. if(debug)
  2280. printf("@@@@ Bad RX PL: %s\n", myrpt->rxpl);
  2281. return -1;
  2282. }
  2283. switch(myrpt->offset)
  2284. {
  2285. case REM_MINUS:
  2286. txoffset = 0;
  2287. break;
  2288. case REM_PLUS:
  2289. txoffset = 0x10;
  2290. break;
  2291. case REM_SIMPLEX:
  2292. txoffset = 0x20;
  2293. break;
  2294. }
  2295. switch(myrpt->powerlevel)
  2296. {
  2297. case REM_LOWPWR:
  2298. txpower = 0;
  2299. break;
  2300. case REM_MEDPWR:
  2301. txpower = 0x20;
  2302. break;
  2303. case REM_HIPWR:
  2304. txpower = 0x10;
  2305. break;
  2306. }
  2307. rbicmd[0] = 0;
  2308. rbicmd[1] = band | txpower | 0xc0;
  2309. rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80;
  2310. if (s[2] == '5') rbicmd[2] |= 0x40;
  2311. rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0');
  2312. rbicmd[4] = rxpl;
  2313. if (myrpt->txplon) rbicmd[4] |= 0x40;
  2314. if (myrpt->rxplon) rbicmd[4] |= 0x80;
  2315. rbi_out(myrpt,rbicmd);
  2316. return 0;
  2317. }
  2318. static int handle_remote_dtmf_digit(struct rpt *myrpt,char c)
  2319. {
  2320. time_t now;
  2321. int ret,res = 0;
  2322. time(&now);
  2323. /* if timed-out */
  2324. if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now)
  2325. {
  2326. myrpt->dtmfidx = -1;
  2327. myrpt->dtmfbuf[0] = 0;
  2328. myrpt->dtmf_time_rem = 0;
  2329. }
  2330. /* if decode not active */
  2331. if (myrpt->dtmfidx == -1)
  2332. {
  2333. /* if not lead-in digit, dont worry */
  2334. if (c != myrpt->funcchar) return 0;
  2335. myrpt->dtmfidx = 0;
  2336. myrpt->dtmfbuf[0] = 0;
  2337. myrpt->dtmf_time_rem = now;
  2338. return 0;
  2339. }
  2340. /* if too many in buffer, start over */
  2341. if (myrpt->dtmfidx >= MAXDTMF)
  2342. {
  2343. myrpt->dtmfidx = 0;
  2344. myrpt->dtmfbuf[0] = 0;
  2345. myrpt->dtmf_time_rem = now;
  2346. }
  2347. if (c == myrpt->funcchar)
  2348. {
  2349. /* if star at beginning, or 2 together, erase buffer */
  2350. if ((myrpt->dtmfidx < 1) ||
  2351. (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->funcchar))
  2352. {
  2353. myrpt->dtmfidx = 0;
  2354. myrpt->dtmfbuf[0] = 0;
  2355. myrpt->dtmf_time_rem = now;
  2356. return 0;
  2357. }
  2358. }
  2359. myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
  2360. myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
  2361. myrpt->dtmf_time_rem = now;
  2362. ret = collect_function_digits(myrpt, myrpt->dtmfbuf, SOURCE_RMT);
  2363. switch(ret){
  2364. case DC_INDETERMINATE:
  2365. res = 0;
  2366. break;
  2367. case DC_REQ_FLUSH:
  2368. myrpt->dtmfidx = 0;
  2369. myrpt->dtmfbuf[0] = 0;
  2370. res = 0;
  2371. break;
  2372. case DC_COMPLETE:
  2373. myrpt->dtmfbuf[0] = 0;
  2374. myrpt->dtmfidx = -1;
  2375. myrpt->dtmf_time_rem = 0;
  2376. res = 1;
  2377. break;
  2378. case DC_ERROR:
  2379. default:
  2380. myrpt->dtmfbuf[0] = 0;
  2381. myrpt->dtmfidx = -1;
  2382. myrpt->dtmf_time_rem = 0;
  2383. res = 0;
  2384. break;
  2385. }
  2386. return res;
  2387. }
  2388. static int handle_remote_data(struct rpt *myrpt, char *str)
  2389. {
  2390. char tmp[300],cmd[300],dest[300],src[300],c;
  2391. int seq,res;
  2392. /* put string in our buffer */
  2393. strncpy(tmp,str,sizeof(tmp) - 1);
  2394. if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
  2395. {
  2396. ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
  2397. return 0;
  2398. }
  2399. if (strcmp(cmd,"D"))
  2400. {
  2401. ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
  2402. return 0;
  2403. }
  2404. /* if not for me, ignore */
  2405. if (strcmp(dest,myrpt->name)) return 0;
  2406. res = handle_remote_dtmf_digit(myrpt,c);
  2407. if (res != 1)
  2408. return res;
  2409. myrpt->remotetx = 0;
  2410. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
  2411. if (!myrpt->remoterx)
  2412. {
  2413. ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY);
  2414. }
  2415. if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1;
  2416. res = telem_lookup(myrpt->remchannel, myrpt->name, "functcomplete");
  2417. if (!myrpt->remoterx)
  2418. {
  2419. ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_UNKEY);
  2420. }
  2421. return res;
  2422. }
  2423. /* single thread with one file (request) to dial */
  2424. static void *rpt(void *this)
  2425. {
  2426. struct rpt *myrpt = (struct rpt *)this;
  2427. char *tele,*idtalkover;
  2428. int ms = MSWAIT,lasttx,keyed,val,remrx,identqueued,nonidentqueued,res;
  2429. struct ast_channel *who;
  2430. ZT_CONFINFO ci; /* conference info */
  2431. time_t dtmf_time,t;
  2432. struct rpt_link *l,*m;
  2433. struct rpt_tele *telem;
  2434. pthread_attr_t attr;
  2435. char tmpstr[300];
  2436. char cmd[MAXDTMF+1] = "";
  2437. ast_mutex_lock(&myrpt->lock);
  2438. strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1);
  2439. tele = strchr(tmpstr,'/');
  2440. if (!tele)
  2441. {
  2442. fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->rxchanname);
  2443. ast_mutex_unlock(&myrpt->lock);
  2444. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2445. pthread_exit(NULL);
  2446. }
  2447. *tele++ = 0;
  2448. myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele);
  2449. if (myrpt->rxchannel)
  2450. {
  2451. if (myrpt->rxchannel->_state == AST_STATE_BUSY)
  2452. {
  2453. fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
  2454. ast_mutex_unlock(&myrpt->lock);
  2455. ast_hangup(myrpt->rxchannel);
  2456. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2457. pthread_exit(NULL);
  2458. }
  2459. ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
  2460. ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
  2461. myrpt->rxchannel->whentohangup = 0;
  2462. myrpt->rxchannel->appl = "Apprpt";
  2463. myrpt->rxchannel->data = "(Repeater Rx)";
  2464. if (option_verbose > 2)
  2465. ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
  2466. tmpstr,tele,myrpt->rxchannel->name);
  2467. ast_call(myrpt->rxchannel,tele,999);
  2468. if (myrpt->rxchannel->_state != AST_STATE_UP)
  2469. {
  2470. ast_mutex_unlock(&myrpt->lock);
  2471. ast_hangup(myrpt->rxchannel);
  2472. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2473. pthread_exit(NULL);
  2474. }
  2475. }
  2476. else
  2477. {
  2478. fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
  2479. ast_mutex_unlock(&myrpt->lock);
  2480. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2481. pthread_exit(NULL);
  2482. }
  2483. if (myrpt->txchanname)
  2484. {
  2485. strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
  2486. tele = strchr(tmpstr,'/');
  2487. if (!tele)
  2488. {
  2489. fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
  2490. ast_mutex_unlock(&myrpt->lock);
  2491. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2492. pthread_exit(NULL);
  2493. }
  2494. *tele++ = 0;
  2495. myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele);
  2496. if (myrpt->txchannel)
  2497. {
  2498. if (myrpt->txchannel->_state == AST_STATE_BUSY)
  2499. {
  2500. fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
  2501. ast_mutex_unlock(&myrpt->lock);
  2502. ast_hangup(myrpt->txchannel);
  2503. ast_hangup(myrpt->rxchannel);
  2504. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2505. pthread_exit(NULL);
  2506. }
  2507. ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
  2508. ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
  2509. myrpt->txchannel->whentohangup = 0;
  2510. myrpt->txchannel->appl = "Apprpt";
  2511. myrpt->txchannel->data = "(Repeater Rx)";
  2512. if (option_verbose > 2)
  2513. ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
  2514. tmpstr,tele,myrpt->txchannel->name);
  2515. ast_call(myrpt->txchannel,tele,999);
  2516. if (myrpt->rxchannel->_state != AST_STATE_UP)
  2517. {
  2518. ast_mutex_unlock(&myrpt->lock);
  2519. ast_hangup(myrpt->rxchannel);
  2520. ast_hangup(myrpt->txchannel);
  2521. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2522. pthread_exit(NULL);
  2523. }
  2524. }
  2525. else
  2526. {
  2527. fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
  2528. ast_mutex_unlock(&myrpt->lock);
  2529. ast_hangup(myrpt->rxchannel);
  2530. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2531. pthread_exit(NULL);
  2532. }
  2533. }
  2534. else
  2535. {
  2536. myrpt->txchannel = myrpt->rxchannel;
  2537. }
  2538. /* allocate a pseudo-channel thru asterisk */
  2539. myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  2540. if (!myrpt->pchannel)
  2541. {
  2542. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  2543. ast_mutex_unlock(&myrpt->lock);
  2544. if (myrpt->txchannel != myrpt->rxchannel)
  2545. ast_hangup(myrpt->txchannel);
  2546. ast_hangup(myrpt->rxchannel);
  2547. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2548. pthread_exit(NULL);
  2549. }
  2550. /* make a conference for the tx */
  2551. ci.chan = 0;
  2552. ci.confno = -1; /* make a new conf */
  2553. ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER;
  2554. /* first put the channel on the conference in proper mode */
  2555. if (ioctl(myrpt->txchannel->fds[0],ZT_SETCONF,&ci) == -1)
  2556. {
  2557. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  2558. ast_mutex_unlock(&myrpt->lock);
  2559. ast_hangup(myrpt->pchannel);
  2560. if (myrpt->txchannel != myrpt->rxchannel)
  2561. ast_hangup(myrpt->txchannel);
  2562. ast_hangup(myrpt->rxchannel);
  2563. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2564. pthread_exit(NULL);
  2565. }
  2566. /* save tx conference number */
  2567. myrpt->txconf = ci.confno;
  2568. /* make a conference for the pseudo */
  2569. ci.chan = 0;
  2570. ci.confno = -1; /* make a new conf */
  2571. ci.confmode = ZT_CONF_CONFANNMON;
  2572. /* first put the channel on the conference in announce mode */
  2573. if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
  2574. {
  2575. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  2576. ast_mutex_unlock(&myrpt->lock);
  2577. ast_hangup(myrpt->pchannel);
  2578. if (myrpt->txchannel != myrpt->rxchannel)
  2579. ast_hangup(myrpt->txchannel);
  2580. ast_hangup(myrpt->rxchannel);
  2581. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2582. pthread_exit(NULL);
  2583. }
  2584. /* save pseudo channel conference number */
  2585. myrpt->conf = ci.confno;
  2586. /* allocate a pseudo-channel thru asterisk */
  2587. myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  2588. if (!myrpt->txpchannel)
  2589. {
  2590. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  2591. ast_mutex_unlock(&myrpt->lock);
  2592. ast_hangup(myrpt->pchannel);
  2593. if (myrpt->txchannel != myrpt->rxchannel)
  2594. ast_hangup(myrpt->txchannel);
  2595. ast_hangup(myrpt->rxchannel);
  2596. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2597. pthread_exit(NULL);
  2598. }
  2599. /* make a conference for the tx */
  2600. ci.chan = 0;
  2601. ci.confno = myrpt->txconf;
  2602. ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ;
  2603. /* first put the channel on the conference in proper mode */
  2604. if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1)
  2605. {
  2606. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  2607. ast_mutex_unlock(&myrpt->lock);
  2608. ast_hangup(myrpt->txpchannel);
  2609. ast_hangup(myrpt->pchannel);
  2610. if (myrpt->txchannel != myrpt->rxchannel)
  2611. ast_hangup(myrpt->txchannel);
  2612. ast_hangup(myrpt->rxchannel);
  2613. myrpt->rpt_thread = AST_PTHREADT_STOP;
  2614. pthread_exit(NULL);
  2615. }
  2616. /* Now, the idea here is to copy from the physical rx channel buffer
  2617. into the pseudo tx buffer, and from the pseudo rx buffer into the
  2618. tx channel buffer */
  2619. myrpt->links.next = &myrpt->links;
  2620. myrpt->links.prev = &myrpt->links;
  2621. myrpt->tailtimer = 0;
  2622. myrpt->totimer = 0;
  2623. myrpt->idtimer = myrpt->politeid;
  2624. myrpt->mustid = 0;
  2625. myrpt->callmode = 0;
  2626. myrpt->tounkeyed = 0;
  2627. myrpt->tonotify = 0;
  2628. lasttx = 0;
  2629. keyed = 0;
  2630. idtalkover = ast_variable_retrieve(cfg, myrpt->name, "idtalkover");
  2631. myrpt->dtmfidx = -1;
  2632. myrpt->dtmfbuf[0] = 0;
  2633. myrpt->rem_dtmfidx = -1;
  2634. myrpt->rem_dtmfbuf[0] = 0;
  2635. dtmf_time = 0;
  2636. myrpt->rem_dtmf_time = 0;
  2637. myrpt->enable = 1;
  2638. ast_mutex_unlock(&myrpt->lock);
  2639. val = 0;
  2640. ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
  2641. val = 1;
  2642. ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0);
  2643. while (ms >= 0)
  2644. {
  2645. struct ast_frame *f;
  2646. struct ast_channel *cs[300];
  2647. int totx,elap,n,toexit;
  2648. if (ast_check_hangup(myrpt->rxchannel)) break;
  2649. if (ast_check_hangup(myrpt->txchannel)) break;
  2650. if (ast_check_hangup(myrpt->pchannel)) break;
  2651. if (ast_check_hangup(myrpt->txpchannel)) break;
  2652. ast_mutex_lock(&myrpt->lock);
  2653. myrpt->localtx = keyed && (myrpt->dtmfidx == -1) && (!myrpt->cmdnode[0]);
  2654. /* If someone's connected, and they're transmitting from their end to us, set remrx true */
  2655. l = myrpt->links.next;
  2656. remrx = 0;
  2657. while(l != &myrpt->links)
  2658. {
  2659. if (l->lastrx) remrx = 1;
  2660. l = l->next;
  2661. }
  2662. /* Create a "must_id" flag for the cleanup ID */
  2663. myrpt->mustid |= (myrpt->idtimer) && (keyed || remrx) ;
  2664. /* Build a fresh totx from keyed and autopatch activated */
  2665. totx = myrpt->localtx || myrpt->callmode;
  2666. /* Traverse the telemetry list to see if there's an ID queued and if there is not an ID queued */
  2667. identqueued = 0;
  2668. nonidentqueued = 0;
  2669. telem = myrpt->tele.next;
  2670. while(telem != &myrpt->tele)
  2671. {
  2672. if((telem->mode == ID) || (telem->mode == IDTALKOVER)){
  2673. identqueued = 1;
  2674. }
  2675. else
  2676. nonidentqueued = 1;
  2677. telem = telem->next;
  2678. }
  2679. /* Add in any non-id telemetry */
  2680. totx = totx || nonidentqueued;
  2681. /* Update external transmitter PTT state with everything but ID telemetry */
  2682. myrpt->exttx = totx;
  2683. /* Add in ID telemetry to local transmitter */
  2684. totx = totx || remrx || identqueued;
  2685. if (!totx)
  2686. {
  2687. myrpt->totimer = myrpt->totime;
  2688. myrpt->tounkeyed = 0;
  2689. myrpt->tonotify = 0;
  2690. }
  2691. else myrpt->tailtimer = myrpt->hangtime;
  2692. totx = totx && myrpt->totimer;
  2693. /* if timed-out and not said already, say it */
  2694. if ((!myrpt->totimer) && (!myrpt->tonotify))
  2695. {
  2696. myrpt->tonotify = 1;
  2697. rpt_telemetry(myrpt,TIMEOUT,NULL);
  2698. }
  2699. /* if wants to transmit and in phone call, but timed out,
  2700. reset time-out timer if keyed */
  2701. if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!keyed))
  2702. {
  2703. myrpt->tounkeyed = 1;
  2704. }
  2705. if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->localtx)
  2706. {
  2707. myrpt->totimer = myrpt->totime;
  2708. myrpt->tounkeyed = 0;
  2709. myrpt->tonotify = 0;
  2710. ast_mutex_unlock(&myrpt->lock);
  2711. continue;
  2712. }
  2713. /* if timed-out and in circuit busy after call */
  2714. if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4))
  2715. {
  2716. myrpt->callmode = 0;
  2717. }
  2718. /* get rid of tail if timed out */
  2719. if (!myrpt->totimer) myrpt->tailtimer = 0;
  2720. /* if not timed-out, add in tail */
  2721. if (myrpt->totimer) totx = totx || myrpt->tailtimer;
  2722. /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
  2723. if (identqueued && (keyed || remrx) && idtalkover) {
  2724. int hasid = 0,hastalkover = 0;
  2725. telem = myrpt->tele.next;
  2726. while(telem != &myrpt->tele){
  2727. if(telem->mode == ID){
  2728. if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
  2729. hasid = 1;
  2730. }
  2731. if (telem->mode == IDTALKOVER) hastalkover = 1;
  2732. telem = telem->next;
  2733. }
  2734. ast_mutex_unlock(&myrpt->lock);
  2735. if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */
  2736. ast_mutex_lock(&myrpt->lock);
  2737. }
  2738. /* Try to be polite */
  2739. /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/
  2740. /* If within 30 seconds of the time to ID, try do it in the tail */
  2741. /* else if at ID time limit, do it right over the top of them */
  2742. /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */
  2743. if (((totx && (!myrpt->exttx) && (myrpt->idtimer <= myrpt->politeid) && myrpt->tailtimer)) ||
  2744. (myrpt->mustid && (!myrpt->idtimer)))
  2745. {
  2746. myrpt->mustid = 0;
  2747. myrpt->idtimer = myrpt->idtime; /* Reset our ID timer */
  2748. ast_mutex_unlock(&myrpt->lock);
  2749. rpt_telemetry(myrpt,ID,NULL);
  2750. ast_mutex_lock(&myrpt->lock);
  2751. }
  2752. /* let telemetry transmit anyway (regardless of timeout) */
  2753. totx = totx || (myrpt->tele.next != &myrpt->tele);
  2754. if (totx && (!lasttx))
  2755. {
  2756. lasttx = 1;
  2757. ast_mutex_unlock(&myrpt->lock);
  2758. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
  2759. ast_mutex_lock(&myrpt->lock);
  2760. }
  2761. totx = totx && myrpt->enable;
  2762. if ((!totx) && lasttx)
  2763. {
  2764. lasttx = 0;
  2765. ast_mutex_unlock(&myrpt->lock);
  2766. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
  2767. ast_mutex_lock(&myrpt->lock);
  2768. }
  2769. time(&t);
  2770. /* if DTMF timeout */
  2771. if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((dtmf_time + DTMF_TIMEOUT) < t))
  2772. {
  2773. myrpt->dtmfidx = -1;
  2774. myrpt->dtmfbuf[0] = 0;
  2775. }
  2776. /* if remote DTMF timeout */
  2777. if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t))
  2778. {
  2779. myrpt->rem_dtmfidx = -1;
  2780. myrpt->rem_dtmfbuf[0] = 0;
  2781. }
  2782. n = 0;
  2783. cs[n++] = myrpt->rxchannel;
  2784. cs[n++] = myrpt->pchannel;
  2785. cs[n++] = myrpt->txpchannel;
  2786. if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel;
  2787. l = myrpt->links.next;
  2788. while(l != &myrpt->links)
  2789. {
  2790. cs[n++] = l->chan;
  2791. cs[n++] = l->pchan;
  2792. l = l->next;
  2793. }
  2794. ast_mutex_unlock(&myrpt->lock);
  2795. ms = MSWAIT;
  2796. who = ast_waitfor_n(cs,n,&ms);
  2797. if (who == NULL) ms = 0;
  2798. elap = MSWAIT - ms;
  2799. ast_mutex_lock(&myrpt->lock);
  2800. l = myrpt->links.next;
  2801. while(l != &myrpt->links)
  2802. {
  2803. /* ignore non-timing channels */
  2804. if (l->elaptime < 0)
  2805. {
  2806. l = l->next;
  2807. continue;
  2808. }
  2809. l->elaptime += elap;
  2810. /* if connection has taken too long */
  2811. if ((l->elaptime > MAXCONNECTTIME) &&
  2812. (l->chan->_state != AST_STATE_UP))
  2813. {
  2814. ast_mutex_unlock(&myrpt->lock);
  2815. ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
  2816. rpt_telemetry(myrpt,CONNFAIL,l);
  2817. ast_mutex_lock(&myrpt->lock);
  2818. }
  2819. l = l->next;
  2820. }
  2821. if (myrpt->tailtimer) myrpt->tailtimer -= elap;
  2822. if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
  2823. if (myrpt->totimer) myrpt->totimer -= elap;
  2824. if (myrpt->totimer < 0) myrpt->totimer = 0;
  2825. if (myrpt->idtimer) myrpt->idtimer -= elap;
  2826. if (myrpt->idtimer < 0) myrpt->idtimer = 0;
  2827. ast_mutex_unlock(&myrpt->lock);
  2828. if (!ms) continue;
  2829. if (who == myrpt->rxchannel) /* if it was a read from rx */
  2830. {
  2831. f = ast_read(myrpt->rxchannel);
  2832. if (!f)
  2833. {
  2834. if (debug) printf("@@@@ rpt:Hung Up\n");
  2835. break;
  2836. }
  2837. if (f->frametype == AST_FRAME_VOICE)
  2838. {
  2839. if (!myrpt->localtx)
  2840. memset(f->data,0,f->datalen);
  2841. ast_write(myrpt->pchannel,f);
  2842. }
  2843. else if (f->frametype == AST_FRAME_DTMF)
  2844. {
  2845. char c;
  2846. c = (char) f->subclass; /* get DTMF char */
  2847. ast_frfree(f);
  2848. if (c == myrpt->endchar)
  2849. {
  2850. /* if in simple mode, kill autopatch */
  2851. if (myrpt->simple && myrpt->callmode)
  2852. {
  2853. myrpt->callmode = 0;
  2854. rpt_telemetry(myrpt,TERM,NULL);
  2855. continue;
  2856. }
  2857. ast_mutex_lock(&myrpt->lock);
  2858. if (myrpt->cmdnode[0])
  2859. {
  2860. myrpt->cmdnode[0] = 0;
  2861. myrpt->dtmfidx = -1;
  2862. myrpt->dtmfbuf[0] = 0;
  2863. ast_mutex_unlock(&myrpt->lock);
  2864. rpt_telemetry(myrpt,COMPLETE,NULL);
  2865. } else ast_mutex_unlock(&myrpt->lock);
  2866. continue;
  2867. }
  2868. if (myrpt->cmdnode[0])
  2869. {
  2870. send_link_dtmf(myrpt,c);
  2871. continue;
  2872. }
  2873. if (!myrpt->simple)
  2874. {
  2875. if (c == myrpt->funcchar)
  2876. {
  2877. myrpt->dtmfidx = 0;
  2878. myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
  2879. time(&dtmf_time);
  2880. continue;
  2881. }
  2882. else if ((c != myrpt->endchar) && (myrpt->dtmfidx >= 0))
  2883. {
  2884. time(&dtmf_time);
  2885. if (myrpt->dtmfidx < MAXDTMF)
  2886. {
  2887. myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
  2888. myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
  2889. strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
  2890. ast_mutex_unlock(&myrpt->lock);
  2891. res = collect_function_digits(myrpt, cmd, SOURCE_RPT);
  2892. ast_mutex_lock(&myrpt->lock);
  2893. switch(res){
  2894. case DC_INDETERMINATE:
  2895. break;
  2896. case DC_REQ_FLUSH:
  2897. myrpt->dtmfidx = 0;
  2898. myrpt->dtmfbuf[0] = 0;
  2899. break;
  2900. case DC_COMPLETE:
  2901. myrpt->dtmfbuf[0] = 0;
  2902. myrpt->dtmfidx = -1;
  2903. dtmf_time = 0;
  2904. break;
  2905. case DC_ERROR:
  2906. default:
  2907. myrpt->dtmfbuf[0] = 0;
  2908. myrpt->dtmfidx = -1;
  2909. dtmf_time = 0;
  2910. break;
  2911. }
  2912. ast_mutex_unlock(&myrpt->lock);
  2913. if(res != DC_INDETERMINATE)
  2914. continue;
  2915. }
  2916. }
  2917. }
  2918. else
  2919. {
  2920. if ((!myrpt->callmode) && (c == myrpt->funcchar))
  2921. {
  2922. myrpt->callmode = 1;
  2923. myrpt->cidx = 0;
  2924. myrpt->exten[myrpt->cidx] = 0;
  2925. pthread_attr_init(&attr);
  2926. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  2927. ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
  2928. continue;
  2929. }
  2930. }
  2931. if (myrpt->callmode == 1)
  2932. {
  2933. myrpt->exten[myrpt->cidx++] = c;
  2934. myrpt->exten[myrpt->cidx] = 0;
  2935. /* if this exists */
  2936. if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
  2937. {
  2938. myrpt->callmode = 2;
  2939. rpt_telemetry(myrpt,PROC,NULL);
  2940. }
  2941. /* if can continue, do so */
  2942. if (ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) continue;
  2943. /* call has failed, inform user */
  2944. myrpt->callmode = 4;
  2945. continue;
  2946. }
  2947. if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
  2948. {
  2949. myrpt->mydtmf = f->subclass;
  2950. }
  2951. continue;
  2952. }
  2953. else if (f->frametype == AST_FRAME_CONTROL)
  2954. {
  2955. if (f->subclass == AST_CONTROL_HANGUP)
  2956. {
  2957. if (debug) printf("@@@@ rpt:Hung Up\n");
  2958. ast_frfree(f);
  2959. break;
  2960. }
  2961. /* if RX key */
  2962. if (f->subclass == AST_CONTROL_RADIO_KEY)
  2963. {
  2964. if (debug) printf("@@@@ rx key\n");
  2965. keyed = 1;
  2966. }
  2967. /* if RX un-key */
  2968. if (f->subclass == AST_CONTROL_RADIO_UNKEY)
  2969. {
  2970. if (debug) printf("@@@@ rx un-key\n");
  2971. if(keyed)
  2972. rpt_telemetry(myrpt,UNKEY,NULL);
  2973. keyed = 0;
  2974. }
  2975. }
  2976. ast_frfree(f);
  2977. continue;
  2978. }
  2979. if (who == myrpt->pchannel) /* if it was a read from pseudo */
  2980. {
  2981. f = ast_read(myrpt->pchannel);
  2982. if (!f)
  2983. {
  2984. if (debug) printf("@@@@ rpt:Hung Up\n");
  2985. break;
  2986. }
  2987. if (f->frametype == AST_FRAME_VOICE)
  2988. {
  2989. ast_write(myrpt->txpchannel,f);
  2990. }
  2991. if (f->frametype == AST_FRAME_CONTROL)
  2992. {
  2993. if (f->subclass == AST_CONTROL_HANGUP)
  2994. {
  2995. if (debug) printf("@@@@ rpt:Hung Up\n");
  2996. ast_frfree(f);
  2997. break;
  2998. }
  2999. }
  3000. ast_frfree(f);
  3001. continue;
  3002. }
  3003. if (who == myrpt->txchannel) /* if it was a read from tx */
  3004. {
  3005. f = ast_read(myrpt->txchannel);
  3006. if (!f)
  3007. {
  3008. if (debug) printf("@@@@ rpt:Hung Up\n");
  3009. break;
  3010. }
  3011. if (f->frametype == AST_FRAME_CONTROL)
  3012. {
  3013. if (f->subclass == AST_CONTROL_HANGUP)
  3014. {
  3015. if (debug) printf("@@@@ rpt:Hung Up\n");
  3016. ast_frfree(f);
  3017. break;
  3018. }
  3019. }
  3020. ast_frfree(f);
  3021. continue;
  3022. }
  3023. toexit = 0;
  3024. l = myrpt->links.next;
  3025. while(l != &myrpt->links)
  3026. {
  3027. if (who == l->chan) /* if it was a read from rx */
  3028. {
  3029. ast_mutex_lock(&myrpt->lock);
  3030. remrx = 0;
  3031. /* see if any other links are receiving */
  3032. m = myrpt->links.next;
  3033. while(m != &myrpt->links)
  3034. {
  3035. /* if not us, count it */
  3036. if ((m != l) && (m->lastrx)) remrx = 1;
  3037. m = m->next;
  3038. }
  3039. ast_mutex_unlock(&myrpt->lock);
  3040. totx = (((l->isremote) ? myrpt->localtx :
  3041. myrpt->exttx) || remrx) && l->mode;
  3042. if (l->lasttx != totx)
  3043. {
  3044. if (totx)
  3045. {
  3046. ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
  3047. }
  3048. else
  3049. {
  3050. ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
  3051. }
  3052. }
  3053. l->lasttx = totx;
  3054. f = ast_read(l->chan);
  3055. if (!f)
  3056. {
  3057. ast_mutex_lock(&myrpt->lock);
  3058. /* remove from queue */
  3059. remque((struct qelem *) l);
  3060. if (!strcmp(myrpt->cmdnode,l->name))
  3061. myrpt->cmdnode[0] = 0;
  3062. ast_mutex_unlock(&myrpt->lock);
  3063. rpt_telemetry(myrpt,REMDISC,l);
  3064. /* hang-up on call to device */
  3065. ast_hangup(l->chan);
  3066. ast_hangup(l->pchan);
  3067. free(l);
  3068. break;
  3069. }
  3070. if (f->frametype == AST_FRAME_VOICE)
  3071. {
  3072. ast_write(l->pchan,f);
  3073. }
  3074. if (f->frametype == AST_FRAME_TEXT)
  3075. {
  3076. handle_link_data(myrpt,l,f->data);
  3077. }
  3078. if (f->frametype == AST_FRAME_CONTROL)
  3079. {
  3080. if (f->subclass == AST_CONTROL_ANSWER)
  3081. {
  3082. l->connected = 1;
  3083. l->elaptime = -1;
  3084. rpt_telemetry(myrpt,CONNECTED,l);
  3085. }
  3086. /* if RX key */
  3087. if (f->subclass == AST_CONTROL_RADIO_KEY)
  3088. {
  3089. if (debug) printf("@@@@ rx key\n");
  3090. l->lastrx = 1;
  3091. }
  3092. /* if RX un-key */
  3093. if (f->subclass == AST_CONTROL_RADIO_UNKEY)
  3094. {
  3095. if (debug) printf("@@@@ rx un-key\n");
  3096. l->lastrx = 0;
  3097. }
  3098. if (f->subclass == AST_CONTROL_HANGUP)
  3099. {
  3100. ast_frfree(f);
  3101. ast_mutex_lock(&myrpt->lock);
  3102. /* remove from queue */
  3103. remque((struct qelem *) l);
  3104. if (!strcmp(myrpt->cmdnode,l->name))
  3105. myrpt->cmdnode[0] = 0;
  3106. ast_mutex_unlock(&myrpt->lock);
  3107. rpt_telemetry(myrpt,REMDISC,l);
  3108. /* hang-up on call to device */
  3109. ast_hangup(l->chan);
  3110. ast_hangup(l->pchan);
  3111. free(l);
  3112. break;
  3113. }
  3114. }
  3115. ast_frfree(f);
  3116. break;
  3117. }
  3118. if (who == l->pchan)
  3119. {
  3120. f = ast_read(l->pchan);
  3121. if (!f)
  3122. {
  3123. if (debug) printf("@@@@ rpt:Hung Up\n");
  3124. toexit = 1;
  3125. break;
  3126. }
  3127. if (f->frametype == AST_FRAME_VOICE)
  3128. {
  3129. ast_write(l->chan,f);
  3130. }
  3131. if (f->frametype == AST_FRAME_CONTROL)
  3132. {
  3133. if (f->subclass == AST_CONTROL_HANGUP)
  3134. {
  3135. if (debug) printf("@@@@ rpt:Hung Up\n");
  3136. ast_frfree(f);
  3137. toexit = 1;
  3138. break;
  3139. }
  3140. }
  3141. ast_frfree(f);
  3142. break;
  3143. }
  3144. l = l->next;
  3145. }
  3146. if (toexit) break;
  3147. if (who == myrpt->txpchannel) /* if it was a read from remote tx */
  3148. {
  3149. f = ast_read(myrpt->txpchannel);
  3150. if (!f)
  3151. {
  3152. if (debug) printf("@@@@ rpt:Hung Up\n");
  3153. break;
  3154. }
  3155. if (f->frametype == AST_FRAME_CONTROL)
  3156. {
  3157. if (f->subclass == AST_CONTROL_HANGUP)
  3158. {
  3159. if (debug) printf("@@@@ rpt:Hung Up\n");
  3160. ast_frfree(f);
  3161. break;
  3162. }
  3163. }
  3164. ast_frfree(f);
  3165. continue;
  3166. }
  3167. }
  3168. ast_mutex_lock(&myrpt->lock);
  3169. ast_hangup(myrpt->pchannel);
  3170. ast_hangup(myrpt->txpchannel);
  3171. if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
  3172. ast_hangup(myrpt->rxchannel);
  3173. l = myrpt->links.next;
  3174. while(l != &myrpt->links)
  3175. {
  3176. struct rpt_link *ll = l;
  3177. /* remove from queue */
  3178. remque((struct qelem *) l);
  3179. /* hang-up on call to device */
  3180. ast_hangup(l->chan);
  3181. ast_hangup(l->pchan);
  3182. l = l->next;
  3183. free(ll);
  3184. }
  3185. ast_mutex_unlock(&myrpt->lock);
  3186. if (debug) printf("@@@@ rpt:Hung up channel\n");
  3187. myrpt->rpt_thread = AST_PTHREADT_STOP;
  3188. pthread_exit(NULL);
  3189. return NULL;
  3190. }
  3191. static void *rpt_master(void *ignore)
  3192. {
  3193. char *this,*val;
  3194. struct ast_variable *vp;
  3195. int i,j,n,longestnode;
  3196. pthread_attr_t attr;
  3197. /* start with blank config */
  3198. memset(&rpt_vars,0,sizeof(rpt_vars));
  3199. cfg = ast_load("rpt.conf");
  3200. if (!cfg) {
  3201. ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n");
  3202. pthread_exit(NULL);
  3203. }
  3204. /*
  3205. * Go through the node list to determine the longest node
  3206. */
  3207. longestnode = 0;
  3208. vp = ast_variable_browse(cfg, NODES);
  3209. while(vp){
  3210. j = strlen(vp->name);
  3211. if (j > longestnode)
  3212. longestnode = j;
  3213. vp = vp->next;
  3214. }
  3215. /* go thru all the specified repeaters */
  3216. this = NULL;
  3217. n = 0;
  3218. while((this = ast_category_browse(cfg,this)) != NULL)
  3219. {
  3220. for(i = 0 ; i < strlen(this) ; i++){
  3221. if((this[i] < '0') || (this[i] > '9'))
  3222. break;
  3223. }
  3224. if(i != strlen(this))
  3225. continue; /* Not a node defn */
  3226. ast_log(LOG_DEBUG,"Loading config for repeater %s\n",this);
  3227. ast_mutex_init(&rpt_vars[n].lock);
  3228. rpt_vars[n].tele.next = &rpt_vars[n].tele;
  3229. rpt_vars[n].tele.prev = &rpt_vars[n].tele;
  3230. rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
  3231. rpt_vars[n].name = this;
  3232. rpt_vars[n].rxchanname = ast_variable_retrieve(cfg,this,"rxchannel");
  3233. rpt_vars[n].txchanname = ast_variable_retrieve(cfg,this,"txchannel");
  3234. rpt_vars[n].ourcontext = ast_variable_retrieve(cfg,this,"context");
  3235. if (!rpt_vars[n].ourcontext) rpt_vars[n].ourcontext = this;
  3236. rpt_vars[n].ourcallerid = ast_variable_retrieve(cfg,this,"callerid");
  3237. rpt_vars[n].acctcode = ast_variable_retrieve(cfg,this,"accountcode");
  3238. rpt_vars[n].ident = ast_variable_retrieve(cfg,this,"idrecording");
  3239. val = ast_variable_retrieve(cfg,this,"hangtime");
  3240. if (val) rpt_vars[n].hangtime = atoi(val);
  3241. else rpt_vars[n].hangtime = HANGTIME;
  3242. val = ast_variable_retrieve(cfg,this,"totime");
  3243. if (val) rpt_vars[n].totime = atoi(val);
  3244. else rpt_vars[n].totime = TOTIME;
  3245. rpt_vars[n].idtime = retrieve_astcfgint( this, "idtime", 60000, 2400000, IDTIME); /* Enforce a min max */
  3246. rpt_vars[n].politeid = retrieve_astcfgint( this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
  3247. rpt_vars[n].remote = ast_variable_retrieve(cfg,this,"remote");
  3248. rpt_vars[n].tonezone = ast_variable_retrieve(cfg,this,"tonezone");
  3249. val = ast_variable_retrieve(cfg,this,"iobase");
  3250. if (val) rpt_vars[n].iobase = atoi(val);
  3251. else rpt_vars[n].iobase = DEFAULT_IOBASE;
  3252. rpt_vars[n].simple = 0;
  3253. rpt_vars[n].functions = ast_variable_retrieve(cfg,this,"functions");
  3254. if (!rpt_vars[n].functions)
  3255. {
  3256. rpt_vars[n].functions = FUNCTIONS;
  3257. rpt_vars[n].simple = 1;
  3258. }
  3259. rpt_vars[n].link_functions = ast_variable_retrieve(cfg,this,"link_functions");
  3260. if (!rpt_vars[n].link_functions)
  3261. rpt_vars[n].link_functions = rpt_vars[n].functions;
  3262. val = ast_variable_retrieve(cfg,this,"funcchar");
  3263. if (!val) rpt_vars[n].funcchar = FUNCCHAR; else
  3264. rpt_vars[n].funcchar = *val;
  3265. val = ast_variable_retrieve(cfg,this,"endchar");
  3266. if (!val) rpt_vars[n].endchar = ENDCHAR; else
  3267. rpt_vars[n].endchar = *val;
  3268. n++;
  3269. }
  3270. nrpts = n;
  3271. ast_log(LOG_DEBUG, "Total of %d repeaters configured.\n",n);
  3272. /* start em all */
  3273. for(i = 0; i < n; i++)
  3274. {
  3275. rpt_vars[i].longestnode = longestnode;
  3276. /*
  3277. * For this repeater, Determine the length of the longest function
  3278. */
  3279. rpt_vars[i].longestfunc = 0;
  3280. vp = ast_variable_browse(cfg, rpt_vars[i].functions);
  3281. while(vp){
  3282. j = strlen(vp->name);
  3283. if (j > rpt_vars[i].longestfunc)
  3284. rpt_vars[i].longestfunc = j;
  3285. vp = vp->next;
  3286. }
  3287. /*
  3288. * For this repeater, Determine the length of the longest function
  3289. */
  3290. rpt_vars[i].link_longestfunc = 0;
  3291. vp = ast_variable_browse(cfg, rpt_vars[i].link_functions);
  3292. while(vp){
  3293. j = strlen(vp->name);
  3294. if (j > rpt_vars[i].link_longestfunc)
  3295. rpt_vars[i].link_longestfunc = j;
  3296. vp = vp->next;
  3297. }
  3298. if (!rpt_vars[i].rxchanname)
  3299. {
  3300. ast_log(LOG_WARNING,"Did not specify rxchanname for node %s\n",rpt_vars[i].name);
  3301. pthread_exit(NULL);
  3302. }
  3303. /* if is a remote, dont start one for it */
  3304. if (rpt_vars[i].remote)
  3305. {
  3306. strncpy(rpt_vars[i].freq, "146.460", sizeof(rpt_vars[i].freq) - 1);
  3307. strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
  3308. rpt_vars[i].offset = REM_SIMPLEX;
  3309. rpt_vars[i].powerlevel = REM_MEDPWR;
  3310. continue;
  3311. }
  3312. if (!rpt_vars[i].ident)
  3313. {
  3314. ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name);
  3315. pthread_exit(NULL);
  3316. }
  3317. pthread_attr_init(&attr);
  3318. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  3319. ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
  3320. }
  3321. usleep(500000);
  3322. for(;;)
  3323. {
  3324. /* Now monitor each thread, and restart it if necessary */
  3325. for(i = 0; i < n; i++)
  3326. {
  3327. int rv;
  3328. if (rpt_vars[i].remote) continue;
  3329. if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP)
  3330. rv = -1;
  3331. else
  3332. rv = pthread_kill(rpt_vars[i].rpt_thread,0);
  3333. if (rv)
  3334. {
  3335. pthread_attr_init(&attr);
  3336. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  3337. ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
  3338. ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
  3339. }
  3340. }
  3341. usleep(2000000);
  3342. }
  3343. pthread_exit(NULL);
  3344. }
  3345. static int rpt_exec(struct ast_channel *chan, void *data)
  3346. {
  3347. int res=-1,i,keyed = 0,rem_totx,n;
  3348. struct localuser *u;
  3349. char tmp[256];
  3350. char *options,*stringp,*tele;
  3351. struct rpt *myrpt;
  3352. struct ast_frame *f;
  3353. struct ast_channel *who;
  3354. struct ast_channel *cs[20];
  3355. struct rpt_link *l;
  3356. ZT_CONFINFO ci; /* conference info */
  3357. int ms,elap;
  3358. if (!data || ast_strlen_zero((char *)data)) {
  3359. ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
  3360. return -1;
  3361. }
  3362. strncpy(tmp, (char *)data, sizeof(tmp)-1);
  3363. stringp=tmp;
  3364. strsep(&stringp, "|");
  3365. options = strsep(&stringp, "|");
  3366. myrpt = NULL;
  3367. /* see if we can find our specified one */
  3368. for(i = 0; i < nrpts; i++)
  3369. {
  3370. /* if name matches, assign it and exit loop */
  3371. if (!strcmp(tmp,rpt_vars[i].name))
  3372. {
  3373. myrpt = &rpt_vars[i];
  3374. break;
  3375. }
  3376. }
  3377. if (myrpt == NULL)
  3378. {
  3379. ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp);
  3380. return -1;
  3381. }
  3382. /* if is not a remote */
  3383. if (!myrpt->remote)
  3384. {
  3385. char *b,*b1;
  3386. /* look at callerid to see what node this comes from */
  3387. if (!chan->callerid) /* if doesnt have callerid */
  3388. {
  3389. ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
  3390. return -1;
  3391. }
  3392. ast_callerid_parse(chan->callerid,&b,&b1);
  3393. ast_shrink_phone_number(b1);
  3394. if (!strcmp(myrpt->name,b1))
  3395. {
  3396. ast_log(LOG_WARNING, "Trying to link to self!!\n");
  3397. return -1;
  3398. }
  3399. ast_mutex_lock(&myrpt->lock);
  3400. l = myrpt->links.next;
  3401. /* try to find this one in queue */
  3402. while(l != &myrpt->links)
  3403. {
  3404. /* if found matching string */
  3405. if (!strcmp(l->name,b1)) break;
  3406. l = l->next;
  3407. }
  3408. /* if found */
  3409. if (l != &myrpt->links)
  3410. {
  3411. /* remove from queue */
  3412. remque((struct qelem *) l);
  3413. ast_mutex_unlock(&myrpt->lock);
  3414. /* hang-up on call to device */
  3415. ast_hangup(l->chan);
  3416. ast_hangup(l->pchan);
  3417. free(l);
  3418. usleep(500000);
  3419. } else
  3420. ast_mutex_unlock(&myrpt->lock);
  3421. /* establish call in tranceive mode */
  3422. l = malloc(sizeof(struct rpt_link));
  3423. if (!l)
  3424. {
  3425. ast_log(LOG_WARNING, "Unable to malloc\n");
  3426. pthread_exit(NULL);
  3427. }
  3428. /* zero the silly thing */
  3429. memset((char *)l,0,sizeof(struct rpt_link));
  3430. l->mode = 1;
  3431. strncpy(l->name,b1,MAXNODESTR - 1);
  3432. l->isremote = 0;
  3433. l->chan = chan;
  3434. l->connected = 1;
  3435. ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
  3436. ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
  3437. /* allocate a pseudo-channel thru asterisk */
  3438. l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo");
  3439. if (!l->pchan)
  3440. {
  3441. fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
  3442. pthread_exit(NULL);
  3443. }
  3444. ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
  3445. ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
  3446. /* make a conference for the tx */
  3447. ci.chan = 0;
  3448. ci.confno = myrpt->conf;
  3449. ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
  3450. /* first put the channel on the conference in proper mode */
  3451. if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1)
  3452. {
  3453. ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
  3454. pthread_exit(NULL);
  3455. }
  3456. ast_mutex_lock(&myrpt->lock);
  3457. /* insert at end of queue */
  3458. insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
  3459. ast_mutex_unlock(&myrpt->lock);
  3460. if (chan->_state != AST_STATE_UP) {
  3461. ast_answer(chan);
  3462. }
  3463. return AST_PBX_KEEPALIVE;
  3464. }
  3465. ast_mutex_lock(&myrpt->lock);
  3466. /* if remote, error if anyone else already linked */
  3467. if (myrpt->remoteon)
  3468. {
  3469. ast_mutex_unlock(&myrpt->lock);
  3470. usleep(500000);
  3471. ast_mutex_lock(&myrpt->lock);
  3472. if (myrpt->remoteon)
  3473. {
  3474. ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
  3475. return -1;
  3476. }
  3477. }
  3478. myrpt->remoteon = 1;
  3479. if (ioperm(myrpt->iobase,1,1) == -1)
  3480. {
  3481. ast_mutex_unlock(&myrpt->lock);
  3482. ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->iobase);
  3483. return -1;
  3484. }
  3485. LOCAL_USER_ADD(u);
  3486. tele = strchr(myrpt->rxchanname,'/');
  3487. if (!tele)
  3488. {
  3489. fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
  3490. ast_mutex_unlock(&myrpt->lock);
  3491. pthread_exit(NULL);
  3492. }
  3493. *tele++ = 0;
  3494. myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele);
  3495. if (myrpt->rxchannel)
  3496. {
  3497. ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
  3498. ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
  3499. myrpt->rxchannel->whentohangup = 0;
  3500. myrpt->rxchannel->appl = "Apprpt";
  3501. myrpt->rxchannel->data = "(Link Rx)";
  3502. if (option_verbose > 2)
  3503. ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
  3504. myrpt->rxchanname,tele,myrpt->rxchannel->name);
  3505. ast_mutex_unlock(&myrpt->lock);
  3506. ast_call(myrpt->rxchannel,tele,999);
  3507. ast_mutex_lock(&myrpt->lock);
  3508. }
  3509. else
  3510. {
  3511. fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
  3512. ast_mutex_unlock(&myrpt->lock);
  3513. pthread_exit(NULL);
  3514. }
  3515. *--tele = '/';
  3516. if (myrpt->txchanname)
  3517. {
  3518. tele = strchr(myrpt->txchanname,'/');
  3519. if (!tele)
  3520. {
  3521. fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
  3522. ast_mutex_unlock(&myrpt->lock);
  3523. pthread_exit(NULL);
  3524. }
  3525. *tele++ = 0;
  3526. myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele);
  3527. if (myrpt->txchannel)
  3528. {
  3529. ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
  3530. ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
  3531. myrpt->txchannel->whentohangup = 0;
  3532. myrpt->txchannel->appl = "Apprpt";
  3533. myrpt->txchannel->data = "(Link Tx)";
  3534. if (option_verbose > 2)
  3535. ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
  3536. myrpt->txchanname,tele,myrpt->txchannel->name);
  3537. ast_mutex_unlock(&myrpt->lock);
  3538. ast_call(myrpt->txchannel,tele,999);
  3539. ast_mutex_lock(&myrpt->lock);
  3540. }
  3541. else
  3542. {
  3543. fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
  3544. ast_mutex_unlock(&myrpt->lock);
  3545. pthread_exit(NULL);
  3546. }
  3547. *--tele = '/';
  3548. }
  3549. else
  3550. {
  3551. myrpt->txchannel = myrpt->rxchannel;
  3552. }
  3553. myrpt->remoterx = 0;
  3554. myrpt->remotetx = 0;
  3555. myrpt->remoteon = 1;
  3556. myrpt->dtmfidx = -1;
  3557. myrpt->dtmfbuf[0] = 0;
  3558. myrpt->dtmf_time_rem = 0;
  3559. ast_mutex_unlock(&myrpt->lock);
  3560. setrbi(myrpt);
  3561. ast_set_write_format(chan, AST_FORMAT_SLINEAR);
  3562. ast_set_read_format(chan, AST_FORMAT_SLINEAR);
  3563. /* if we are on 2w loop and are a remote, turn EC on */
  3564. if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
  3565. {
  3566. i = 128;
  3567. ioctl(myrpt->rxchannel->fds[0],ZT_ECHOCANCEL,&i);
  3568. }
  3569. if (chan->_state != AST_STATE_UP) {
  3570. ast_answer(chan);
  3571. }
  3572. n = 0;
  3573. cs[n++] = chan;
  3574. cs[n++] = myrpt->rxchannel;
  3575. if (myrpt->rxchannel != myrpt->txchannel)
  3576. cs[n++] = myrpt->txchannel;
  3577. for(;;)
  3578. {
  3579. if (ast_check_hangup(chan)) break;
  3580. if (ast_check_hangup(myrpt->rxchannel)) break;
  3581. ms = MSWAIT;
  3582. who = ast_waitfor_n(cs,n,&ms);
  3583. if (who == NULL) ms = 0;
  3584. elap = MSWAIT - ms;
  3585. if (!ms) continue;
  3586. rem_totx = keyed;
  3587. if (rem_totx && (!myrpt->remotetx)) /* Remote base radio TX key */
  3588. {
  3589. myrpt->remotetx = 1;
  3590. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
  3591. }
  3592. if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */
  3593. {
  3594. myrpt->remotetx = 0;
  3595. ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
  3596. }
  3597. if (who == chan) /* if it was a read from incomming */
  3598. {
  3599. f = ast_read(chan);
  3600. if (!f)
  3601. {
  3602. if (debug) printf("@@@@ link:Hung Up\n");
  3603. break;
  3604. }
  3605. if (f->frametype == AST_FRAME_VOICE)
  3606. {
  3607. /* if not transmitting, zero-out audio */
  3608. if (!myrpt->remotetx)
  3609. memset(f->data,0,f->datalen);
  3610. ast_write(myrpt->txchannel,f);
  3611. }
  3612. else if (f->frametype == AST_FRAME_TEXT)
  3613. {
  3614. myrpt->remchannel = chan; /* Save copy of channel */
  3615. if (handle_remote_data(myrpt,f->data) == -1)
  3616. {
  3617. if (debug) printf("@@@@ rpt:Hung Up\n");
  3618. ast_frfree(f);
  3619. break;
  3620. }
  3621. }
  3622. else if (f->frametype == AST_FRAME_CONTROL)
  3623. {
  3624. if (f->subclass == AST_CONTROL_HANGUP)
  3625. {
  3626. if (debug) printf("@@@@ rpt:Hung Up\n");
  3627. ast_frfree(f);
  3628. break;
  3629. }
  3630. /* if RX key */
  3631. if (f->subclass == AST_CONTROL_RADIO_KEY)
  3632. {
  3633. if (debug) printf("@@@@ rx key\n");
  3634. keyed = 1;
  3635. }
  3636. /* if RX un-key */
  3637. if (f->subclass == AST_CONTROL_RADIO_UNKEY)
  3638. {
  3639. if (debug) printf("@@@@ rx un-key\n");
  3640. keyed = 0;
  3641. }
  3642. }
  3643. ast_frfree(f);
  3644. continue;
  3645. }
  3646. if (who == myrpt->rxchannel) /* if it was a read from radio */
  3647. {
  3648. f = ast_read(myrpt->rxchannel);
  3649. if (!f)
  3650. {
  3651. if (debug) printf("@@@@ link:Hung Up\n");
  3652. break;
  3653. }
  3654. if (f->frametype == AST_FRAME_VOICE)
  3655. {
  3656. if ((myrpt->remote) && (myrpt->remotetx))
  3657. memset(f->data,0,f->datalen);
  3658. ast_write(chan,f);
  3659. }
  3660. else if (f->frametype == AST_FRAME_CONTROL)
  3661. {
  3662. if (f->subclass == AST_CONTROL_HANGUP)
  3663. {
  3664. if (debug) printf("@@@@ rpt:Hung Up\n");
  3665. ast_frfree(f);
  3666. break;
  3667. }
  3668. /* if RX key */
  3669. if (f->subclass == AST_CONTROL_RADIO_KEY)
  3670. {
  3671. if (debug) printf("@@@@ remote rx key\n");
  3672. if (!myrpt->remotetx)
  3673. {
  3674. ast_indicate(chan,AST_CONTROL_RADIO_KEY);
  3675. myrpt->remoterx = 1;
  3676. }
  3677. }
  3678. /* if RX un-key */
  3679. if (f->subclass == AST_CONTROL_RADIO_UNKEY)
  3680. {
  3681. if (debug) printf("@@@@ remote rx un-key\n");
  3682. if (!myrpt->remotetx)
  3683. {
  3684. ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
  3685. myrpt->remoterx = 0;
  3686. }
  3687. }
  3688. }
  3689. ast_frfree(f);
  3690. continue;
  3691. }
  3692. if ((myrpt->rxchannel != myrpt->txchannel) &&
  3693. (who == myrpt->txchannel)) /* do this cuz you have to */
  3694. {
  3695. f = ast_read(myrpt->txchannel);
  3696. if (!f)
  3697. {
  3698. if (debug) printf("@@@@ link:Hung Up\n");
  3699. break;
  3700. }
  3701. if (f->frametype == AST_FRAME_CONTROL)
  3702. {
  3703. if (f->subclass == AST_CONTROL_HANGUP)
  3704. {
  3705. if (debug) printf("@@@@ rpt:Hung Up\n");
  3706. ast_frfree(f);
  3707. break;
  3708. }
  3709. }
  3710. ast_frfree(f);
  3711. continue;
  3712. }
  3713. }
  3714. ast_mutex_lock(&myrpt->lock);
  3715. if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel);
  3716. ast_hangup(myrpt->rxchannel);
  3717. myrpt->remoteon = 0;
  3718. ast_mutex_unlock(&myrpt->lock);
  3719. LOCAL_USER_REMOVE(u);
  3720. return res;
  3721. }
  3722. int unload_module(void)
  3723. {
  3724. int i;
  3725. STANDARD_HANGUP_LOCALUSERS;
  3726. for(i = 0; i < nrpts; i++) {
  3727. if (!strcmp(rpt_vars[i].name,NODES)) continue;
  3728. ast_mutex_destroy(&rpt_vars[i].lock);
  3729. }
  3730. return ast_unregister_application(app);
  3731. return 0;
  3732. }
  3733. int load_module(void)
  3734. {
  3735. ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL);
  3736. return ast_register_application(app, rpt_exec, synopsis, descrip);
  3737. }
  3738. char *description(void)
  3739. {
  3740. return tdesc;
  3741. }
  3742. int usecount(void)
  3743. {
  3744. int res;
  3745. STANDARD_USECOUNT(res);
  3746. return res;
  3747. }
  3748. char *key()
  3749. {
  3750. return ASTERISK_GPL_KEY;
  3751. }