mod_freetdm.c 185 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715
  1. /*
  2. * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  3. * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
  4. *
  5. * Version: MPL 1.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Anthony Minessale II <anthm@freeswitch.org>
  21. * Portions created by the Initial Developer are Copyright (C)
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. *
  26. * Anthony Minessale II <anthm@freeswitch.org>
  27. * Moises Silva <moy@sangoma.com>
  28. * David Yat Sin <dyatsin@sangoma.com>
  29. * James Zhang <jzhang@sangoma.com>
  30. * Gideon Sadan <gsadan@sangoma.com>
  31. *
  32. * mod_freetdm.c -- FreeTDM Endpoint Module
  33. *
  34. */
  35. #include <switch.h>
  36. #include "freetdm.h"
  37. //#define BACKTRACE_DEBUG
  38. #define FREETDM_LIMIT_REALM "__freetdm"
  39. #define FREETDM_VAR_PREFIX "freetdm_"
  40. #define FREETDM_VAR_PREFIX_LEN (sizeof(FREETDM_VAR_PREFIX)-1)
  41. /* How many consecutive IO errors before giving up */
  42. #define FTDM_MAX_READ_WRITE_ERRORS 10
  43. #define get_ss7_config_node(_cfg, _confname) _get_ss7_config_node(cfg, confname, "ISUP")
  44. SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load);
  45. SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown);
  46. SWITCH_MODULE_DEFINITION(mod_freetdm, mod_freetdm_load, mod_freetdm_shutdown, NULL);
  47. switch_endpoint_interface_t *freetdm_endpoint_interface;
  48. static switch_memory_pool_t *module_pool = NULL;
  49. typedef enum {
  50. ANALOG_OPTION_NONE = 0,
  51. ANALOG_OPTION_3WAY = (1 << 0),
  52. ANALOG_OPTION_CALL_SWAP = (1 << 1)
  53. } analog_option_t;
  54. typedef enum {
  55. FTDM_LIMIT_RESET_ON_TIMEOUT = 0,
  56. FTDM_LIMIT_RESET_ON_ANSWER = 1
  57. } limit_reset_event_t;
  58. typedef enum {
  59. TFLAG_IO = (1 << 0),
  60. TFLAG_DTMF = (1 << 1),
  61. TFLAG_CODEC = (1 << 2),
  62. TFLAG_BREAK = (1 << 3),
  63. TFLAG_HOLD = (1 << 4),
  64. TFLAG_DEAD = (1 << 5),
  65. TFLAG_TRANSFER = (1 << 6),
  66. } TFLAGS;
  67. static struct {
  68. int debug;
  69. char *dialplan;
  70. char *codec_string;
  71. char *codec_order[SWITCH_MAX_CODECS];
  72. int codec_order_last;
  73. char *codec_rates_string;
  74. char *codec_rates[SWITCH_MAX_CODECS];
  75. int codec_rates_last;
  76. unsigned int flags;
  77. int fd;
  78. int calls;
  79. char hold_music[256];
  80. switch_mutex_t *mutex;
  81. analog_option_t analog_options;
  82. switch_hash_t *ss7_configs;
  83. int sip_headers;
  84. uint8_t crash_on_assert;
  85. uint8_t fail_on_error;
  86. uint8_t config_error;
  87. } globals;
  88. /* private data attached to each fs session */
  89. struct private_object {
  90. unsigned int flags;
  91. switch_codec_t read_codec;
  92. switch_codec_t write_codec;
  93. switch_frame_t read_frame;
  94. unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
  95. switch_frame_t cng_frame;
  96. unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
  97. switch_core_session_t *session;
  98. switch_caller_profile_t *caller_profile;
  99. unsigned int codec;
  100. unsigned int codecs;
  101. unsigned short samprate;
  102. switch_mutex_t *mutex;
  103. switch_mutex_t *flag_mutex;
  104. ftdm_channel_t *ftdmchan;
  105. uint32_t write_error;
  106. uint32_t read_error;
  107. char network_peer_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
  108. };
  109. /* private data attached to FTDM channels (only FXS for now) */
  110. typedef struct chan_pvt {
  111. unsigned int flags;
  112. } chan_pvt_t;
  113. typedef struct private_object private_t;
  114. struct span_config {
  115. ftdm_span_t *span;
  116. char dialplan[80];
  117. char context[80];
  118. char dial_regex[256];
  119. char fail_dial_regex[256];
  120. char hold_music[256];
  121. char type[256];
  122. analog_option_t analog_options;
  123. const char *limit_backend;
  124. int limit_calls;
  125. int limit_seconds;
  126. limit_reset_event_t limit_reset_event;
  127. /* digital codec and digital sampling rate are used to configure the codec
  128. * when bearer capability is set to unrestricted digital */
  129. const char *digital_codec;
  130. int digital_sampling_rate;
  131. chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
  132. };
  133. static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}};
  134. static switch_status_t channel_on_init(switch_core_session_t *session);
  135. static switch_status_t channel_on_hangup(switch_core_session_t *session);
  136. static switch_status_t channel_on_destroy(switch_core_session_t *session);
  137. static switch_status_t channel_on_routing(switch_core_session_t *session);
  138. static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
  139. static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
  140. static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
  141. switch_caller_profile_t *outbound_profile,
  142. switch_core_session_t **new_session,
  143. switch_memory_pool_t **pool,
  144. switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
  145. static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
  146. static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
  147. static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
  148. static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name);
  149. ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp);
  150. void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
  151. void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
  152. #if 0
  153. void ctdm_init(switch_loadable_module_interface_t *module_interface);
  154. #endif
  155. static switch_core_session_t *ftdm_channel_get_session(ftdm_channel_t *channel, int32_t id)
  156. {
  157. switch_core_session_t *session = NULL;
  158. const char *token = ftdm_channel_get_token(channel, id);
  159. if (!zstr(token)) {
  160. if (!(session = switch_core_session_locate(token))) {
  161. ftdm_channel_clear_token(channel, token);
  162. }
  163. }
  164. return session;
  165. }
  166. static const char *ftdm_channel_get_uuid(ftdm_channel_t *channel, int32_t id)
  167. {
  168. return ftdm_channel_get_token(channel, id);
  169. }
  170. static void stop_hold(switch_core_session_t *session_a, const char *uuid)
  171. {
  172. switch_core_session_t *session;
  173. switch_channel_t *channel, *channel_a;
  174. if (!uuid) {
  175. return;
  176. }
  177. if ((session = switch_core_session_locate(uuid))) {
  178. channel = switch_core_session_get_channel(session);
  179. if (switch_channel_test_flag(channel, CF_HOLD)) {
  180. channel_a = switch_core_session_get_channel(session_a);
  181. switch_ivr_unhold(session);
  182. switch_channel_clear_flag(channel_a, CF_SUSPEND);
  183. switch_channel_clear_flag(channel_a, CF_HOLD);
  184. } else {
  185. switch_channel_stop_broadcast(channel);
  186. switch_channel_wait_for_flag(channel, CF_BROADCAST, SWITCH_FALSE, 2000, NULL);
  187. }
  188. switch_core_session_rwunlock(session);
  189. }
  190. }
  191. static void start_hold(ftdm_channel_t *ftdmchan, switch_core_session_t *session_a, const char *uuid, const char *stream)
  192. {
  193. switch_core_session_t *session;
  194. switch_channel_t *channel, *channel_a;
  195. int32_t spanid = 0;
  196. if (!uuid) {
  197. return;
  198. }
  199. spanid = ftdm_channel_get_span_id(ftdmchan);
  200. if ((session = switch_core_session_locate(uuid))) {
  201. channel = switch_core_session_get_channel(session);
  202. if (zstr(stream)) {
  203. if (!strcasecmp(globals.hold_music, "indicate_hold")) {
  204. stream = "indicate_hold";
  205. }
  206. if (!strcasecmp(SPAN_CONFIG[spanid].hold_music, "indicate_hold")) {
  207. stream = "indicate_hold";
  208. }
  209. }
  210. if (zstr(stream)) {
  211. stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE);
  212. }
  213. if (zstr(stream)) {
  214. stream = SPAN_CONFIG[spanid].hold_music;
  215. }
  216. if (zstr(stream)) {
  217. stream = globals.hold_music;
  218. }
  219. if (zstr(stream) && !(stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
  220. stream = globals.hold_music;
  221. }
  222. if (!zstr(stream)) {
  223. if (!strcasecmp(stream, "indicate_hold")) {
  224. channel_a = switch_core_session_get_channel(session_a);
  225. switch_ivr_hold_uuid(uuid, NULL, 0);
  226. switch_channel_set_flag(channel_a, CF_SUSPEND);
  227. switch_channel_set_flag(channel_a, CF_HOLD);
  228. } else {
  229. switch_ivr_broadcast(switch_core_session_get_uuid(session), stream, SMF_ECHO_ALEG | SMF_LOOP);
  230. }
  231. }
  232. switch_core_session_rwunlock(session);
  233. }
  234. }
  235. static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bcast) {
  236. uint32_t i = 0;
  237. switch_core_session_t *session;
  238. switch_channel_t *channel;
  239. private_t *tech_pvt;
  240. uint32_t tokencnt = ftdm_channel_get_token_count(ftdmchan);
  241. for (i = 0; i < tokencnt; i++) {
  242. if ((session = ftdm_channel_get_session(ftdmchan, i))) {
  243. const char *buuid;
  244. tech_pvt = switch_core_session_get_private(session);
  245. channel = switch_core_session_get_channel(session);
  246. buuid = switch_channel_get_partner_uuid(channel);
  247. if (tokencnt == 1 && flash) {
  248. if (switch_test_flag(tech_pvt, TFLAG_HOLD)) {
  249. stop_hold(session, buuid);
  250. switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
  251. } else {
  252. start_hold(ftdmchan, session, buuid, bcast);
  253. switch_set_flag_locked(tech_pvt, TFLAG_HOLD);
  254. }
  255. } else if (i) {
  256. start_hold(ftdmchan, session, buuid, bcast);
  257. switch_set_flag_locked(tech_pvt, TFLAG_HOLD);
  258. } else {
  259. stop_hold(session, buuid);
  260. switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
  261. if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
  262. switch_channel_mark_answered(channel);
  263. }
  264. }
  265. switch_core_session_rwunlock(session);
  266. }
  267. }
  268. }
  269. static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data)
  270. {
  271. const char *dname = NULL;
  272. uint32_t interval = 0, srate = 8000;
  273. uint32_t span_id;
  274. ftdm_codec_t codec;
  275. tech_pvt->ftdmchan = ftdmchan;
  276. tech_pvt->read_frame.data = tech_pvt->databuf;
  277. tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
  278. tech_pvt->cng_frame.data = tech_pvt->cng_databuf;
  279. tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf);
  280. tech_pvt->cng_frame.flags = SFF_CNG;
  281. tech_pvt->cng_frame.codec = &tech_pvt->read_codec;
  282. memset(tech_pvt->cng_frame.data, 255, tech_pvt->cng_frame.buflen);
  283. switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
  284. switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
  285. switch_core_session_set_private(session, tech_pvt);
  286. tech_pvt->session = session;
  287. if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
  288. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
  289. return SWITCH_STATUS_GENERR;
  290. }
  291. span_id = ftdm_channel_get_span_id(ftdmchan);
  292. if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED
  293. && SPAN_CONFIG[span_id].digital_codec) {
  294. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing digital call with codec %s at %dhz.\n",
  295. SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate);
  296. dname = SPAN_CONFIG[span_id].digital_codec;
  297. srate = SPAN_CONFIG[span_id].digital_sampling_rate;
  298. goto init_codecs;
  299. }
  300. if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) {
  301. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
  302. return SWITCH_STATUS_GENERR;
  303. }
  304. switch (codec) {
  305. case FTDM_CODEC_ULAW:
  306. {
  307. dname = "PCMU";
  308. }
  309. break;
  310. case FTDM_CODEC_ALAW:
  311. {
  312. dname = "PCMA";
  313. }
  314. break;
  315. case FTDM_CODEC_SLIN:
  316. {
  317. dname = "L16";
  318. }
  319. break;
  320. default:
  321. {
  322. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
  323. return SWITCH_STATUS_GENERR;
  324. }
  325. }
  326. init_codecs:
  327. if (switch_core_codec_init(&tech_pvt->read_codec,
  328. dname,
  329. NULL,
  330. NULL,
  331. srate,
  332. interval,
  333. 1,
  334. SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
  335. NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
  336. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
  337. return SWITCH_STATUS_GENERR;
  338. } else {
  339. if (switch_core_codec_init(&tech_pvt->write_codec,
  340. dname,
  341. NULL,
  342. NULL,
  343. srate,
  344. interval,
  345. 1,
  346. SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
  347. NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
  348. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
  349. switch_core_codec_destroy(&tech_pvt->read_codec);
  350. return SWITCH_STATUS_GENERR;
  351. }
  352. }
  353. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set codec %s %dms\n", dname, interval);
  354. switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
  355. switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
  356. switch_set_flag_locked(tech_pvt, TFLAG_CODEC);
  357. tech_pvt->read_frame.codec = &tech_pvt->read_codec;
  358. switch_set_flag_locked(tech_pvt, TFLAG_IO);
  359. return SWITCH_STATUS_SUCCESS;
  360. }
  361. static switch_status_t channel_on_init(switch_core_session_t *session)
  362. {
  363. switch_channel_t *channel;
  364. private_t *tech_pvt = NULL;
  365. tech_pvt = switch_core_session_get_private(session);
  366. assert(tech_pvt != NULL);
  367. channel = switch_core_session_get_channel(session);
  368. assert(channel != NULL);
  369. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  370. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  371. return SWITCH_STATUS_SUCCESS;
  372. }
  373. /* Move channel's state machine to ROUTING */
  374. switch_channel_set_state(channel, CS_ROUTING);
  375. switch_mutex_lock(globals.mutex);
  376. globals.calls++;
  377. switch_mutex_unlock(globals.mutex);
  378. //switch_channel_set_flag(channel, CF_ACCEPT_CNG);
  379. return SWITCH_STATUS_SUCCESS;
  380. }
  381. static switch_status_t channel_on_routing(switch_core_session_t *session)
  382. {
  383. switch_channel_t *channel = NULL;
  384. private_t *tech_pvt = NULL;
  385. channel = switch_core_session_get_channel(session);
  386. switch_assert(channel != NULL);
  387. tech_pvt = switch_core_session_get_private(session);
  388. switch_assert(tech_pvt != NULL);
  389. switch_assert(tech_pvt->ftdmchan != NULL);
  390. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
  391. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
  392. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED);
  393. }
  394. return SWITCH_STATUS_SUCCESS;
  395. }
  396. static switch_status_t channel_on_execute(switch_core_session_t *session)
  397. {
  398. switch_channel_t *channel = NULL;
  399. private_t *tech_pvt = NULL;
  400. channel = switch_core_session_get_channel(session);
  401. switch_assert(channel != NULL);
  402. tech_pvt = switch_core_session_get_private(session);
  403. switch_assert(tech_pvt != NULL);
  404. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
  405. return SWITCH_STATUS_SUCCESS;
  406. }
  407. static switch_status_t channel_on_destroy(switch_core_session_t *session)
  408. {
  409. private_t *tech_pvt = NULL;
  410. if ((tech_pvt = switch_core_session_get_private(session))) {
  411. if (tech_pvt->read_codec.implementation) {
  412. switch_core_codec_destroy(&tech_pvt->read_codec);
  413. }
  414. if (tech_pvt->write_codec.implementation) {
  415. switch_core_codec_destroy(&tech_pvt->write_codec);
  416. }
  417. switch_core_session_unset_read_codec(session);
  418. switch_core_session_unset_write_codec(session);
  419. }
  420. return SWITCH_STATUS_SUCCESS;
  421. }
  422. #ifdef BACKTRACE_DEBUG
  423. struct debug_trace_priv {
  424. const char *name;
  425. int span_id;
  426. int chan_id;
  427. };
  428. static void debug_trace(const int tid, const void *addr, const char *symbol, void *priv)
  429. {
  430. struct debug_trace_priv *data = priv;
  431. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
  432. data->span_id, data->chan_id, tid, data->name, symbol);
  433. }
  434. #endif
  435. static switch_status_t channel_on_hangup(switch_core_session_t *session)
  436. {
  437. switch_channel_t *channel = NULL;
  438. private_t *tech_pvt = NULL;
  439. ftdm_chan_type_t chantype;
  440. const char *name = NULL;
  441. int span_id = 0;
  442. int chan_id = 0;
  443. uint32_t t = 0;
  444. uint32_t tokencnt;
  445. char *uuid = NULL;
  446. const char *token = NULL;
  447. uint8_t uuid_found = 0;
  448. channel = switch_core_session_get_channel(session);
  449. assert(channel != NULL);
  450. tech_pvt = switch_core_session_get_private(session);
  451. assert(tech_pvt != NULL);
  452. /* ignore any further I/O requests, we're hanging up already! */
  453. switch_clear_flag_locked(tech_pvt, TFLAG_IO);
  454. name = switch_channel_get_name(channel);
  455. span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0;
  456. chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0;
  457. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP ENTER\n", span_id, chan_id, name);
  458. /* First verify this call has a device attached */
  459. if (!tech_pvt->ftdmchan) {
  460. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s does not have any ftdmchan attached\n", name);
  461. goto end;
  462. }
  463. /* Now verify the device is still attached to this call :-)
  464. * Sometimes the FS core takes too long (more than 3 seconds) in calling
  465. * channel_on_hangup() and the FreeTDM core decides to take the brute
  466. * force approach and hangup and detach themselves from the call. Later
  467. * when FS finally comes around, we might end up hanging up the device
  468. * attached to another call, this verification avoids that. */
  469. uuid = switch_core_session_get_uuid(session);
  470. tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
  471. for (t = 0; t < tokencnt; t++) {
  472. token = ftdm_channel_get_token(tech_pvt->ftdmchan, t);
  473. if (!zstr(token) && !strcasecmp(uuid, token)) {
  474. uuid_found = 1;
  475. break;
  476. }
  477. }
  478. if (!uuid_found) {
  479. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s\n", span_id, chan_id, name);
  480. goto end;
  481. }
  482. #ifdef BACKTRACE_DEBUG
  483. {
  484. struct debug_trace_priv trace_data;
  485. trace_data.name = name;
  486. trace_data.span_id = span_id;
  487. trace_data.chan_id = chan_id;
  488. ftdm_backtrace_walk(&debug_trace, &trace_data);
  489. }
  490. #endif
  491. ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
  492. chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
  493. switch (chantype) {
  494. case FTDM_CHAN_TYPE_FXO:
  495. case FTDM_CHAN_TYPE_EM:
  496. {
  497. ftdm_channel_call_hangup(tech_pvt->ftdmchan);
  498. }
  499. break;
  500. case FTDM_CHAN_TYPE_FXS:
  501. {
  502. tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
  503. if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) {
  504. if (tokencnt) {
  505. cycle_foreground(tech_pvt->ftdmchan, 0, NULL);
  506. } else {
  507. ftdm_channel_call_hangup(tech_pvt->ftdmchan);
  508. }
  509. }
  510. }
  511. break;
  512. case FTDM_CHAN_TYPE_CAS:
  513. case FTDM_CHAN_TYPE_B:
  514. {
  515. const char *var = NULL;
  516. switch_call_cause_t ccause = switch_channel_get_cause_q850(channel);
  517. ftdm_call_cause_t hcause;
  518. if (ccause < 1 || ccause > 127) {
  519. hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
  520. } else {
  521. hcause = (ftdm_call_cause_t)ccause;
  522. }
  523. var = switch_channel_get_variable(channel, "ss7_rel_loc");
  524. if (var) {
  525. ftdm_usrmsg_t usrmsg;
  526. memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t));
  527. ftdm_usrmsg_add_var(&usrmsg, "ss7_rel_loc", var);
  528. ftdm_channel_call_hangup_with_cause_ex(tech_pvt->ftdmchan, hcause, &usrmsg);
  529. } else {
  530. ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause);
  531. }
  532. }
  533. break;
  534. default:
  535. {
  536. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unhandled channel type %d for channel %s\n", chantype, switch_channel_get_name(channel));
  537. }
  538. break;
  539. }
  540. end:
  541. switch_mutex_lock(globals.mutex);
  542. globals.calls--;
  543. if (globals.calls < 0) {
  544. globals.calls = 0;
  545. }
  546. switch_mutex_unlock(globals.mutex);
  547. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP EXIT\n", span_id, chan_id, name);
  548. return SWITCH_STATUS_SUCCESS;
  549. }
  550. static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
  551. {
  552. switch_channel_t *channel = NULL;
  553. private_t *tech_pvt = NULL;
  554. channel = switch_core_session_get_channel(session);
  555. assert(channel != NULL);
  556. tech_pvt = switch_core_session_get_private(session);
  557. assert(tech_pvt != NULL);
  558. switch (sig) {
  559. case SWITCH_SIG_KILL:
  560. switch_clear_flag_locked(tech_pvt, TFLAG_IO);
  561. switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
  562. break;
  563. case SWITCH_SIG_BREAK:
  564. switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
  565. break;
  566. default:
  567. break;
  568. }
  569. return SWITCH_STATUS_SUCCESS;
  570. }
  571. static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
  572. {
  573. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL EXCHANGE_MEDIA\n");
  574. return SWITCH_STATUS_SUCCESS;
  575. }
  576. static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
  577. {
  578. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL SOFT_EXECUTE\n");
  579. return SWITCH_STATUS_SUCCESS;
  580. }
  581. static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
  582. {
  583. private_t *tech_pvt = NULL;
  584. char tmp[2] = "";
  585. tech_pvt = switch_core_session_get_private(session);
  586. assert(tech_pvt != NULL);
  587. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  588. switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
  589. return SWITCH_STATUS_FALSE;
  590. }
  591. tmp[0] = dtmf->digit;
  592. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SEND_DTMF, tmp);
  593. return SWITCH_STATUS_SUCCESS;
  594. }
  595. static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
  596. {
  597. switch_channel_t *channel = NULL;
  598. private_t *tech_pvt = NULL;
  599. ftdm_size_t len;
  600. ftdm_wait_flag_t wflags = FTDM_READ;
  601. char dtmf[128] = "";
  602. ftdm_status_t status;
  603. int total_to;
  604. int chunk, do_break = 0;
  605. uint32_t span_id, chan_id;
  606. const char *name = NULL;
  607. channel = switch_core_session_get_channel(session);
  608. assert(channel != NULL);
  609. tech_pvt = switch_core_session_get_private(session);
  610. assert(tech_pvt != NULL);
  611. name = switch_channel_get_name(channel);
  612. if (!tech_pvt->ftdmchan) {
  613. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
  614. return SWITCH_STATUS_FALSE;
  615. }
  616. span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
  617. chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
  618. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  619. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
  620. return SWITCH_STATUS_FALSE;
  621. }
  622. /* Digium Cards sometimes timeout several times in a row here.
  623. Yes, we support digium cards, ain't we nice.......
  624. 6 double length intervals should compensate */
  625. chunk = ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 2;
  626. total_to = chunk * 6;
  627. top:
  628. if (switch_channel_test_flag(channel, CF_SUSPEND)) {
  629. do_break = 1;
  630. }
  631. if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
  632. switch_clear_flag_locked(tech_pvt, TFLAG_BREAK);
  633. do_break = 1;
  634. }
  635. if (switch_test_flag(tech_pvt, TFLAG_HOLD) || do_break) {
  636. switch_yield(ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 1000);
  637. tech_pvt->cng_frame.datalen = ftdm_channel_get_io_packet_len(tech_pvt->ftdmchan);
  638. tech_pvt->cng_frame.samples = tech_pvt->cng_frame.datalen;
  639. tech_pvt->cng_frame.flags = SFF_CNG;
  640. *frame = &tech_pvt->cng_frame;
  641. if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) {
  642. tech_pvt->cng_frame.samples /= 2;
  643. }
  644. return SWITCH_STATUS_SUCCESS;
  645. }
  646. if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
  647. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
  648. goto fail;
  649. }
  650. wflags = FTDM_READ;
  651. status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk);
  652. if (status == FTDM_FAIL) {
  653. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
  654. goto fail;
  655. }
  656. if (status == FTDM_TIMEOUT) {
  657. if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) {
  658. total_to -= chunk;
  659. if (total_to <= 0) {
  660. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id);
  661. goto fail;
  662. }
  663. }
  664. goto top;
  665. }
  666. if (!(wflags & FTDM_READ)) {
  667. goto top;
  668. }
  669. len = tech_pvt->read_frame.buflen;
  670. if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
  671. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  672. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to read from dead channel %s device %d:%d\n", name, span_id, chan_id);
  673. goto normal_failure;
  674. }
  675. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
  676. if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) {
  677. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id);
  678. goto fail;
  679. }
  680. } else {
  681. tech_pvt->read_error = 0;
  682. }
  683. *frame = &tech_pvt->read_frame;
  684. tech_pvt->read_frame.datalen = (uint32_t)len;
  685. tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
  686. if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) {
  687. tech_pvt->read_frame.samples /= 2;
  688. }
  689. while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) {
  690. switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
  691. char *p;
  692. for (p = dtmf; p && *p; p++) {
  693. if (is_dtmf(*p)) {
  694. _dtmf.digit = *p;
  695. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
  696. switch_channel_queue_dtmf(channel, &_dtmf);
  697. }
  698. }
  699. }
  700. return SWITCH_STATUS_SUCCESS;
  701. fail:
  702. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id);
  703. normal_failure:
  704. switch_clear_flag_locked(tech_pvt, TFLAG_IO);
  705. return SWITCH_STATUS_GENERR;
  706. }
  707. static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
  708. {
  709. switch_channel_t *channel = NULL;
  710. private_t *tech_pvt = NULL;
  711. ftdm_size_t len;
  712. unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
  713. const char *name = "(none)";
  714. ftdm_wait_flag_t wflags = FTDM_WRITE;
  715. uint32_t span_id = 0, chan_id = 0;
  716. channel = switch_core_session_get_channel(session);
  717. assert(channel != NULL);
  718. tech_pvt = switch_core_session_get_private(session);
  719. assert(tech_pvt != NULL);
  720. name = switch_channel_get_name(channel);
  721. if (!tech_pvt->ftdmchan) {
  722. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
  723. return SWITCH_STATUS_FALSE;
  724. }
  725. span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
  726. chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
  727. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  728. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
  729. return SWITCH_STATUS_FALSE;
  730. }
  731. if (switch_test_flag(tech_pvt, TFLAG_HOLD)) {
  732. return SWITCH_STATUS_SUCCESS;
  733. }
  734. if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
  735. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
  736. goto fail;
  737. }
  738. if (switch_test_flag(frame, SFF_CNG)) {
  739. frame->data = data;
  740. frame->buflen = sizeof(data);
  741. if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) {
  742. goto fail;
  743. }
  744. memset(data, 255, frame->datalen);
  745. }
  746. wflags = FTDM_WRITE;
  747. ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
  748. if (!(wflags & FTDM_WRITE)) {
  749. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
  750. return SWITCH_STATUS_SUCCESS;
  751. }
  752. len = frame->datalen;
  753. if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
  754. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
  755. if (++tech_pvt->write_error > FTDM_MAX_READ_WRITE_ERRORS) {
  756. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel),
  757. SWITCH_LOG_ERROR, "Too many I/O write errors on channel %s device %d:%d!\n", name, span_id, chan_id);
  758. goto fail;
  759. }
  760. } else {
  761. tech_pvt->write_error = 0;
  762. }
  763. return SWITCH_STATUS_SUCCESS;
  764. fail:
  765. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id);
  766. switch_clear_flag_locked(tech_pvt, TFLAG_IO);
  767. return SWITCH_STATUS_GENERR;
  768. }
  769. static switch_status_t channel_receive_message_cas(switch_core_session_t *session, switch_core_session_message_t *msg)
  770. {
  771. switch_channel_t *channel;
  772. private_t *tech_pvt;
  773. uint32_t phy_id;
  774. channel = switch_core_session_get_channel(session);
  775. assert(channel != NULL);
  776. tech_pvt = (private_t *) switch_core_session_get_private(session);
  777. assert(tech_pvt != NULL);
  778. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  779. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  780. return SWITCH_STATUS_FALSE;
  781. }
  782. phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan);
  783. ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id);
  784. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
  785. return SWITCH_STATUS_SUCCESS;
  786. }
  787. switch (msg->message_id) {
  788. case SWITCH_MESSAGE_INDICATE_RINGING:
  789. {
  790. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
  791. }
  792. break;
  793. case SWITCH_MESSAGE_INDICATE_PROGRESS:
  794. {
  795. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA);
  796. }
  797. break;
  798. case SWITCH_MESSAGE_INDICATE_ANSWER:
  799. {
  800. ftdm_channel_call_answer(tech_pvt->ftdmchan);
  801. }
  802. break;
  803. default:
  804. break;
  805. }
  806. return SWITCH_STATUS_SUCCESS;
  807. }
  808. static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg)
  809. {
  810. switch_channel_t *channel;
  811. private_t *tech_pvt;
  812. channel = switch_core_session_get_channel(session);
  813. assert(channel != NULL);
  814. tech_pvt = (private_t *) switch_core_session_get_private(session);
  815. assert(tech_pvt != NULL);
  816. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  817. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  818. return SWITCH_STATUS_FALSE;
  819. }
  820. if (ftdm_channel_call_check_hangup(tech_pvt->ftdmchan)) {
  821. return SWITCH_STATUS_SUCCESS;
  822. }
  823. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
  824. return SWITCH_STATUS_SUCCESS;
  825. }
  826. switch (msg->message_id) {
  827. case SWITCH_MESSAGE_INDICATE_RINGING:
  828. {
  829. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
  830. }
  831. break;
  832. case SWITCH_MESSAGE_INDICATE_PROGRESS:
  833. {
  834. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA);
  835. }
  836. break;
  837. case SWITCH_MESSAGE_INDICATE_ANSWER:
  838. {
  839. ftdm_channel_call_answer(tech_pvt->ftdmchan);
  840. }
  841. break;
  842. case SWITCH_MESSAGE_INDICATE_REDIRECT:
  843. case SWITCH_MESSAGE_INDICATE_DEFLECT:
  844. {
  845. ftdm_usrmsg_t usrmsg;
  846. const char *val = NULL;
  847. memset(&usrmsg, 0, sizeof(usrmsg));
  848. if ((val = switch_channel_get_variable(channel, "freetdm_transfer_data"))) {
  849. ftdm_usrmsg_add_var(&usrmsg, "transfer_data", val);
  850. }
  851. switch_set_flag(tech_pvt, TFLAG_TRANSFER);
  852. if (ftdm_channel_call_transfer_ex(tech_pvt->ftdmchan, msg->string_arg, &usrmsg) != FTDM_SUCCESS) {
  853. switch_clear_flag(tech_pvt, TFLAG_TRANSFER);
  854. }
  855. while (switch_test_flag(tech_pvt, TFLAG_TRANSFER)) {
  856. switch_yield(100000);
  857. }
  858. }
  859. default:
  860. break;
  861. }
  862. return SWITCH_STATUS_SUCCESS;
  863. }
  864. static switch_status_t channel_receive_message_fxo(switch_core_session_t *session, switch_core_session_message_t *msg)
  865. {
  866. switch_channel_t *channel;
  867. private_t *tech_pvt;
  868. channel = switch_core_session_get_channel(session);
  869. assert(channel != NULL);
  870. tech_pvt = (private_t *) switch_core_session_get_private(session);
  871. assert(tech_pvt != NULL);
  872. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  873. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  874. return SWITCH_STATUS_FALSE;
  875. }
  876. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
  877. return SWITCH_STATUS_SUCCESS;
  878. }
  879. switch (msg->message_id) {
  880. case SWITCH_MESSAGE_INDICATE_PROGRESS:
  881. case SWITCH_MESSAGE_INDICATE_ANSWER:
  882. ftdm_channel_call_answer(tech_pvt->ftdmchan);
  883. break;
  884. default:
  885. break;
  886. }
  887. return SWITCH_STATUS_SUCCESS;
  888. }
  889. static switch_status_t channel_receive_message_fxs(switch_core_session_t *session, switch_core_session_message_t *msg)
  890. {
  891. switch_channel_t *channel;
  892. private_t *tech_pvt;
  893. channel = switch_core_session_get_channel(session);
  894. assert(channel != NULL);
  895. tech_pvt = (private_t *) switch_core_session_get_private(session);
  896. assert(tech_pvt != NULL);
  897. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  898. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  899. return SWITCH_STATUS_FALSE;
  900. }
  901. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
  902. return SWITCH_STATUS_SUCCESS;
  903. }
  904. switch (msg->message_id) {
  905. case SWITCH_MESSAGE_INDICATE_PROGRESS:
  906. case SWITCH_MESSAGE_INDICATE_ANSWER:
  907. ftdm_channel_call_answer(tech_pvt->ftdmchan);
  908. switch_channel_mark_answered(channel);
  909. break;
  910. case SWITCH_MESSAGE_INDICATE_RINGING:
  911. if (!switch_channel_test_flag(channel, CF_ANSWERED) &&
  912. !switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
  913. !switch_channel_test_flag(channel, CF_RING_READY)
  914. ) {
  915. ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RINGING);
  916. switch_channel_mark_ring_ready(channel);
  917. }
  918. break;
  919. default:
  920. break;
  921. }
  922. return SWITCH_STATUS_SUCCESS;
  923. }
  924. static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
  925. {
  926. private_t *tech_pvt;
  927. switch_status_t status;
  928. switch_channel_t *channel;
  929. const char *var;
  930. ftdm_channel_t *ftdmchan = NULL;
  931. tech_pvt = (private_t *) switch_core_session_get_private(session);
  932. assert(tech_pvt != NULL);
  933. channel = switch_core_session_get_channel(session);
  934. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  935. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  936. return SWITCH_STATUS_FALSE;
  937. }
  938. if (!(ftdmchan = tech_pvt->ftdmchan)) {
  939. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  940. return SWITCH_STATUS_FALSE;
  941. }
  942. if (!tech_pvt->ftdmchan) {
  943. switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
  944. return SWITCH_STATUS_FALSE;
  945. }
  946. switch (msg->message_id) {
  947. case SWITCH_MESSAGE_INDICATE_PROGRESS:
  948. case SWITCH_MESSAGE_INDICATE_ANSWER:
  949. if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
  950. if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) {
  951. int tmp = atoi(var);
  952. if (tmp > -1) {
  953. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
  954. }
  955. }
  956. if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
  957. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
  958. }
  959. }
  960. break;
  961. case SWITCH_MESSAGE_INDICATE_UUID_CHANGE:
  962. {
  963. ftdm_channel_replace_token(tech_pvt->ftdmchan, msg->string_array_arg[0], msg->string_array_arg[1]);
  964. }
  965. break;
  966. default:
  967. break;
  968. }
  969. switch (ftdm_channel_get_type(tech_pvt->ftdmchan)) {
  970. case FTDM_CHAN_TYPE_FXS:
  971. case FTDM_CHAN_TYPE_EM:
  972. status = channel_receive_message_fxs(session, msg);
  973. break;
  974. case FTDM_CHAN_TYPE_FXO:
  975. status = channel_receive_message_fxo(session, msg);
  976. break;
  977. case FTDM_CHAN_TYPE_B:
  978. status = channel_receive_message_b(session, msg);
  979. break;
  980. case FTDM_CHAN_TYPE_CAS:
  981. status = channel_receive_message_cas(session, msg);
  982. break;
  983. default:
  984. status = SWITCH_STATUS_FALSE;
  985. break;
  986. }
  987. return status;
  988. }
  989. switch_state_handler_table_t freetdm_state_handlers = {
  990. /*.on_init */ channel_on_init,
  991. /*.on_routing */ channel_on_routing,
  992. /*.on_execute */ channel_on_execute,
  993. /*.on_hangup */ channel_on_hangup,
  994. /*.on_exchange_media */ channel_on_exchange_media,
  995. /*.on_soft_execute */ channel_on_soft_execute,
  996. /*.on_consume_media */ NULL,
  997. /*.on_hibernate */ NULL,
  998. /*.on_reset */ NULL,
  999. /*.on_park*/ NULL,
  1000. /*.on_reporting*/ NULL,
  1001. /*.on_destroy*/ channel_on_destroy
  1002. };
  1003. switch_io_routines_t freetdm_io_routines = {
  1004. /*.outgoing_channel */ channel_outgoing_channel,
  1005. /*.read_frame */ channel_read_frame,
  1006. /*.write_frame */ channel_write_frame,
  1007. /*.kill_channel */ channel_kill_channel,
  1008. /*.send_dtmf */ channel_send_dtmf,
  1009. /*.receive_message*/ channel_receive_message
  1010. };
  1011. static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name)
  1012. {
  1013. const char *variable = NULL;
  1014. if (var_event) {
  1015. if ((variable = switch_event_get_header(var_event, variable_name))) {
  1016. return variable;
  1017. }
  1018. }
  1019. if (session) {
  1020. switch_channel_t *channel = switch_core_session_get_channel(session);
  1021. if ((variable = switch_channel_get_variable(channel, variable_name))) {
  1022. return variable;
  1023. }
  1024. }
  1025. return NULL;
  1026. }
  1027. typedef struct {
  1028. switch_event_t *var_event;
  1029. switch_core_session_t *new_session;
  1030. private_t *tech_pvt;
  1031. switch_caller_profile_t *caller_profile;
  1032. } hunt_data_t;
  1033. static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data)
  1034. {
  1035. uint32_t span_id, chan_id;
  1036. const char *var;
  1037. char *sess_uuid;
  1038. char name[128];
  1039. ftdm_status_t status;
  1040. hunt_data_t *hdata = caller_data->priv;
  1041. switch_channel_t *channel = switch_core_session_get_channel(hdata->new_session);
  1042. if ((var = switch_event_get_header(hdata->var_event, "freetdm_pre_buffer_size"))) {
  1043. int tmp = atoi(var);
  1044. if (tmp > -1) {
  1045. ftdm_channel_command(fchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
  1046. }
  1047. }
  1048. span_id = ftdm_channel_get_span_id(fchan);
  1049. chan_id = ftdm_channel_get_id(fchan);
  1050. tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data);
  1051. snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits);
  1052. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
  1053. switch_channel_set_name(channel, name);
  1054. switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(fchan));
  1055. switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id);
  1056. switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id);
  1057. switch_channel_set_caller_profile(channel, hdata->caller_profile);
  1058. hdata->tech_pvt->caller_profile = hdata->caller_profile;
  1059. switch_channel_set_state(channel, CS_INIT);
  1060. sess_uuid = switch_core_session_get_uuid(hdata->new_session);
  1061. status = ftdm_channel_add_token(fchan, sess_uuid, ftdm_channel_get_token_count(fchan));
  1062. switch_assert(status == FTDM_SUCCESS);
  1063. if (SPAN_CONFIG[span_id].limit_calls) {
  1064. char spanresource[512];
  1065. snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(fchan),
  1066. caller_data->dnis.digits);
  1067. ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n",
  1068. span_id, chan_id, FREETDM_LIMIT_REALM,
  1069. spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds);
  1070. if (switch_limit_incr("hash", hdata->new_session, FREETDM_LIMIT_REALM, spanresource,
  1071. SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) {
  1072. return FTDM_BREAK;
  1073. }
  1074. }
  1075. switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Attached session %s to channel %d:%d\n", sess_uuid, span_id, chan_id);
  1076. return FTDM_SUCCESS;
  1077. }
  1078. /* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
  1079. that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
  1080. */
  1081. static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
  1082. switch_caller_profile_t *outbound_profile,
  1083. switch_core_session_t **new_session, switch_memory_pool_t **pool,
  1084. switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
  1085. {
  1086. hunt_data_t hunt_data;
  1087. const char *dest = NULL;
  1088. char *data = NULL;
  1089. int span_id = -1, group_id = -1, chan_id = 0;
  1090. switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1091. ftdm_status_t status;
  1092. ftdm_hunt_direction_t direction = FTDM_HUNT_BOTTOM_UP;
  1093. ftdm_caller_data_t caller_data = {{ 0 }};
  1094. char *span_name = NULL;
  1095. switch_event_header_t *h;
  1096. char *argv[3];
  1097. int argc = 0;
  1098. const char *var;
  1099. const char *dest_num = NULL, *callerid_num = NULL;
  1100. const char *network_peer_uuid = NULL;
  1101. char sigbridge_peer[255];
  1102. switch_channel_t *peer_chan = NULL;
  1103. switch_channel_t *our_chan = NULL;
  1104. ftdm_hunting_scheme_t hunting;
  1105. ftdm_usrmsg_t usrmsg;
  1106. memset(&usrmsg, 0, sizeof(ftdm_usrmsg_t));
  1107. memset(sigbridge_peer, 0, sizeof(sigbridge_peer));
  1108. if (!outbound_profile) {
  1109. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n");
  1110. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1111. }
  1112. if (zstr(outbound_profile->destination_number)) {
  1113. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n");
  1114. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1115. }
  1116. data = switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number);
  1117. if (!zstr(outbound_profile->destination_number)) {
  1118. dest_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number));
  1119. }
  1120. if (!zstr(outbound_profile->caller_id_number)) {
  1121. callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number));
  1122. if ( callerid_num && *callerid_num == '+' ) {
  1123. callerid_num++;
  1124. }
  1125. }
  1126. if (!zstr(callerid_num) && !strcmp(callerid_num, SWITCH_DEFAULT_CLID_NUMBER)) {
  1127. callerid_num = NULL;
  1128. }
  1129. if ((argc = switch_separate_string(data, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) {
  1130. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n");
  1131. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1132. }
  1133. if (switch_is_number(argv[0])) {
  1134. span_id = atoi(argv[0]);
  1135. } else {
  1136. span_name = argv[0];
  1137. }
  1138. if (*argv[1] == 'a') {
  1139. direction = FTDM_HUNT_BOTTOM_UP;
  1140. } else if (*argv[1] == 'A') {
  1141. direction = FTDM_HUNT_TOP_DOWN;
  1142. } else if (*argv[1] == 'R') {
  1143. direction = FTDM_HUNT_RR_DOWN;
  1144. } else if (*argv[1] == 'r') {
  1145. direction = FTDM_HUNT_RR_UP;
  1146. } else {
  1147. chan_id = atoi(argv[1]);
  1148. }
  1149. if (!(dest = argv[2])) {
  1150. dest = "";
  1151. }
  1152. if (span_id == 0 && chan_id != 0) {
  1153. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Span 0 is used to pick the first available span, selecting a channel is not supported (and doesn't make sense)\n");
  1154. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1155. }
  1156. if (span_id == -1 && !zstr(span_name)) {
  1157. ftdm_span_t *span;
  1158. ftdm_status_t zstatus = ftdm_span_find_by_name(span_name, &span);
  1159. if (zstatus == FTDM_SUCCESS && span) {
  1160. span_id = ftdm_span_get_id(span);
  1161. }
  1162. }
  1163. if (span_id == -1) {
  1164. //Look for a group
  1165. ftdm_group_t *group;
  1166. ftdm_status_t zstatus = ftdm_group_find_by_name(span_name, &group);
  1167. if (zstatus == FTDM_SUCCESS && group) {
  1168. group_id = ftdm_group_get_id(group);
  1169. } else {
  1170. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing ftdm span or group: %s\n", span_name);
  1171. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1172. }
  1173. }
  1174. if (group_id < 0 && chan_id < 0) {
  1175. direction = FTDM_HUNT_BOTTOM_UP;
  1176. chan_id = 0;
  1177. }
  1178. if (session && globals.sip_headers && !switch_core_session_check_interface (session,freetdm_endpoint_interface) ) {
  1179. switch_channel_t *channel = switch_core_session_get_channel(session);
  1180. const char *sipvar;
  1181. network_peer_uuid = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-TransUUID");
  1182. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerName");
  1183. if (sipvar) {
  1184. ftdm_set_string(caller_data.cid_name, sipvar);
  1185. }
  1186. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerNumber");
  1187. if (sipvar) {
  1188. if ( *sipvar == '+' ) {
  1189. sipvar++;
  1190. }
  1191. ftdm_set_string(caller_data.cid_num.digits, sipvar);
  1192. }
  1193. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI");
  1194. if (sipvar) {
  1195. ftdm_set_string(caller_data.ani.digits, sipvar);
  1196. }
  1197. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-TON");
  1198. if (sipvar) {
  1199. caller_data.ani.type = (uint8_t)atoi(sipvar);
  1200. }
  1201. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-Plan");
  1202. if (sipvar) {
  1203. caller_data.ani.plan = (uint8_t)atoi(sipvar);
  1204. }
  1205. /* Used by ftmod_sangoma_ss7 only */
  1206. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-NADI");
  1207. if (sipvar) {
  1208. ftdm_usrmsg_add_var(&usrmsg, "ss7_clg_nadi", sipvar);
  1209. }
  1210. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI2");
  1211. if (sipvar) {
  1212. ftdm_set_string(caller_data.aniII, sipvar);
  1213. }
  1214. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS");
  1215. if (sipvar) {
  1216. ftdm_set_string(caller_data.dnis.digits, sipvar);
  1217. }
  1218. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC");
  1219. if (sipvar) {
  1220. ftdm_set_string(caller_data.loc.digits, sipvar);
  1221. }
  1222. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Access-Transport-URLENC");
  1223. if (sipvar) {
  1224. ftdm_usrmsg_add_var(&usrmsg, "ss7_access_transport_urlenc", sipvar);
  1225. }
  1226. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-Screen");
  1227. if (sipvar) {
  1228. ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_screen_ind", sipvar);
  1229. }
  1230. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-Presentation");
  1231. if (sipvar) {
  1232. ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_pres_ind", sipvar);
  1233. }
  1234. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-LOC-NADI");
  1235. if (sipvar) {
  1236. ftdm_usrmsg_add_var(&usrmsg, "ss7_loc_nadi", sipvar);
  1237. }
  1238. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-TON");
  1239. if (sipvar) {
  1240. caller_data.dnis.type = (uint8_t)atoi(sipvar);
  1241. }
  1242. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-Plan");
  1243. if (sipvar) {
  1244. caller_data.dnis.plan = (uint8_t)atoi(sipvar);
  1245. }
  1246. /* Used by ftmod_sangoma_ss7 only */
  1247. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-NADI");
  1248. if (sipvar) {
  1249. ftdm_usrmsg_add_var(&usrmsg, "ss7_cld_nadi", sipvar);
  1250. }
  1251. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS");
  1252. if (sipvar) {
  1253. ftdm_set_string(caller_data.rdnis.digits, sipvar);
  1254. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_digits", sipvar);
  1255. }
  1256. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Plan");
  1257. if (sipvar) {
  1258. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_plan", sipvar);
  1259. }
  1260. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-NADI");
  1261. if (sipvar) {
  1262. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_nadi", sipvar);
  1263. }
  1264. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Screen");
  1265. if (sipvar) {
  1266. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_screen_ind", sipvar);
  1267. }
  1268. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Presentation");
  1269. if (sipvar) {
  1270. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_pres_ind", sipvar);
  1271. }
  1272. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN");
  1273. if (sipvar) {
  1274. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_digits", sipvar);
  1275. }
  1276. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumQual");
  1277. if (sipvar) {
  1278. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_numqual", sipvar);
  1279. }
  1280. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NADI");
  1281. if (sipvar) {
  1282. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_nadi", sipvar);
  1283. }
  1284. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Screen");
  1285. if (sipvar) {
  1286. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_screen_ind", sipvar);
  1287. }
  1288. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Presentation");
  1289. if (sipvar) {
  1290. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_pres_ind", sipvar);
  1291. }
  1292. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Plan");
  1293. if (sipvar) {
  1294. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_npi", sipvar);
  1295. }
  1296. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumInComp");
  1297. if (sipvar) {
  1298. ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_num_inc_ind", sipvar);
  1299. }
  1300. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Screen");
  1301. if (sipvar) {
  1302. ftdm_usrmsg_add_var(&usrmsg, "ss7_screen_ind", sipvar);
  1303. }
  1304. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Presentation");
  1305. if (sipvar) {
  1306. ftdm_usrmsg_add_var(&usrmsg, "ss7_pres_ind", sipvar);
  1307. }
  1308. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CPC");
  1309. if (sipvar) {
  1310. ftdm_set_calling_party_category(sipvar, (uint8_t *)&caller_data.cpc);
  1311. }
  1312. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM");
  1313. if (sipvar) {
  1314. ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar);
  1315. }
  1316. /* redirection information */
  1317. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Indicator");
  1318. if (sipvar) {
  1319. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_indicator", sipvar);
  1320. }
  1321. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-OrigReason");
  1322. if (sipvar) {
  1323. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_orig", sipvar);
  1324. }
  1325. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Count");
  1326. if (sipvar) {
  1327. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_count", sipvar);
  1328. }
  1329. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDINF-Reason");
  1330. if (sipvar) {
  1331. ftdm_usrmsg_add_var(&usrmsg, "ss7_rdinfo_reason", sipvar);
  1332. }
  1333. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN");
  1334. if (sipvar) {
  1335. ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn", sipvar);
  1336. }
  1337. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-NADI");
  1338. if (sipvar) {
  1339. ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_nadi", sipvar);
  1340. }
  1341. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-Plan");
  1342. if (sipvar) {
  1343. ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_plan", sipvar);
  1344. }
  1345. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-OCN-Presentation");
  1346. if (sipvar) {
  1347. ftdm_usrmsg_add_var(&usrmsg, "ss7_ocn_pres", sipvar);
  1348. }
  1349. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM-FWD-IND-HEX");
  1350. if (sipvar) {
  1351. ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_fwd_ind_hex", sipvar);
  1352. }
  1353. sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX");
  1354. if (sipvar) {
  1355. ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_nature_connection_hex", sipvar);
  1356. }
  1357. }
  1358. if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
  1359. caller_data.screen = FTDM_SCREENING_VERIFIED_PASSED;
  1360. }
  1361. if (switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER)) {
  1362. caller_data.pres = FTDM_PRES_RESTRICTED;
  1363. }
  1364. if ((var = channel_get_variable(session, var_event, "freetdm_iam_fwd_ind_isdn_access_ind"))) {
  1365. ftdm_usrmsg_add_var(&usrmsg, "iam_fwd_ind_isdn_access_ind", var);
  1366. }
  1367. if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) {
  1368. caller_data.bearer_capability = (uint8_t)atoi(var);
  1369. }
  1370. if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) {
  1371. caller_data.bearer_layer1 = (uint8_t)atoi(var);
  1372. }
  1373. if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) {
  1374. ftdm_set_screening_ind(var, &caller_data.screen);
  1375. }
  1376. if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) {
  1377. ftdm_set_presentation_ind(var, &caller_data.pres);
  1378. }
  1379. if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) {
  1380. ftdm_set_ton(var, &caller_data.dnis.type);
  1381. } else {
  1382. caller_data.dnis.type = outbound_profile->destination_number_ton;
  1383. }
  1384. if ((var = channel_get_variable(session, var_event, "freetdm_outbound_npi"))) {
  1385. ftdm_set_npi(var, &caller_data.dnis.plan);
  1386. } else {
  1387. caller_data.dnis.plan = outbound_profile->destination_number_numplan;
  1388. }
  1389. if ((var = channel_get_variable(session, var_event, "freetdm_calling_party_category"))) {
  1390. ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc);
  1391. }
  1392. if (!zstr(dest)) {
  1393. ftdm_set_string(caller_data.dnis.digits, dest);
  1394. }
  1395. caller_data.dnis.plan = outbound_profile->destination_number_numplan;
  1396. /* blindly copy data from outbound_profile. They will be overwritten
  1397. * by calling ftdm_caller_data if needed after */
  1398. caller_data.cid_num.type = outbound_profile->caller_ton;
  1399. caller_data.cid_num.plan = outbound_profile->caller_numplan;
  1400. caller_data.rdnis.type = outbound_profile->rdnis_ton;
  1401. caller_data.rdnis.plan = outbound_profile->rdnis_numplan;
  1402. ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name);
  1403. ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(callerid_num));
  1404. memset(&hunting, 0, sizeof(hunting));
  1405. if (group_id >= 0) {
  1406. hunting.mode = FTDM_HUNT_GROUP;
  1407. hunting.mode_data.group.group_id = group_id;
  1408. hunting.mode_data.group.direction = direction;
  1409. } else if (chan_id) {
  1410. hunting.mode = FTDM_HUNT_CHAN;
  1411. hunting.mode_data.chan.span_id = span_id;
  1412. hunting.mode_data.chan.chan_id = chan_id;
  1413. } else {
  1414. hunting.mode = FTDM_HUNT_SPAN;
  1415. hunting.mode_data.span.span_id = span_id;
  1416. hunting.mode_data.span.direction = direction;
  1417. }
  1418. for (h = var_event->headers; h; h = h->next) {
  1419. if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) {
  1420. char *v = h->name + FREETDM_VAR_PREFIX_LEN;
  1421. if (!zstr(v)) {
  1422. if (!strcasecmp(v, "ss7_iam")) {
  1423. /* Do not print the value of ss7_iam as it is very long */
  1424. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s to channel %d:%d\n", v, span_id, chan_id);
  1425. } else {
  1426. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
  1427. }
  1428. ftdm_usrmsg_add_var(&usrmsg, v, h->value);
  1429. }
  1430. }
  1431. }
  1432. if ((*new_session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) {
  1433. private_t *tech_pvt;
  1434. switch_caller_profile_t *caller_profile;
  1435. switch_core_session_add_stream(*new_session, NULL);
  1436. if (!(tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t)))) {
  1437. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
  1438. switch_core_session_destroy(new_session);
  1439. cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1440. goto fail;
  1441. }
  1442. our_chan = switch_core_session_get_channel(*new_session);
  1443. switch_channel_set_flag(our_chan, CF_AUDIO);
  1444. /* Figure out if there is a native bridge requested through SIP x headers */
  1445. if (network_peer_uuid) {
  1446. switch_core_session_t *network_peer = switch_core_session_locate(network_peer_uuid);
  1447. if (network_peer) {
  1448. const char *my_uuid = switch_core_session_get_uuid(*new_session);
  1449. private_t *peer_private = switch_core_session_get_private(network_peer);
  1450. peer_chan = switch_core_session_get_channel(network_peer);
  1451. switch_set_string(tech_pvt->network_peer_uuid, network_peer_uuid);
  1452. switch_set_string(peer_private->network_peer_uuid, my_uuid);
  1453. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session %s is network-bridged with %s\n",
  1454. my_uuid, network_peer_uuid);
  1455. snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u",
  1456. ftdm_channel_get_span_id(peer_private->ftdmchan), ftdm_channel_get_id(peer_private->ftdmchan));
  1457. switch_core_session_rwunlock(network_peer);
  1458. }
  1459. /* Figure out if there is a native bridge requested through dial plan variable and the originating channel is also freetdm (not going through SIP) */
  1460. } else if (session
  1461. && (var = channel_get_variable(session, var_event, FREETDM_VAR_PREFIX "native_sigbridge"))
  1462. && switch_true(var)
  1463. && switch_core_session_compare(*new_session, session)) {
  1464. private_t *peer_pvt = switch_core_session_get_private(session);
  1465. peer_chan = switch_core_session_get_channel(session);
  1466. snprintf(sigbridge_peer, sizeof(sigbridge_peer), "%u:%u",
  1467. ftdm_channel_get_span_id(peer_pvt->ftdmchan), ftdm_channel_get_id(peer_pvt->ftdmchan));
  1468. }
  1469. caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
  1470. caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
  1471. caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num));
  1472. hunting.result_cb = on_channel_found;
  1473. hunt_data.var_event = var_event;
  1474. hunt_data.new_session = *new_session;
  1475. hunt_data.caller_profile = caller_profile;
  1476. hunt_data.tech_pvt = tech_pvt;
  1477. caller_data.priv = &hunt_data;
  1478. if (session && !zstr(sigbridge_peer)) {
  1479. peer_chan = switch_core_session_get_channel(session);
  1480. ftdm_usrmsg_add_var(&usrmsg, "sigbridge_peer", sigbridge_peer);
  1481. }
  1482. if ((status = ftdm_call_place_ex(&caller_data, &hunting, &usrmsg)) != FTDM_SUCCESS) {
  1483. if (tech_pvt->read_codec.implementation) {
  1484. switch_core_codec_destroy(&tech_pvt->read_codec);
  1485. }
  1486. if (tech_pvt->write_codec.implementation) {
  1487. switch_core_codec_destroy(&tech_pvt->write_codec);
  1488. }
  1489. switch_core_session_destroy(new_session);
  1490. if (status == FTDM_BREAK || status == FTDM_EBUSY) {
  1491. cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
  1492. } else {
  1493. cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  1494. }
  1495. goto fail;
  1496. }
  1497. if (our_chan && peer_chan) {
  1498. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
  1499. "Bridging native signaling of channel %s to channel %s\n",
  1500. switch_channel_get_name(peer_chan), switch_channel_get_name(our_chan));
  1501. }
  1502. return SWITCH_CAUSE_SUCCESS;
  1503. }
  1504. fail:
  1505. return cause;
  1506. }
  1507. static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel)
  1508. {
  1509. if (channel) {
  1510. const char *var;
  1511. if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
  1512. if (switch_true(var)) {
  1513. ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
  1514. ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
  1515. return;
  1516. }
  1517. }
  1518. /* the variable is not present or has a negative value then proceed to enable DTMF ... */
  1519. }
  1520. if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) {
  1521. ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
  1522. }
  1523. }
  1524. ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp)
  1525. {
  1526. switch_core_session_t *session = NULL;
  1527. private_t *tech_pvt = NULL;
  1528. switch_channel_t *channel = NULL;
  1529. ftdm_iterator_t *iter = NULL;
  1530. ftdm_iterator_t *curr = NULL;
  1531. const char *var_name = NULL;
  1532. const char *var_value = NULL;
  1533. uint32_t spanid, chanid;
  1534. char name[128];
  1535. ftdm_caller_data_t *channel_caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  1536. *sp = NULL;
  1537. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  1538. chanid = ftdm_channel_get_id(sigmsg->channel);
  1539. if (!(session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) {
  1540. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
  1541. return FTDM_FAIL;
  1542. }
  1543. /* I guess we always want DTMF detection */
  1544. ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
  1545. switch_core_session_add_stream(session, NULL);
  1546. tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
  1547. assert(tech_pvt != NULL);
  1548. channel = switch_core_session_get_channel(session);
  1549. if (tech_init(tech_pvt, session, sigmsg->channel, channel_caller_data) != SWITCH_STATUS_SUCCESS) {
  1550. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
  1551. switch_core_session_destroy(&session);
  1552. return FTDM_FAIL;
  1553. }
  1554. switch_channel_set_flag(channel, CF_AUDIO);
  1555. channel_caller_data->collected[0] = '\0';
  1556. if (zstr(channel_caller_data->cid_name)) {
  1557. switch_set_string(channel_caller_data->cid_name, ftdm_channel_get_name(sigmsg->channel));
  1558. }
  1559. if (zstr(channel_caller_data->cid_num.digits)) {
  1560. if (!zstr(channel_caller_data->ani.digits)) {
  1561. switch_set_string(channel_caller_data->cid_num.digits, channel_caller_data->ani.digits);
  1562. } else {
  1563. switch_set_string(channel_caller_data->cid_num.digits, ftdm_channel_get_number(sigmsg->channel));
  1564. }
  1565. }
  1566. tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
  1567. "FreeTDM",
  1568. SPAN_CONFIG[spanid].dialplan,
  1569. channel_caller_data->cid_name,
  1570. channel_caller_data->cid_num.digits,
  1571. NULL,
  1572. channel_caller_data->ani.digits,
  1573. channel_caller_data->aniII,
  1574. channel_caller_data->rdnis.digits,
  1575. (char *)modname,
  1576. SPAN_CONFIG[spanid].context,
  1577. channel_caller_data->dnis.digits);
  1578. assert(tech_pvt->caller_profile != NULL);
  1579. if (channel_caller_data->screen == 1 || channel_caller_data->screen == 3) {
  1580. switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
  1581. }
  1582. tech_pvt->caller_profile->caller_ton = channel_caller_data->cid_num.type;
  1583. tech_pvt->caller_profile->caller_numplan = channel_caller_data->cid_num.plan;
  1584. tech_pvt->caller_profile->ani_ton = channel_caller_data->ani.type;
  1585. tech_pvt->caller_profile->ani_numplan = channel_caller_data->ani.plan;
  1586. tech_pvt->caller_profile->destination_number_ton = channel_caller_data->dnis.type;
  1587. tech_pvt->caller_profile->destination_number_numplan = channel_caller_data->dnis.plan;
  1588. tech_pvt->caller_profile->rdnis_ton = channel_caller_data->rdnis.type;
  1589. tech_pvt->caller_profile->rdnis_numplan = channel_caller_data->rdnis.plan;
  1590. if (channel_caller_data->pres) {
  1591. switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
  1592. }
  1593. snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", spanid, chanid, tech_pvt->caller_profile->destination_number);
  1594. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect inbound channel %s\n", name);
  1595. switch_channel_set_name(channel, name);
  1596. switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
  1597. switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(sigmsg->channel));
  1598. switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", spanid);
  1599. switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid);
  1600. switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability);
  1601. switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1);
  1602. switch_channel_set_variable_printf(channel, "freetdm_calling_party_category", ftdm_calling_party_category2str(channel_caller_data->cpc));
  1603. switch_channel_set_variable_printf(channel, "screening_ind", ftdm_screening2str(channel_caller_data->screen));
  1604. switch_channel_set_variable_printf(channel, "presentation_ind", ftdm_presentation2str(channel_caller_data->pres));
  1605. if (globals.sip_headers) {
  1606. switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
  1607. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
  1608. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-TransUUID", "%s",switch_core_session_get_uuid(session));
  1609. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
  1610. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ChanNumber", "%d", chanid);
  1611. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerName", "%s", channel_caller_data->cid_name);
  1612. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerNumber", "%s", channel_caller_data->cid_num.digits);
  1613. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI", "%s", channel_caller_data->ani.digits);
  1614. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-TON", "%d", channel_caller_data->ani.type);
  1615. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-Plan", "%d", channel_caller_data->ani.plan);
  1616. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI2", "%s", channel_caller_data->aniII);
  1617. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS", "%s", channel_caller_data->dnis.digits);
  1618. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-TON", "%d", channel_caller_data->dnis.type);
  1619. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%d", channel_caller_data->dnis.plan);
  1620. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits);
  1621. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type);
  1622. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
  1623. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc));
  1624. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam_nature_connection_hex");
  1625. if (!ftdm_strlen_zero(var_value)) {
  1626. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX", "%s", var_value);
  1627. }
  1628. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam_fwd_ind_hex");
  1629. if (!ftdm_strlen_zero(var_value)) {
  1630. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-FWD-IND-HEX", "%s", var_value);
  1631. }
  1632. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_access_transport_urlenc");
  1633. if (!ftdm_strlen_zero(var_value)) {
  1634. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Access-Transport-URLENC", "%s", var_value);
  1635. }
  1636. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_indicator");
  1637. if (!ftdm_strlen_zero(var_value)) {
  1638. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Indicator", "%s", var_value);
  1639. }
  1640. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_orig");
  1641. if (!ftdm_strlen_zero(var_value)) {
  1642. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-OrigReason", "%s", var_value);
  1643. }
  1644. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_count");
  1645. if (!ftdm_strlen_zero(var_value)) {
  1646. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Count", "%s", var_value);
  1647. }
  1648. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdinfo_reason");
  1649. if (!ftdm_strlen_zero(var_value)) {
  1650. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDINF-Reason", "%s", var_value);
  1651. }
  1652. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_clg_nadi");
  1653. if (!ftdm_strlen_zero(var_value)) {
  1654. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-NADI", "%s", var_value);
  1655. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-NADI", "%s", var_value);
  1656. }
  1657. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cld_nadi");
  1658. if (!ftdm_strlen_zero(var_value)) {
  1659. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-NADI", "%s", var_value);
  1660. }
  1661. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind");
  1662. if (!ftdm_strlen_zero(var_value)) {
  1663. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Screen", "%s", var_value);
  1664. }
  1665. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_pres_ind");
  1666. if (!ftdm_strlen_zero(var_value)) {
  1667. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Presentation", "%s", var_value);
  1668. }
  1669. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits");
  1670. if (!ftdm_strlen_zero(var_value)) {
  1671. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN", "%s", var_value);
  1672. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_numqual");
  1673. if (!ftdm_strlen_zero(var_value)) {
  1674. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumQual", "%s", var_value);
  1675. }
  1676. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_nadi");
  1677. if (!ftdm_strlen_zero(var_value)) {
  1678. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NADI", "%s", var_value);
  1679. }
  1680. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_screen_ind");
  1681. if (!ftdm_strlen_zero(var_value)) {
  1682. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Screen", "%s", var_value);
  1683. }
  1684. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_pres_ind");
  1685. if (!ftdm_strlen_zero(var_value)) {
  1686. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Presentation", "%s", var_value);
  1687. }
  1688. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_npi");
  1689. if (!ftdm_strlen_zero(var_value)) {
  1690. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Plan", "%s", var_value);
  1691. }
  1692. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_num_inc_ind");
  1693. if (!ftdm_strlen_zero(var_value)) {
  1694. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%s", var_value);
  1695. }
  1696. } /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */
  1697. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam");
  1698. if (!ftdm_strlen_zero(var_value)) {
  1699. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value);
  1700. }
  1701. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_cic");
  1702. if (!ftdm_strlen_zero(var_value)) {
  1703. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CIC", "%s", var_value);
  1704. }
  1705. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
  1706. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres);
  1707. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallReference", "%d", channel_caller_data->call_reference);
  1708. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_opc");
  1709. if (!ftdm_strlen_zero(var_value)) {
  1710. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OPC", "%s", var_value);
  1711. }
  1712. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_digits");
  1713. if (!ftdm_strlen_zero(var_value)) {
  1714. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC", "%s", var_value);
  1715. }
  1716. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_screen_ind");
  1717. if (!ftdm_strlen_zero(var_value)) {
  1718. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Screen", "%s", var_value);
  1719. }
  1720. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_pres_ind");
  1721. if (!ftdm_strlen_zero(var_value)) {
  1722. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-Presentation", "%s", var_value);
  1723. }
  1724. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_loc_nadi");
  1725. if (!ftdm_strlen_zero(var_value)) {
  1726. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-LOC-NADI", "%s", var_value);
  1727. }
  1728. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn");
  1729. if (!ftdm_strlen_zero(var_value)) {
  1730. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN", "%s", var_value);
  1731. }
  1732. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_nadi");
  1733. if (!ftdm_strlen_zero(var_value)) {
  1734. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-NADI", "%s", var_value);
  1735. }
  1736. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_plan");
  1737. if (!ftdm_strlen_zero(var_value)) {
  1738. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-Plan", "%s", var_value);
  1739. }
  1740. var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_ocn_pres");
  1741. if (!ftdm_strlen_zero(var_value)) {
  1742. switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-OCN-Presentation", "%s", var_value);
  1743. }
  1744. }
  1745. /* Add any call variable to the dial plan */
  1746. iter = ftdm_sigmsg_get_var_iterator(sigmsg, iter);
  1747. for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) {
  1748. ftdm_get_current_var(curr, &var_name, &var_value);
  1749. snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
  1750. switch_channel_set_variable_printf(channel, name, "%s", var_value);
  1751. if (!strcasecmp(var_name, "ss7_iam")) {
  1752. /* Do not print freetdm_ss7_iam as it is a very long variable */
  1753. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s is present\n", name);
  1754. } else {
  1755. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value);
  1756. }
  1757. }
  1758. ftdm_iterator_free(iter);
  1759. switch_channel_set_state(channel, CS_INIT);
  1760. if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
  1761. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
  1762. switch_core_session_destroy(&session);
  1763. return FTDM_FAIL;
  1764. }
  1765. if (ftdm_channel_add_token(sigmsg->channel, switch_core_session_get_uuid(session), 0) != FTDM_SUCCESS) {
  1766. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding token\n");
  1767. switch_core_session_destroy(&session);
  1768. return FTDM_FAIL;
  1769. }
  1770. *sp = session;
  1771. return FTDM_SUCCESS;
  1772. }
  1773. static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
  1774. {
  1775. uint32_t chanid, spanid;
  1776. switch_event_t *event = NULL;
  1777. ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
  1778. chanid = ftdm_channel_get_id(sigmsg->channel);
  1779. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  1780. switch (sigmsg->event_id) {
  1781. case FTDM_SIGEVENT_SMS:
  1782. {
  1783. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  1784. ftdm_sms_data_t *sms = (ftdm_sms_data_t*) caller_data->priv;
  1785. ftdm_log(FTDM_LOG_INFO, "SMS received on %d:%d from %s: %s", spanid, chanid, sms->from, sms->body);
  1786. if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
  1787. ftdm_log(FTDM_LOG_ERROR, "failed to create SMS event\n");
  1788. return FTDM_FAIL;
  1789. }
  1790. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", sms->from);
  1791. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "body", sms->body);
  1792. alarmbits = 0;
  1793. }
  1794. //return FTDM_BREAK;
  1795. break;
  1796. case FTDM_SIGEVENT_ALARM_CLEAR:
  1797. case FTDM_SIGEVENT_ALARM_TRAP:
  1798. {
  1799. if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
  1800. ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
  1801. return FTDM_FAIL;
  1802. }
  1803. if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
  1804. ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
  1805. return FTDM_FAIL;
  1806. }
  1807. if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
  1808. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
  1809. } else {
  1810. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
  1811. }
  1812. }
  1813. break;
  1814. case FTDM_SIGEVENT_UP:
  1815. {
  1816. /* clear any rate limit resource for this span */
  1817. char spanresource[512];
  1818. if (SPAN_CONFIG[spanid].limit_reset_event == FTDM_LIMIT_RESET_ON_ANSWER && SPAN_CONFIG[spanid].limit_calls) {
  1819. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  1820. snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(sigmsg->channel), caller_data->dnis.digits);
  1821. ftdm_log(FTDM_LOG_DEBUG, "Clearing rate limit resource on channel %d:%d (%s/%s)\n", spanid, chanid, FREETDM_LIMIT_REALM, spanresource);
  1822. switch_limit_interval_reset("hash", FREETDM_LIMIT_REALM, spanresource);
  1823. }
  1824. return FTDM_SUCCESS;
  1825. }
  1826. break;
  1827. case FTDM_SIGEVENT_TRANSFER_COMPLETED:
  1828. {
  1829. switch_core_session_t *session = NULL;
  1830. switch_channel_t *channel = NULL;
  1831. private_t *tech_pvt = NULL;
  1832. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  1833. channel = switch_core_session_get_channel(session);
  1834. tech_pvt = switch_core_session_get_private(session);
  1835. switch_clear_flag_locked(tech_pvt, TFLAG_TRANSFER);
  1836. switch_channel_set_variable(channel, "freetdm_transfer_response", ftdm_transfer_response2str(sigmsg->ev_data.transfer_completed.response));
  1837. switch_core_session_rwunlock(session);
  1838. }
  1839. return FTDM_SUCCESS;
  1840. }
  1841. break;
  1842. case FTDM_SIGEVENT_RELEASED:
  1843. case FTDM_SIGEVENT_INDICATION_COMPLETED:
  1844. case FTDM_SIGEVENT_DIALING:
  1845. {
  1846. /* Swallow these events */
  1847. return FTDM_BREAK;
  1848. }
  1849. break;
  1850. case FTDM_SIGEVENT_STOP:
  1851. case FTDM_SIGEVENT_RESTART:
  1852. {
  1853. switch_core_session_t *session = NULL;
  1854. private_t *tech_pvt = NULL;
  1855. while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  1856. tech_pvt = switch_core_session_get_private(session);
  1857. switch_clear_flag_locked(tech_pvt, TFLAG_TRANSFER);
  1858. switch_core_session_rwunlock(session);
  1859. return FTDM_SUCCESS;
  1860. }
  1861. }
  1862. break;
  1863. default:
  1864. return FTDM_SUCCESS;
  1865. break;
  1866. }
  1867. if (event) {
  1868. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
  1869. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
  1870. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
  1871. if (alarmbits & FTDM_ALARM_RED) {
  1872. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
  1873. }
  1874. if (alarmbits & FTDM_ALARM_YELLOW) {
  1875. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
  1876. }
  1877. if (alarmbits & FTDM_ALARM_RAI) {
  1878. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
  1879. }
  1880. if (alarmbits & FTDM_ALARM_BLUE) {
  1881. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
  1882. }
  1883. if (alarmbits & FTDM_ALARM_AIS) {
  1884. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
  1885. }
  1886. if (alarmbits & FTDM_ALARM_GENERAL) {
  1887. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
  1888. }
  1889. switch_event_fire(&event);
  1890. }
  1891. return FTDM_BREAK;
  1892. }
  1893. static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
  1894. {
  1895. switch_core_session_t *session = NULL;
  1896. switch_channel_t *channel = NULL;
  1897. ftdm_status_t status = FTDM_SUCCESS;
  1898. uint32_t spanid;
  1899. uint32_t chanid;
  1900. ftdm_caller_data_t *caller_data;
  1901. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  1902. chanid = ftdm_channel_get_id(sigmsg->channel);
  1903. caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  1904. ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id));
  1905. switch (sigmsg->event_id) {
  1906. case FTDM_SIGEVENT_PROGRESS_MEDIA:
  1907. {
  1908. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  1909. channel = switch_core_session_get_channel(session);
  1910. switch_channel_mark_pre_answered(channel);
  1911. switch_core_session_rwunlock(session);
  1912. }
  1913. }
  1914. break;
  1915. case FTDM_SIGEVENT_STOP:
  1916. {
  1917. private_t *tech_pvt = NULL;
  1918. while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  1919. tech_pvt = switch_core_session_get_private(session);
  1920. switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
  1921. ftdm_channel_clear_token(sigmsg->channel, 0);
  1922. channel = switch_core_session_get_channel(session);
  1923. switch_channel_hangup(channel, caller_data->hangup_cause);
  1924. ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
  1925. switch_core_session_rwunlock(session);
  1926. }
  1927. }
  1928. break;
  1929. case FTDM_SIGEVENT_UP:
  1930. {
  1931. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  1932. channel = switch_core_session_get_channel(session);
  1933. switch_channel_mark_answered(channel);
  1934. ftdm_enable_channel_dtmf(sigmsg->channel, channel);
  1935. switch_core_session_rwunlock(session);
  1936. }
  1937. }
  1938. break;
  1939. case FTDM_SIGEVENT_START:
  1940. {
  1941. status = ftdm_channel_from_event(sigmsg, &session);
  1942. if (status != FTDM_SUCCESS) {
  1943. ftdm_channel_call_hangup(sigmsg->channel);
  1944. }
  1945. }
  1946. break;
  1947. case FTDM_SIGEVENT_COLLECTED_DIGIT: /* Analog E&M */
  1948. {
  1949. int span_id = ftdm_channel_get_span_id(sigmsg->channel);
  1950. char *dtmf = sigmsg->ev_data.collected.digits;
  1951. char *regex = SPAN_CONFIG[span_id].dial_regex;
  1952. char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
  1953. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  1954. if (zstr(regex)) {
  1955. regex = NULL;
  1956. }
  1957. if (zstr(fail_regex)) {
  1958. fail_regex = NULL;
  1959. }
  1960. ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf);
  1961. switch_set_string(caller_data->collected, dtmf);
  1962. if ((regex || fail_regex) && !zstr(dtmf)) {
  1963. switch_regex_t *re = NULL;
  1964. int ovector[30];
  1965. int match = 0;
  1966. if (fail_regex) {
  1967. match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  1968. status = match ? FTDM_SUCCESS : FTDM_BREAK;
  1969. switch_regex_safe_free(re);
  1970. ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match");
  1971. }
  1972. if (status == FTDM_SUCCESS && regex) {
  1973. match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  1974. status = match ? FTDM_BREAK : FTDM_SUCCESS;
  1975. switch_regex_safe_free(re);
  1976. ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match");
  1977. }
  1978. ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf);
  1979. }
  1980. }
  1981. break;
  1982. case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
  1983. /* span signaling status changed ... nothing to do here .. */
  1984. break;
  1985. default:
  1986. {
  1987. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
  1988. sigmsg->event_id, spanid, chanid);
  1989. }
  1990. break;
  1991. }
  1992. return status;
  1993. }
  1994. static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
  1995. {
  1996. switch_core_session_t *session = NULL;
  1997. switch_channel_t *channel = NULL;
  1998. ftdm_status_t status = FTDM_SUCCESS;
  1999. uint32_t chanid, spanid, tokencount;
  2000. chanid = ftdm_channel_get_id(sigmsg->channel);
  2001. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  2002. tokencount = ftdm_channel_get_token_count(sigmsg->channel);
  2003. ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
  2004. switch (sigmsg->event_id) {
  2005. case FTDM_SIGEVENT_UP:
  2006. {
  2007. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2008. channel = switch_core_session_get_channel(session);
  2009. switch_channel_mark_answered(channel);
  2010. ftdm_enable_channel_dtmf(sigmsg->channel, channel);
  2011. switch_core_session_rwunlock(session);
  2012. }
  2013. }
  2014. break;
  2015. case FTDM_SIGEVENT_PROGRESS:
  2016. {
  2017. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2018. channel = switch_core_session_get_channel(session);
  2019. switch_channel_mark_ring_ready(channel);
  2020. switch_core_session_rwunlock(session);
  2021. }
  2022. }
  2023. break;
  2024. case FTDM_SIGEVENT_START:
  2025. {
  2026. status = ftdm_channel_from_event(sigmsg, &session);
  2027. if (status != FTDM_SUCCESS) {
  2028. ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_BUSY);
  2029. }
  2030. }
  2031. break;
  2032. case FTDM_SIGEVENT_STOP:
  2033. {
  2034. private_t *tech_pvt = NULL;
  2035. switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
  2036. if (tokencount) {
  2037. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  2038. switch_core_session_t *session_a, *session_b, *session_t = NULL;
  2039. switch_channel_t *channel_a = NULL, *channel_b = NULL;
  2040. int digits = !zstr(caller_data->collected);
  2041. const char *br_a_uuid = NULL, *br_b_uuid = NULL;
  2042. private_t *tech_pvt = NULL;
  2043. if ((session_a = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 0)))) {
  2044. channel_a = switch_core_session_get_channel(session_a);
  2045. br_a_uuid = switch_channel_get_partner_uuid(channel_a);
  2046. tech_pvt = switch_core_session_get_private(session_a);
  2047. stop_hold(session_a, switch_channel_get_partner_uuid(channel_a));
  2048. switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
  2049. }
  2050. if ((session_b = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 1)))) {
  2051. channel_b = switch_core_session_get_channel(session_b);
  2052. br_b_uuid = switch_channel_get_partner_uuid(channel_b);
  2053. tech_pvt = switch_core_session_get_private(session_b);
  2054. stop_hold(session_a, switch_channel_get_partner_uuid(channel_b));
  2055. switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
  2056. }
  2057. if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND &&
  2058. switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) {
  2059. cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
  2060. if (br_a_uuid && br_b_uuid) {
  2061. switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
  2062. } else if (br_a_uuid && digits) {
  2063. session_t = switch_core_session_locate(br_a_uuid);
  2064. } else if (br_b_uuid && digits) {
  2065. session_t = switch_core_session_locate(br_b_uuid);
  2066. }
  2067. }
  2068. if (session_t) {
  2069. switch_ivr_session_transfer(session_t, caller_data->collected, NULL, NULL);
  2070. switch_core_session_rwunlock(session_t);
  2071. }
  2072. if (session_a) {
  2073. switch_core_session_rwunlock(session_a);
  2074. }
  2075. if (session_b) {
  2076. switch_core_session_rwunlock(session_b);
  2077. }
  2078. }
  2079. while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2080. tech_pvt = switch_core_session_get_private(session);
  2081. switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
  2082. channel = switch_core_session_get_channel(session);
  2083. switch_channel_hangup(channel, cause);
  2084. ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
  2085. switch_core_session_rwunlock(session);
  2086. }
  2087. ftdm_channel_clear_token(sigmsg->channel, NULL);
  2088. }
  2089. break;
  2090. case FTDM_SIGEVENT_ADD_CALL:
  2091. {
  2092. cycle_foreground(sigmsg->channel, 1, NULL);
  2093. }
  2094. break;
  2095. case FTDM_SIGEVENT_FLASH:
  2096. {
  2097. chan_pvt_t *chanpvt = ftdm_channel_get_private(sigmsg->channel);
  2098. if (!chanpvt) {
  2099. ftdm_log(FTDM_LOG_ERROR, "%d:%d has no private data, can't handle FXS features! (this is a bug)\n",
  2100. chanid, spanid);
  2101. break;
  2102. }
  2103. if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) {
  2104. switch_core_session_t *session;
  2105. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2106. const char *buuid;
  2107. switch_channel_t *channel;
  2108. private_t *tech_pvt;
  2109. tech_pvt = switch_core_session_get_private(session);
  2110. channel = switch_core_session_get_channel(session);
  2111. buuid = switch_channel_get_partner_uuid(channel);
  2112. ftdm_channel_call_unhold(sigmsg->channel);
  2113. stop_hold(session, buuid);
  2114. switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
  2115. switch_core_session_rwunlock(session);
  2116. }
  2117. } else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) {
  2118. if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) {
  2119. switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY);
  2120. if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) {
  2121. channel = switch_core_session_get_channel(session);
  2122. switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
  2123. ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
  2124. switch_core_session_rwunlock(session);
  2125. }
  2126. cycle_foreground(sigmsg->channel, 1, NULL);
  2127. } else {
  2128. char *cmd;
  2129. cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0));
  2130. switch_set_flag(chanpvt, ANALOG_OPTION_3WAY);
  2131. cycle_foreground(sigmsg->channel, 1, cmd);
  2132. free(cmd);
  2133. }
  2134. } else if ((SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_CALL_SWAP)
  2135. || (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)
  2136. ) {
  2137. cycle_foreground(sigmsg->channel, 1, NULL);
  2138. if (tokencount == 1) {
  2139. ftdm_channel_call_hold(sigmsg->channel);
  2140. }
  2141. }
  2142. }
  2143. break;
  2144. case FTDM_SIGEVENT_COLLECTED_DIGIT:
  2145. {
  2146. int span_id = ftdm_channel_get_span_id(sigmsg->channel);
  2147. char *dtmf = sigmsg->ev_data.collected.digits;
  2148. char *regex = SPAN_CONFIG[span_id].dial_regex;
  2149. char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
  2150. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  2151. if (zstr(regex)) {
  2152. regex = NULL;
  2153. }
  2154. if (zstr(fail_regex)) {
  2155. fail_regex = NULL;
  2156. }
  2157. ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf);
  2158. switch_set_string(caller_data->collected, dtmf);
  2159. if ((regex || fail_regex) && !zstr(dtmf)) {
  2160. switch_regex_t *re = NULL;
  2161. int ovector[30];
  2162. int match = 0;
  2163. if (fail_regex) {
  2164. match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  2165. status = match ? FTDM_SUCCESS : FTDM_BREAK;
  2166. switch_regex_safe_free(re);
  2167. ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match");
  2168. }
  2169. if (status == FTDM_SUCCESS && regex) {
  2170. match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  2171. status = match ? FTDM_BREAK : FTDM_SUCCESS;
  2172. switch_regex_safe_free(re);
  2173. ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match");
  2174. }
  2175. ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf);
  2176. }
  2177. }
  2178. break;
  2179. default:
  2180. {
  2181. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
  2182. sigmsg->event_id, spanid, chanid);
  2183. }
  2184. break;
  2185. }
  2186. return status;
  2187. }
  2188. static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
  2189. {
  2190. uint32_t phyid, chanid, spanid;
  2191. switch_core_session_t *session = NULL;
  2192. switch_channel_t *channel = NULL;
  2193. ftdm_status_t status = FTDM_SUCCESS;
  2194. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  2195. phyid = ftdm_channel_get_ph_id(sigmsg->channel);
  2196. chanid = ftdm_channel_get_id(sigmsg->channel);
  2197. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  2198. ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel %d\n", ftdm_signal_event2str(sigmsg->event_id), phyid);
  2199. if (on_common_signal(sigmsg) == FTDM_BREAK) {
  2200. return FTDM_SUCCESS;
  2201. }
  2202. switch (sigmsg->event_id) {
  2203. case FTDM_SIGEVENT_STOP: /* on_call_disconnect from the R2 side */
  2204. {
  2205. private_t *tech_pvt = NULL;
  2206. while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2207. tech_pvt = switch_core_session_get_private(session);
  2208. switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
  2209. channel = switch_core_session_get_channel(session);
  2210. switch_channel_hangup(channel, caller_data->hangup_cause);
  2211. switch_core_session_rwunlock(session);
  2212. }
  2213. }
  2214. break;
  2215. case FTDM_SIGEVENT_START: /* on_call_offered from the R2 side */
  2216. {
  2217. status = ftdm_channel_from_event(sigmsg, &session);
  2218. }
  2219. break;
  2220. case FTDM_SIGEVENT_COLLECTED_DIGIT: /* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */
  2221. {
  2222. ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  2223. int span_id = ftdm_channel_get_span_id(sigmsg->channel);
  2224. char *regex = SPAN_CONFIG[span_id].dial_regex;
  2225. char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
  2226. if (zstr(regex)) {
  2227. regex = NULL;
  2228. }
  2229. if (zstr(fail_regex)) {
  2230. fail_regex = NULL;
  2231. }
  2232. ftdm_log(FTDM_LOG_DEBUG, "R2 DNIS so far [%s]\n", caller_data->dnis.digits);
  2233. if ((regex || fail_regex) && !zstr(caller_data->dnis.digits)) {
  2234. switch_regex_t *re = NULL;
  2235. int ovector[30];
  2236. int match = 0;
  2237. if (fail_regex) {
  2238. match = switch_regex_perform(caller_data->dnis.digits, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  2239. status = match ? FTDM_SUCCESS : FTDM_BREAK;
  2240. switch_regex_safe_free(re);
  2241. }
  2242. if (status == FTDM_SUCCESS && regex) {
  2243. match = switch_regex_perform(caller_data->dnis.digits, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
  2244. status = match ? FTDM_BREAK : FTDM_SUCCESS;
  2245. }
  2246. switch_regex_safe_free(re);
  2247. }
  2248. }
  2249. break;
  2250. case FTDM_SIGEVENT_PROGRESS:
  2251. {
  2252. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2253. channel = switch_core_session_get_channel(session);
  2254. switch_channel_mark_ring_ready(channel);
  2255. switch_core_session_rwunlock(session);
  2256. }
  2257. }
  2258. break;
  2259. case FTDM_SIGEVENT_PROGRESS_MEDIA:
  2260. {
  2261. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2262. channel = switch_core_session_get_channel(session);
  2263. switch_channel_mark_pre_answered(channel);
  2264. switch_core_session_rwunlock(session);
  2265. }
  2266. }
  2267. break;
  2268. case FTDM_SIGEVENT_UP:
  2269. {
  2270. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2271. channel = switch_core_session_get_channel(session);
  2272. switch_channel_mark_answered(channel);
  2273. ftdm_enable_channel_dtmf(sigmsg->channel, channel);
  2274. switch_core_session_rwunlock(session);
  2275. }
  2276. }
  2277. break;
  2278. case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
  2279. {
  2280. ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status;
  2281. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n",
  2282. spanid, chanid, ftdm_signaling_status2str(sigstatus));
  2283. }
  2284. break;
  2285. case FTDM_SIGEVENT_PROCEED:
  2286. case FTDM_SIGEVENT_INDICATION_COMPLETED:
  2287. break;
  2288. default:
  2289. {
  2290. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n",
  2291. sigmsg->event_id, spanid, chanid);
  2292. }
  2293. break;
  2294. }
  2295. return status;
  2296. }
  2297. static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
  2298. {
  2299. switch_core_session_t *session = NULL;
  2300. switch_channel_t *channel = NULL;
  2301. ftdm_caller_data_t *caller_data;
  2302. uint32_t spanid, chanid;
  2303. ftdm_log(FTDM_LOG_DEBUG, "got clear channel sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
  2304. caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
  2305. chanid = ftdm_channel_get_id(sigmsg->channel);
  2306. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  2307. if (on_common_signal(sigmsg) == FTDM_BREAK) {
  2308. return FTDM_SUCCESS;
  2309. }
  2310. switch (sigmsg->event_id) {
  2311. case FTDM_SIGEVENT_START:
  2312. {
  2313. return ftdm_channel_from_event(sigmsg, &session);
  2314. }
  2315. break;
  2316. case FTDM_SIGEVENT_STOP:
  2317. case FTDM_SIGEVENT_RESTART:
  2318. {
  2319. private_t *tech_pvt = NULL;
  2320. while ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2321. tech_pvt = switch_core_session_get_private(session);
  2322. switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
  2323. channel = switch_core_session_get_channel(session);
  2324. switch_channel_hangup(channel, caller_data->hangup_cause);
  2325. switch_core_session_rwunlock(session);
  2326. }
  2327. }
  2328. break;
  2329. case FTDM_SIGEVENT_UP:
  2330. {
  2331. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2332. channel = switch_core_session_get_channel(session);
  2333. switch_channel_mark_answered(channel);
  2334. ftdm_enable_channel_dtmf(sigmsg->channel, channel);
  2335. switch_core_session_rwunlock(session);
  2336. } else {
  2337. const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
  2338. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
  2339. spanid, chanid, (uuid) ? uuid : "N/A");
  2340. }
  2341. }
  2342. break;
  2343. case FTDM_SIGEVENT_PROGRESS_MEDIA:
  2344. {
  2345. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2346. channel = switch_core_session_get_channel(session);
  2347. switch_channel_mark_pre_answered(channel);
  2348. switch_core_session_rwunlock(session);
  2349. } else {
  2350. const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
  2351. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
  2352. spanid, chanid, (uuid) ? uuid : "N/A");
  2353. }
  2354. }
  2355. break;
  2356. case FTDM_SIGEVENT_PROGRESS:
  2357. case FTDM_SIGEVENT_RINGING:
  2358. {
  2359. if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
  2360. channel = switch_core_session_get_channel(session);
  2361. switch_channel_mark_ring_ready(channel);
  2362. switch_core_session_rwunlock(session);
  2363. } else {
  2364. const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
  2365. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
  2366. spanid, chanid, (uuid) ? uuid : "N/A");
  2367. }
  2368. }
  2369. break;
  2370. case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
  2371. {
  2372. ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status;
  2373. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
  2374. spanid, chanid, ftdm_signaling_status2str(sigstatus));
  2375. }
  2376. break;
  2377. case FTDM_SIGEVENT_PROCEED:
  2378. case FTDM_SIGEVENT_FACILITY:
  2379. case FTDM_SIGEVENT_TRANSFER_COMPLETED:
  2380. /* FS does not have handlers for these messages, so ignore them for now */
  2381. break;
  2382. default:
  2383. {
  2384. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
  2385. sigmsg->event_id, spanid, chanid);
  2386. }
  2387. break;
  2388. }
  2389. return FTDM_SUCCESS;
  2390. }
  2391. static FIO_SIGNAL_CB_FUNCTION(on_analog_signal)
  2392. {
  2393. uint32_t spanid, chanid;
  2394. ftdm_chan_type_t type;
  2395. ftdm_status_t status = FTDM_FAIL;
  2396. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  2397. chanid = ftdm_channel_get_span_id(sigmsg->channel);
  2398. type = ftdm_channel_get_type(sigmsg->channel);
  2399. if (on_common_signal(sigmsg) == FTDM_BREAK) {
  2400. return FTDM_SUCCESS;
  2401. }
  2402. switch (type) {
  2403. case FTDM_CHAN_TYPE_FXO:
  2404. case FTDM_CHAN_TYPE_EM:
  2405. {
  2406. status = on_fxo_signal(sigmsg);
  2407. }
  2408. break;
  2409. case FTDM_CHAN_TYPE_FXS:
  2410. {
  2411. status = on_fxs_signal(sigmsg);
  2412. }
  2413. break;
  2414. default:
  2415. {
  2416. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled analog channel type %d for channel %d:%d\n",
  2417. type, spanid, chanid);
  2418. }
  2419. break;
  2420. }
  2421. return status;
  2422. }
  2423. static void ftdm_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
  2424. {
  2425. char *data = NULL;
  2426. va_list ap;
  2427. va_start(ap, fmt);
  2428. if (switch_vasprintf(&data, fmt, ap) != -1) {
  2429. switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data);
  2430. }
  2431. if (data) {
  2432. free(data);
  2433. }
  2434. va_end(ap);
  2435. }
  2436. static uint32_t enable_analog_option(const char *str, uint32_t current_options)
  2437. {
  2438. if (!strcasecmp(str, "3-way")) {
  2439. current_options |= ANALOG_OPTION_3WAY;
  2440. current_options &= ~ANALOG_OPTION_CALL_SWAP;
  2441. } else if (!strcasecmp(str, "call-swap")) {
  2442. current_options |= ANALOG_OPTION_CALL_SWAP;
  2443. current_options &= ~ANALOG_OPTION_3WAY;
  2444. }
  2445. return current_options;
  2446. }
  2447. #define LOAD_ERROR(...) { \
  2448. ftdm_log(FTDM_LOG_ERROR, __VA_ARGS__); \
  2449. globals.config_error = 1; \
  2450. }
  2451. /*
  2452. * Create ftdm_conf_node_t tree based on a fixed pattern XML configuration list.
  2453. * Last 2 args are for limited aka dumb recursivity.
  2454. */
  2455. static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode,
  2456. const char *list_name, const char *list_element_name,
  2457. const char *sub_list_name, const char *sub_list_element_name)
  2458. {
  2459. char *var, *val;
  2460. switch_xml_t list;
  2461. switch_xml_t element;
  2462. switch_xml_t param;
  2463. ftdm_conf_node_t *n_list;
  2464. ftdm_conf_node_t *n_element;
  2465. list = switch_xml_child(swnode, list_name);
  2466. if (!list) {
  2467. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name);
  2468. return -1;
  2469. }
  2470. if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) {
  2471. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name);
  2472. return -1;
  2473. }
  2474. for (element = switch_xml_child(list, list_element_name); element; element = element->next) {
  2475. char *element_name = (char *) switch_xml_attr(element, "name");
  2476. if (!element_name) {
  2477. continue;
  2478. }
  2479. if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) {
  2480. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name);
  2481. return -1;
  2482. }
  2483. ftdm_conf_node_add_param(n_element, "name", element_name);
  2484. for (param = switch_xml_child(element, "param"); param; param = param->next) {
  2485. var = (char *) switch_xml_attr_soft(param, "name");
  2486. val = (char *) switch_xml_attr_soft(param, "value");
  2487. ftdm_conf_node_add_param(n_element, var, val);
  2488. }
  2489. if (sub_list_name && sub_list_element_name) {
  2490. if (add_config_list_nodes(element, n_element, sub_list_name, sub_list_element_name, NULL, NULL)) {
  2491. return -1;
  2492. }
  2493. }
  2494. }
  2495. return 0;
  2496. }
  2497. /*
  2498. * Create ftdm_conf_node_t tree based on a fixed pattern XML configuration list.
  2499. * Last arg is to specify if we have any sublist for e.g.:
  2500. *
  2501. * <list_name>
  2502. * <list_element_name>
  2503. * <param name="xxx" value="xxx"/>
  2504. * <sub-list>
  2505. * <param name="xxx" value="xxx"/>
  2506. * </sub-list>
  2507. * </list_element_name>
  2508. * </list_name>
  2509. */
  2510. static int add_config_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode,
  2511. const char *list_name, const char *list_element_name, const char *sub_list_name)
  2512. {
  2513. char *var, *val;
  2514. switch_xml_t list;
  2515. switch_xml_t sub_list;
  2516. switch_xml_t element;
  2517. switch_xml_t param;
  2518. ftdm_conf_node_t *n_list;
  2519. ftdm_conf_node_t *n_element;
  2520. list = switch_xml_child(swnode, list_name);
  2521. if (!list) {
  2522. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name);
  2523. return -1;
  2524. }
  2525. if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) {
  2526. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name);
  2527. return -1;
  2528. }
  2529. for (element = switch_xml_child(list, list_element_name); element; element = element->next) {
  2530. char *element_name = (char *) switch_xml_attr(element, "name");
  2531. if (!element_name) {
  2532. continue;
  2533. }
  2534. if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) {
  2535. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name);
  2536. return -1;
  2537. }
  2538. ftdm_conf_node_add_param(n_element, "name", element_name);
  2539. for (param = switch_xml_child(element, "param"); param; param = param->next) {
  2540. var = (char *) switch_xml_attr_soft(param, "name");
  2541. val = (char *) switch_xml_attr_soft(param, "value");
  2542. ftdm_conf_node_add_param(n_element, var, val);
  2543. }
  2544. /*If we have single node list */
  2545. if (sub_list_name ) {
  2546. sub_list = switch_xml_child(element, sub_list_name);
  2547. if (!sub_list) {
  2548. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no sub_list %s found\n", sub_list_name);
  2549. return -1;
  2550. }
  2551. for (param = switch_xml_child(sub_list, "param"); param; param = param->next) {
  2552. var = (char *) switch_xml_attr_soft(param, "name");
  2553. val = (char *) switch_xml_attr_soft(param, "value");
  2554. ftdm_conf_node_add_param(n_element, var, val);
  2555. }
  2556. }
  2557. }
  2558. return 0;
  2559. }
  2560. static ftdm_conf_node_t *_get_ss7_config_node(switch_xml_t cfg, const char *confname, const char *operating_mode)
  2561. {
  2562. switch_xml_t signode, ss7configs, isup, gen, param;
  2563. ftdm_conf_node_t *rootnode, *list;
  2564. char *var, *val;
  2565. int is_isup = 0x00;
  2566. /* try to find the conf in the hash first */
  2567. rootnode = switch_core_hash_find(globals.ss7_configs, confname);
  2568. if (rootnode) {
  2569. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ss7 config %s was found in the hash already\n", confname);
  2570. return rootnode;
  2571. }
  2572. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not found %s config in hash, searching in xml ...\n", confname);
  2573. signode = switch_xml_child(cfg, "signaling_configs");
  2574. if (!signode) {
  2575. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'signaling_configs' XML config section\n");
  2576. return NULL;
  2577. }
  2578. ss7configs = switch_xml_child(signode, "sngss7_configs");
  2579. if (!ss7configs) {
  2580. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'sngss7_configs' XML config section\n");
  2581. return NULL;
  2582. }
  2583. /* sng_isup and ss7config xml childs are treated the same way. sng_isup was used initially, but does not make sense
  2584. * for configurations that do not have an ISUP layer, sng_isup is kept for backward compatibility */
  2585. /* search the ss7config */
  2586. for (isup = switch_xml_child(ss7configs, "sngss7_config"); isup; isup = isup->next) {
  2587. char *name = (char *) switch_xml_attr(isup, "name");
  2588. if (!name) {
  2589. continue;
  2590. }
  2591. if (!strcasecmp(name, confname)) {
  2592. break;
  2593. }
  2594. }
  2595. if (!isup) {
  2596. /* search the isup config */
  2597. for (isup = switch_xml_child(ss7configs, "sng_isup"); isup; isup = isup->next) {
  2598. char *name = (char *) switch_xml_attr(isup, "name");
  2599. if (!name) {
  2600. continue;
  2601. }
  2602. if (!strcasecmp(name, confname)) {
  2603. break;
  2604. }
  2605. }
  2606. if (!isup) {
  2607. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found '%s' ss7config or sng_isup XML config section\n", confname);
  2608. return NULL;
  2609. }
  2610. }
  2611. /* found our XML chunk, create the root node */
  2612. if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_isup", &rootnode, NULL))) {
  2613. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create root node for sng_isup config %s\n", confname);
  2614. return NULL;
  2615. }
  2616. /* operating mode , M2UA or ISUP */
  2617. if (operating_mode && ('\0' != operating_mode[0])) {
  2618. if (!strcasecmp(operating_mode, "ISUP")) {
  2619. is_isup = 0x01;
  2620. }
  2621. else if (!strcasecmp(operating_mode, "M2UA_SG")) {
  2622. is_isup = 0x00;
  2623. } else {
  2624. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid operating Mode[%s] \n", operating_mode);
  2625. ftdm_conf_node_destroy(rootnode);
  2626. return NULL;
  2627. }
  2628. } else {
  2629. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Operating mode not specified, default to ISUP \n");
  2630. is_isup = 0x01;
  2631. }
  2632. /* add sng_gen */
  2633. gen = switch_xml_child(isup, "sng_gen");
  2634. if (gen == NULL) {
  2635. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_gen for sng_isup config %s\n", confname);
  2636. ftdm_conf_node_destroy(rootnode);
  2637. return NULL;
  2638. }
  2639. if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_gen", &list, rootnode))) {
  2640. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", "sng_gen", confname);
  2641. ftdm_conf_node_destroy(rootnode);
  2642. return NULL;
  2643. }
  2644. for (param = switch_xml_child(gen, "param"); param; param = param->next) {
  2645. var = (char *) switch_xml_attr_soft(param, "name");
  2646. val = (char *) switch_xml_attr_soft(param, "value");
  2647. ftdm_conf_node_add_param(list, var, val);
  2648. }
  2649. /* add relay channels */
  2650. if (add_config_list_nodes(isup, rootnode, "sng_relay", "relay_channel", NULL, NULL)) {
  2651. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_relay for sng_isup config %s\n", confname);
  2652. ftdm_conf_node_destroy(rootnode);
  2653. return NULL;
  2654. }
  2655. /* add mtp1 links */
  2656. if (add_config_list_nodes(isup, rootnode, "mtp1_links", "mtp1_link", NULL, NULL)) {
  2657. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp1_links for sng_isup config %s\n", confname);
  2658. ftdm_conf_node_destroy(rootnode);
  2659. return NULL;
  2660. }
  2661. /* add mtp2 links */
  2662. if (add_config_list_nodes(isup, rootnode, "mtp2_links", "mtp2_link", NULL, NULL)) {
  2663. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp2_links for sng_isup config %s\n", confname);
  2664. ftdm_conf_node_destroy(rootnode);
  2665. return NULL;
  2666. }
  2667. if (is_isup) {
  2668. /* add mtp3 links */
  2669. if (add_config_list_nodes(isup, rootnode, "mtp3_links", "mtp3_link", NULL, NULL)) {
  2670. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp3_links for sng_isup config %s\n", confname);
  2671. ftdm_conf_node_destroy(rootnode);
  2672. return NULL;
  2673. }
  2674. /* add mtp linksets */
  2675. if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", NULL, NULL)) {
  2676. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname);
  2677. ftdm_conf_node_destroy(rootnode);
  2678. return NULL;
  2679. }
  2680. /* add mtp routes */
  2681. if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", "linksets", "linkset")) {
  2682. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname);
  2683. ftdm_conf_node_destroy(rootnode);
  2684. return NULL;
  2685. }
  2686. /* add isup interfaces */
  2687. if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) {
  2688. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname);
  2689. ftdm_conf_node_destroy(rootnode);
  2690. return NULL;
  2691. }
  2692. /* add cc spans */
  2693. if (add_config_list_nodes(isup, rootnode, "cc_spans", "cc_span", NULL, NULL)) {
  2694. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process cc_spans for sng_isup config %s\n", confname);
  2695. ftdm_conf_node_destroy(rootnode);
  2696. return NULL;
  2697. }
  2698. } else {
  2699. /* add sctp links */
  2700. if (add_config_nodes(isup, rootnode, "sng_sctp_interfaces", "sng_sctp_interface", "sng_source_addresses")) {
  2701. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_sctp_interface for sng_isup config %s\n", confname);
  2702. ftdm_conf_node_destroy(rootnode);
  2703. return NULL;
  2704. }
  2705. if (add_config_list_nodes(isup, rootnode, "sng_nif_interfaces", "sng_nif_interface", NULL, NULL)) {
  2706. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_nif_interfaces for sng_isup config %s\n", confname);
  2707. ftdm_conf_node_destroy(rootnode);
  2708. return NULL;
  2709. }
  2710. if (add_config_list_nodes(isup, rootnode, "sng_m2ua_interfaces", "sng_m2ua_interface", NULL, NULL)) {
  2711. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_interfaces for sng_isup config %s\n", confname);
  2712. ftdm_conf_node_destroy(rootnode);
  2713. return NULL;
  2714. }
  2715. if (add_config_nodes(isup, rootnode, "sng_m2ua_peer_interfaces", "sng_m2ua_peer_interface", "sng_destination_addresses")) {
  2716. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_peer_interfaces for sng_isup config %s\n", confname);
  2717. ftdm_conf_node_destroy(rootnode);
  2718. return NULL;
  2719. }
  2720. if (add_config_nodes(isup, rootnode, "sng_m2ua_cluster_interfaces", "sng_m2ua_cluster_interface", "sng_m2ua_peers")) {
  2721. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_cluster_interfaces for sng_isup config %s\n", confname);
  2722. ftdm_conf_node_destroy(rootnode);
  2723. return NULL;
  2724. }
  2725. }
  2726. switch_core_hash_insert(globals.ss7_configs, confname, rootnode);
  2727. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname);
  2728. return rootnode;
  2729. }
  2730. static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_conf_parameter_t *parameters, int len)
  2731. {
  2732. switch_xml_t profnode, profile, param;
  2733. int paramindex = 0;
  2734. profnode = switch_xml_child(cfg, "config_profiles");
  2735. if (!profnode) {
  2736. LOAD_ERROR("cannot find profile '%s', there is no 'config_profiles' XML section\n", profname);
  2737. return 0;
  2738. }
  2739. /* search the profile */
  2740. for (profile = switch_xml_child(profnode, "profile"); profile; profile = profile->next) {
  2741. char *name = (char *) switch_xml_attr(profile, "name");
  2742. if (!name) {
  2743. continue;
  2744. }
  2745. if (!strcasecmp(name, profname)) {
  2746. break;
  2747. }
  2748. }
  2749. if (!profile) {
  2750. LOAD_ERROR("failed to find profile '%s'\n", profname);
  2751. return 0;
  2752. }
  2753. for (param = switch_xml_child(profile, "param"); param; param = param->next) {
  2754. char *var = (char *) switch_xml_attr_soft(param, "name");
  2755. char *val = (char *) switch_xml_attr_soft(param, "value");
  2756. if (!var || !val) {
  2757. continue;
  2758. }
  2759. parameters[paramindex].var = var;
  2760. parameters[paramindex].val = val;
  2761. paramindex++;
  2762. }
  2763. return paramindex;
  2764. }
  2765. static void parse_gsm_spans(switch_xml_t cfg, switch_xml_t spans)
  2766. {
  2767. switch_xml_t myspan, param;
  2768. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  2769. ftdm_status_t zstatus = FTDM_FAIL;
  2770. const char *context = "default";
  2771. const char *dialplan = "XML";
  2772. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  2773. char *id = (char *) switch_xml_attr(myspan, "id");
  2774. char *name = (char *) switch_xml_attr(myspan, "name");
  2775. char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
  2776. ftdm_span_t *span = NULL;
  2777. uint32_t span_id = 0;
  2778. unsigned paramindex = 0;
  2779. if (!name && !id) {
  2780. LOAD_ERROR("GSM span missing required attribute 'id' or 'name', skipping ...\n");
  2781. continue;
  2782. }
  2783. if (name) {
  2784. zstatus = ftdm_span_find_by_name(name, &span);
  2785. } else {
  2786. if (switch_is_number(id)) {
  2787. span_id = atoi(id);
  2788. zstatus = ftdm_span_find(span_id, &span);
  2789. }
  2790. if (zstatus != FTDM_SUCCESS) {
  2791. zstatus = ftdm_span_find_by_name(id, &span);
  2792. }
  2793. }
  2794. if (zstatus != FTDM_SUCCESS) {
  2795. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  2796. continue;
  2797. }
  2798. if (!span_id) {
  2799. span_id = ftdm_span_get_id(span);
  2800. }
  2801. memset(spanparameters, 0, sizeof(spanparameters));
  2802. paramindex = 0;
  2803. if (configname) {
  2804. paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
  2805. if (paramindex) {
  2806. ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
  2807. }
  2808. }
  2809. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  2810. char *var = (char *) switch_xml_attr_soft(param, "name");
  2811. char *val = (char *) switch_xml_attr_soft(param, "value");
  2812. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  2813. LOAD_ERROR("Too many parameters for GSM span, ignoring any parameter after %s\n", var);
  2814. break;
  2815. }
  2816. if (!strcasecmp(var, "context")) {
  2817. context = val;
  2818. } else if (!strcasecmp(var, "dialplan")) {
  2819. dialplan = val;
  2820. } else {
  2821. spanparameters[paramindex].var = var;
  2822. spanparameters[paramindex].val = val;
  2823. paramindex++;
  2824. }
  2825. }
  2826. if (ftdm_configure_span_signaling(span,
  2827. "gsm",
  2828. on_clear_channel_signal,
  2829. spanparameters) != FTDM_SUCCESS) {
  2830. LOAD_ERROR("Error configuring Sangoma GSM FreeTDM span %d\n", span_id);
  2831. continue;
  2832. }
  2833. SPAN_CONFIG[span_id].span = span;
  2834. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  2835. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  2836. switch_copy_string(SPAN_CONFIG[span_id].type, "GSM", sizeof(SPAN_CONFIG[span_id].type));
  2837. ftdm_log(FTDM_LOG_DEBUG, "Configured GSM FreeTDM span %d\n", span_id);
  2838. ftdm_span_start(span);
  2839. }
  2840. }
  2841. static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
  2842. {
  2843. switch_xml_t myspan, param;
  2844. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  2845. ftdm_status_t zstatus = FTDM_FAIL;
  2846. const char *context = "default";
  2847. const char *dialplan = "XML";
  2848. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  2849. char *id = (char *) switch_xml_attr(myspan, "id");
  2850. char *name = (char *) switch_xml_attr(myspan, "name");
  2851. char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
  2852. ftdm_span_t *span = NULL;
  2853. uint32_t span_id = 0;
  2854. unsigned paramindex = 0;
  2855. if (!name && !id) {
  2856. LOAD_ERROR("sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n");
  2857. continue;
  2858. }
  2859. if (name) {
  2860. zstatus = ftdm_span_find_by_name(name, &span);
  2861. } else {
  2862. if (switch_is_number(id)) {
  2863. span_id = atoi(id);
  2864. zstatus = ftdm_span_find(span_id, &span);
  2865. }
  2866. if (zstatus != FTDM_SUCCESS) {
  2867. zstatus = ftdm_span_find_by_name(id, &span);
  2868. }
  2869. }
  2870. if (zstatus != FTDM_SUCCESS) {
  2871. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  2872. continue;
  2873. }
  2874. if (!span_id) {
  2875. span_id = ftdm_span_get_id(span);
  2876. }
  2877. memset(spanparameters, 0, sizeof(spanparameters));
  2878. paramindex = 0;
  2879. if (configname) {
  2880. paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
  2881. if (paramindex) {
  2882. ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
  2883. }
  2884. }
  2885. /* some defaults first */
  2886. SPAN_CONFIG[span_id].limit_backend = "hash";
  2887. SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
  2888. SPAN_CONFIG[span_id].digital_sampling_rate = 8000;
  2889. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  2890. char *var = (char *) switch_xml_attr_soft(param, "name");
  2891. char *val = (char *) switch_xml_attr_soft(param, "value");
  2892. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  2893. LOAD_ERROR("Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
  2894. break;
  2895. }
  2896. if (!strcasecmp(var, "context")) {
  2897. context = val;
  2898. } else if (!strcasecmp(var, "dialplan")) {
  2899. dialplan = val;
  2900. } else if (!strcasecmp(var, "unrestricted-digital-codec")) {
  2901. //switch_core_strdup(pool, val);
  2902. const switch_codec_implementation_t *codec = NULL;
  2903. int num_codecs;
  2904. num_codecs = switch_loadable_module_get_codecs_sorted(&codec, NULL, 1, &val, 1);
  2905. if (num_codecs != 1 || !codec) {
  2906. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
  2907. "Failed finding codec %s for unrestricted digital calls\n", val);
  2908. } else {
  2909. SPAN_CONFIG[span_id].digital_codec = switch_core_strdup(module_pool, codec->iananame);
  2910. SPAN_CONFIG[span_id].digital_sampling_rate = codec->samples_per_second;
  2911. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
  2912. "Unrestricted digital codec is %s at %dhz for span %d\n",
  2913. SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate, span_id);
  2914. }
  2915. } else if (!strcasecmp(var, "call_limit_backend")) {
  2916. SPAN_CONFIG[span_id].limit_backend = val;
  2917. ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
  2918. } else if (!strcasecmp(var, "call_limit_rate")) {
  2919. int calls;
  2920. int seconds;
  2921. if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
  2922. LOAD_ERROR("Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
  2923. } else {
  2924. if (calls < 1 || seconds < 1) {
  2925. LOAD_ERROR("Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
  2926. } else {
  2927. SPAN_CONFIG[span_id].limit_calls = calls;
  2928. SPAN_CONFIG[span_id].limit_seconds = seconds;
  2929. }
  2930. }
  2931. } else if (!strcasecmp(var, "call_limit_reset_event")) {
  2932. if (!strcasecmp(val, "answer")) {
  2933. SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
  2934. } else {
  2935. LOAD_ERROR("Invalid %s parameter value, only accepted event is 'answer'\n", var);
  2936. }
  2937. } else {
  2938. spanparameters[paramindex].var = var;
  2939. spanparameters[paramindex].val = val;
  2940. paramindex++;
  2941. }
  2942. }
  2943. if (ftdm_configure_span_signaling(span,
  2944. "sangoma_isdn",
  2945. on_clear_channel_signal,
  2946. spanparameters) != FTDM_SUCCESS) {
  2947. LOAD_ERROR("Error configuring Sangoma ISDN FreeTDM span %d\n", span_id);
  2948. continue;
  2949. }
  2950. SPAN_CONFIG[span_id].span = span;
  2951. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  2952. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  2953. switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type));
  2954. ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id);
  2955. ftdm_span_start(span);
  2956. }
  2957. }
  2958. static switch_status_t load_config_path(void)
  2959. {
  2960. const char *cf = "freetdm.conf";
  2961. switch_xml_t cfg, xml, settings, param;
  2962. if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
  2963. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
  2964. return SWITCH_STATUS_TERM;
  2965. }
  2966. if ((settings = switch_xml_child(cfg, "settings"))) {
  2967. for (param = switch_xml_child(settings, "param"); param; param = param->next) {
  2968. char *var = (char *) switch_xml_attr_soft(param, "name");
  2969. char *val = (char *) switch_xml_attr_soft(param, "value");
  2970. if (!strcasecmp(var, "mod-dir")) {
  2971. ftdm_global_set_mod_directory(val);
  2972. } else if (!strcasecmp(var, "conf-dir")) {
  2973. ftdm_global_set_config_directory(val);
  2974. }
  2975. }
  2976. }
  2977. switch_xml_free(xml);
  2978. return SWITCH_STATUS_SUCCESS;
  2979. }
  2980. static switch_status_t load_config(void)
  2981. {
  2982. const char *cf = "freetdm.conf";
  2983. switch_xml_t cfg, xml, settings, param, spans, myspan;
  2984. ftdm_conf_node_t *ss7confnode = NULL;
  2985. unsigned int i = 0;
  2986. ftdm_channel_t *fchan = NULL;
  2987. ftdm_iterator_t *chaniter = NULL;
  2988. ftdm_iterator_t *curr = NULL;
  2989. memset(&globals, 0, sizeof(globals));
  2990. switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
  2991. if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
  2992. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
  2993. return SWITCH_STATUS_TERM;
  2994. }
  2995. if ((settings = switch_xml_child(cfg, "settings"))) {
  2996. for (param = switch_xml_child(settings, "param"); param; param = param->next) {
  2997. char *var = (char *) switch_xml_attr_soft(param, "name");
  2998. char *val = (char *) switch_xml_attr_soft(param, "value");
  2999. if (!strcasecmp(var, "debug")) {
  3000. globals.debug = atoi(val);
  3001. } else if (!strcasecmp(var, "hold-music")) {
  3002. switch_set_string(globals.hold_music, val);
  3003. } else if (!strcasecmp(var, "crash-on-assert")) {
  3004. globals.crash_on_assert = (uint8_t)switch_true(val);
  3005. } else if (!strcasecmp(var, "fail-on-error")) {
  3006. globals.fail_on_error = (uint8_t)switch_true(val);
  3007. } else if (!strcasecmp(var, "sip-headers")) {
  3008. globals.sip_headers = switch_true(val);
  3009. } else if (!strcasecmp(var, "enable-analog-option")) {
  3010. globals.analog_options = enable_analog_option(val, globals.analog_options);
  3011. }
  3012. }
  3013. }
  3014. if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) {
  3015. parse_bri_pri_spans(cfg, spans);
  3016. }
  3017. if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
  3018. parse_bri_pri_spans(cfg, spans);
  3019. }
  3020. if ((spans = switch_xml_child(cfg, "gsm_spans"))) {
  3021. parse_gsm_spans(cfg, spans);
  3022. }
  3023. switch_core_hash_init(&globals.ss7_configs);
  3024. if ((spans = switch_xml_child(cfg, "sangoma_ss7_spans"))) {
  3025. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3026. ftdm_status_t zstatus = FTDM_FAIL;
  3027. const char *context = "default";
  3028. const char *dialplan = "XML";
  3029. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  3030. char *id = (char *) switch_xml_attr(myspan, "id");
  3031. char *name = (char *) switch_xml_attr(myspan, "name");
  3032. char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
  3033. char *operating_mode = (char *) switch_xml_attr(myspan, "operating_mode");
  3034. ftdm_span_t *span = NULL;
  3035. uint32_t span_id = 0;
  3036. unsigned paramindex = 0;
  3037. if (!name && !id) {
  3038. LOAD_ERROR("ss7 span missing required attribute 'id' or 'name', skipping ...\n");
  3039. continue;
  3040. }
  3041. if (!configname) {
  3042. LOAD_ERROR("ss7 span missing required attribute, skipping ...\n");
  3043. continue;
  3044. }
  3045. if (name) {
  3046. zstatus = ftdm_span_find_by_name(name, &span);
  3047. } else {
  3048. if (switch_is_number(id)) {
  3049. span_id = atoi(id);
  3050. zstatus = ftdm_span_find(span_id, &span);
  3051. }
  3052. if (zstatus != FTDM_SUCCESS) {
  3053. zstatus = ftdm_span_find_by_name(id, &span);
  3054. }
  3055. }
  3056. if (zstatus != FTDM_SUCCESS) {
  3057. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  3058. continue;
  3059. }
  3060. if (!span_id) {
  3061. span_id = ftdm_span_get_id(span);
  3062. }
  3063. ss7confnode = _get_ss7_config_node(cfg, configname, operating_mode);
  3064. if (!ss7confnode) {
  3065. LOAD_ERROR("Error finding ss7config '%s' for FreeTDM span id: %s\n", configname, switch_str_nil(id));
  3066. continue;
  3067. }
  3068. memset(spanparameters, 0, sizeof(spanparameters));
  3069. paramindex = 0;
  3070. if (operating_mode) {
  3071. spanparameters[paramindex].var = "operating-mode";
  3072. spanparameters[paramindex].val = operating_mode;
  3073. paramindex++;
  3074. }
  3075. spanparameters[paramindex].var = "confnode";
  3076. spanparameters[paramindex].ptr = ss7confnode;
  3077. paramindex++;
  3078. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3079. char *var = (char *) switch_xml_attr_soft(param, "name");
  3080. char *val = (char *) switch_xml_attr_soft(param, "value");
  3081. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  3082. LOAD_ERROR("Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
  3083. break;
  3084. }
  3085. if (!strcasecmp(var, "context")) {
  3086. context = val;
  3087. } else if (!strcasecmp(var, "dialplan")) {
  3088. dialplan = val;
  3089. } else {
  3090. spanparameters[paramindex].var = var;
  3091. spanparameters[paramindex].val = val;
  3092. paramindex++;
  3093. }
  3094. }
  3095. if (ftdm_configure_span_signaling(span,
  3096. "sangoma_ss7",
  3097. on_clear_channel_signal,
  3098. spanparameters) != FTDM_SUCCESS) {
  3099. LOAD_ERROR("Error configuring ss7 FreeTDM span %d\n", span_id);
  3100. continue;
  3101. }
  3102. SPAN_CONFIG[span_id].span = span;
  3103. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  3104. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  3105. switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (SS7)", sizeof(SPAN_CONFIG[span_id].type));
  3106. ftdm_log(FTDM_LOG_DEBUG, "Configured ss7 FreeTDM span %d with config node %s\n", span_id, configname);
  3107. if (FTDM_SUCCESS != ftdm_span_start(span)) {
  3108. LOAD_ERROR("Error Starting ss7 FreeTDM span %d\n", span_id);
  3109. continue;
  3110. }
  3111. }
  3112. }
  3113. if ((spans = switch_xml_child(cfg, "analog_spans"))) {
  3114. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3115. char *id = (char *) switch_xml_attr(myspan, "id");
  3116. char *name = (char *) switch_xml_attr(myspan, "name");
  3117. ftdm_status_t zstatus = FTDM_FAIL;
  3118. const char *context = "default";
  3119. const char *dialplan = "XML";
  3120. const char *tonegroup = NULL;
  3121. char *digit_timeout = NULL;
  3122. char *max_digits = NULL;
  3123. char *hotline = NULL;
  3124. char *dial_regex = NULL;
  3125. char *hold_music = NULL;
  3126. char *fail_dial_regex = NULL;
  3127. const char *enable_callerid = "true";
  3128. const char *answer_polarity = "false";
  3129. const char *hangup_polarity = "false";
  3130. const char *polarity_callerid = "false";
  3131. int polarity_delay = 600;
  3132. int callwaiting = 1;
  3133. int dialtone_timeout = 5000;
  3134. uint32_t span_id = 0, to = 0, max = 0;
  3135. ftdm_span_t *span = NULL;
  3136. analog_option_t analog_options = ANALOG_OPTION_NONE;
  3137. if (name) {
  3138. zstatus = ftdm_span_find_by_name(name, &span);
  3139. } else {
  3140. if (switch_is_number(id)) {
  3141. span_id = atoi(id);
  3142. zstatus = ftdm_span_find(span_id, &span);
  3143. }
  3144. if (zstatus != FTDM_SUCCESS) {
  3145. zstatus = ftdm_span_find_by_name(id, &span);
  3146. }
  3147. }
  3148. if (zstatus != FTDM_SUCCESS) {
  3149. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  3150. continue;
  3151. }
  3152. if (!span_id) {
  3153. span_id = ftdm_span_get_id(span);
  3154. }
  3155. /* some defaults first */
  3156. SPAN_CONFIG[span_id].limit_backend = "hash";
  3157. SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
  3158. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3159. char *var = (char *) switch_xml_attr_soft(param, "name");
  3160. char *val = (char *) switch_xml_attr_soft(param, "value");
  3161. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "analog_spans var = %s\n", var);
  3162. if (!strcasecmp(var, "tonegroup")) {
  3163. tonegroup = val;
  3164. } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
  3165. digit_timeout = val;
  3166. } else if (!strcasecmp(var, "wait-dialtone-timeout")) {
  3167. dialtone_timeout = atoi(val);
  3168. } else if (!strcasecmp(var, "context")) {
  3169. context = val;
  3170. } else if (!strcasecmp(var, "dialplan")) {
  3171. dialplan = val;
  3172. } else if (!strcasecmp(var, "call_limit_backend")) {
  3173. SPAN_CONFIG[span_id].limit_backend = val;
  3174. ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
  3175. } else if (!strcasecmp(var, "call_limit_rate")) {
  3176. int calls;
  3177. int seconds;
  3178. if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
  3179. LOAD_ERROR("Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
  3180. } else {
  3181. if (calls < 1 || seconds < 1) {
  3182. LOAD_ERROR("Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
  3183. } else {
  3184. SPAN_CONFIG[span_id].limit_calls = calls;
  3185. SPAN_CONFIG[span_id].limit_seconds = seconds;
  3186. }
  3187. }
  3188. } else if (!strcasecmp(var, "call_limit_reset_event")) {
  3189. if (!strcasecmp(val, "answer")) {
  3190. SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
  3191. } else {
  3192. LOAD_ERROR("Invalid %s parameter value, only accepted event is 'answer'\n", var);
  3193. }
  3194. } else if (!strcasecmp(var, "dial-regex")) {
  3195. dial_regex = val;
  3196. } else if (!strcasecmp(var, "enable-callerid")) {
  3197. enable_callerid = val;
  3198. } else if (!strcasecmp(var, "answer-polarity-reverse")) {
  3199. answer_polarity = val;
  3200. } else if (!strcasecmp(var, "hangup-polarity-reverse")) {
  3201. hangup_polarity = val;
  3202. } else if (!strcasecmp(var, "polarity-delay")) {
  3203. polarity_delay = atoi(val);
  3204. } else if (!strcasecmp(var, "polarity-callerid")) {
  3205. polarity_callerid = val;
  3206. } else if (!strcasecmp(var, "fail-dial-regex")) {
  3207. fail_dial_regex = val;
  3208. } else if (!strcasecmp(var, "hold-music")) {
  3209. hold_music = val;
  3210. } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) {
  3211. max_digits = val;
  3212. } else if (!strcasecmp(var, "hotline")) {
  3213. hotline = val;
  3214. } else if (!strcasecmp(var, "callwaiting")) {
  3215. callwaiting = switch_true(val) ? 1 : 0;
  3216. } else if (!strcasecmp(var, "enable-analog-option")) {
  3217. analog_options = enable_analog_option(val, analog_options);
  3218. }
  3219. }
  3220. if (!id && !name) {
  3221. LOAD_ERROR("span missing required param 'id'\n");
  3222. continue;
  3223. }
  3224. if (!tonegroup) {
  3225. tonegroup = "us";
  3226. }
  3227. if (digit_timeout) {
  3228. to = atoi(digit_timeout);
  3229. }
  3230. if (max_digits) {
  3231. max = atoi(max_digits);
  3232. }
  3233. if (name) {
  3234. zstatus = ftdm_span_find_by_name(name, &span);
  3235. } else {
  3236. if (switch_is_number(id)) {
  3237. span_id = atoi(id);
  3238. zstatus = ftdm_span_find(span_id, &span);
  3239. }
  3240. if (zstatus != FTDM_SUCCESS) {
  3241. zstatus = ftdm_span_find_by_name(id, &span);
  3242. }
  3243. }
  3244. if (zstatus != FTDM_SUCCESS) {
  3245. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  3246. continue;
  3247. }
  3248. if (!span_id) {
  3249. span_id = ftdm_span_get_id(span);
  3250. }
  3251. if (ftdm_configure_span(span, "analog", on_analog_signal,
  3252. "tonemap", tonegroup,
  3253. "digit_timeout", &to,
  3254. "max_dialstr", &max,
  3255. "hotline", hotline ? hotline : "",
  3256. "enable_callerid", enable_callerid,
  3257. "answer_polarity_reverse", answer_polarity,
  3258. "hangup_polarity_reverse", hangup_polarity,
  3259. "polarity_callerid", polarity_callerid,
  3260. "polarity_delay", &polarity_delay,
  3261. "callwaiting", &callwaiting,
  3262. "wait_dialtone_timeout", &dialtone_timeout,
  3263. FTDM_TAG_END) != FTDM_SUCCESS) {
  3264. LOAD_ERROR("Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
  3265. continue;
  3266. }
  3267. SPAN_CONFIG[span_id].span = span;
  3268. switch_set_string(SPAN_CONFIG[span_id].context, context);
  3269. switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
  3270. SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
  3271. chaniter = ftdm_span_get_chan_iterator(span, NULL);
  3272. for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
  3273. fchan = ftdm_iterator_current(curr);
  3274. ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]);
  3275. }
  3276. ftdm_iterator_free(chaniter);
  3277. if (dial_regex) {
  3278. switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
  3279. }
  3280. if (fail_dial_regex) {
  3281. switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
  3282. }
  3283. if (hold_music) {
  3284. switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music);
  3285. }
  3286. switch_copy_string(SPAN_CONFIG[span_id].type, "analog", sizeof(SPAN_CONFIG[span_id].type));
  3287. ftdm_span_start(span);
  3288. }
  3289. }
  3290. if ((spans = switch_xml_child(cfg, "analog_em_spans"))) {
  3291. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3292. char *id = (char *) switch_xml_attr(myspan, "id");
  3293. char *name = (char *) switch_xml_attr(myspan, "name");
  3294. ftdm_status_t zstatus = FTDM_FAIL;
  3295. const char *context = "default";
  3296. const char *dialplan = "XML";
  3297. const char *tonegroup = NULL;
  3298. char *digit_timeout = NULL;
  3299. char *dial_timeout = NULL;
  3300. char *release_guard_time_ms = NULL;
  3301. char *max_digits = NULL;
  3302. char *dial_regex = NULL;
  3303. char *hold_music = NULL;
  3304. char *fail_dial_regex = NULL;
  3305. char str_false[] = "false";
  3306. char str_empty[] = "";
  3307. char *answer_supervision = str_false;
  3308. char *immediate_ringback = str_false;
  3309. char *ringback_file = str_empty;
  3310. uint32_t span_id = 0, to = 0, max = 0, dial_timeout_int = 0, release_guard_time_ms_int = 0;
  3311. ftdm_span_t *span = NULL;
  3312. analog_option_t analog_options = ANALOG_OPTION_NONE;
  3313. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3314. char *var = (char *) switch_xml_attr_soft(param, "name");
  3315. char *val = (char *) switch_xml_attr_soft(param, "value");
  3316. if (!strcasecmp(var, "tonegroup")) {
  3317. tonegroup = val;
  3318. } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
  3319. digit_timeout = val;
  3320. } else if (!strcasecmp(var, "dial-timeout")) {
  3321. dial_timeout = val;
  3322. } else if (!strcasecmp(var, "release-guard-time-ms")) {
  3323. release_guard_time_ms = val;
  3324. } else if (!strcasecmp(var, "context")) {
  3325. context = val;
  3326. } else if (!strcasecmp(var, "dialplan")) {
  3327. dialplan = val;
  3328. } else if (!strcasecmp(var, "dial-regex")) {
  3329. dial_regex = val;
  3330. } else if (!strcasecmp(var, "fail-dial-regex")) {
  3331. fail_dial_regex = val;
  3332. } else if (!strcasecmp(var, "hold-music")) {
  3333. hold_music = val;
  3334. } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) {
  3335. max_digits = val;
  3336. } else if (!strcasecmp(var, "answer-supervision")) {
  3337. answer_supervision = val;
  3338. } else if (!strcasecmp(var, "immediate-ringback")) {
  3339. immediate_ringback = val;
  3340. } else if (!strcasecmp(var, "ringback-file")) {
  3341. ringback_file = val;
  3342. } else if (!strcasecmp(var, "enable-analog-option")) {
  3343. analog_options = enable_analog_option(val, analog_options);
  3344. }
  3345. }
  3346. if (!id && !name) {
  3347. LOAD_ERROR("span missing required param 'id'\n");
  3348. continue;
  3349. }
  3350. if (!tonegroup) {
  3351. tonegroup = "us";
  3352. }
  3353. if (digit_timeout) {
  3354. to = atoi(digit_timeout);
  3355. }
  3356. if (dial_timeout) {
  3357. dial_timeout_int = atoi(dial_timeout);
  3358. }
  3359. if (release_guard_time_ms) {
  3360. release_guard_time_ms_int = atoi(release_guard_time_ms);
  3361. }
  3362. if (max_digits) {
  3363. max = atoi(max_digits);
  3364. }
  3365. if (name) {
  3366. zstatus = ftdm_span_find_by_name(name, &span);
  3367. } else {
  3368. if (switch_is_number(id)) {
  3369. span_id = atoi(id);
  3370. zstatus = ftdm_span_find(span_id, &span);
  3371. }
  3372. if (zstatus != FTDM_SUCCESS) {
  3373. zstatus = ftdm_span_find_by_name(id, &span);
  3374. }
  3375. }
  3376. if (zstatus != FTDM_SUCCESS) {
  3377. LOAD_ERROR("Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
  3378. continue;
  3379. }
  3380. if (!span_id) {
  3381. span_id = ftdm_span_get_id(span);
  3382. }
  3383. if (ftdm_configure_span(span, "analog_em", on_analog_signal,
  3384. "tonemap", tonegroup,
  3385. "answer_supervision", answer_supervision,
  3386. "immediate_ringback", immediate_ringback,
  3387. "ringback_file", ringback_file,
  3388. "digit_timeout", &to,
  3389. "dial_timeout", &dial_timeout_int,
  3390. "release_guard_time_ms", &release_guard_time_ms_int,
  3391. "max_dialstr", &max,
  3392. FTDM_TAG_END) != FTDM_SUCCESS) {
  3393. LOAD_ERROR("Error starting FreeTDM span %d\n", span_id);
  3394. continue;
  3395. }
  3396. SPAN_CONFIG[span_id].span = span;
  3397. switch_set_string(SPAN_CONFIG[span_id].context, context);
  3398. switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
  3399. SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
  3400. if (dial_regex) {
  3401. switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
  3402. }
  3403. if (fail_dial_regex) {
  3404. switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
  3405. }
  3406. if (hold_music) {
  3407. switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music);
  3408. }
  3409. switch_copy_string(SPAN_CONFIG[span_id].type, "analog_em", sizeof(SPAN_CONFIG[span_id].type));
  3410. ftdm_span_start(span);
  3411. }
  3412. }
  3413. if ((spans = switch_xml_child(cfg, "pri_spans"))) {
  3414. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3415. char *name = (char *) switch_xml_attr(myspan, "name");
  3416. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  3417. ftdm_status_t zstatus = FTDM_FAIL;
  3418. const char *context = "default";
  3419. const char *dialplan = "XML";
  3420. unsigned paramindex = 0;
  3421. ftdm_span_t *span = NULL;
  3422. uint32_t span_id = 0;
  3423. if (!name) {
  3424. LOAD_ERROR("span missing required attribute 'name'\n");
  3425. continue;
  3426. }
  3427. memset(spanparameters, 0, sizeof(spanparameters));
  3428. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3429. char *var = (char *) switch_xml_attr_soft(param, "name");
  3430. char *val = (char *) switch_xml_attr_soft(param, "value");
  3431. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  3432. LOAD_ERROR("Too many parameters for pri span '%s', ignoring everything after '%s'\n", name, var);
  3433. break;
  3434. }
  3435. if (ftdm_strlen_zero(var) || ftdm_strlen_zero(val)) {
  3436. ftdm_log(FTDM_LOG_WARNING, "Skipping parameter with empty name or value\n");
  3437. continue;
  3438. }
  3439. if (!strcasecmp(var, "context")) {
  3440. context = val;
  3441. } else if (!strcasecmp(var, "dialplan")) {
  3442. dialplan = val;
  3443. } else {
  3444. spanparameters[paramindex].var = var;
  3445. spanparameters[paramindex].val = val;
  3446. paramindex++;
  3447. }
  3448. }
  3449. zstatus = ftdm_span_find_by_name(name, &span);
  3450. if (zstatus != FTDM_SUCCESS) {
  3451. LOAD_ERROR("Error finding FreeTDM span %s\n", name);
  3452. continue;
  3453. }
  3454. span_id = ftdm_span_get_id(span);
  3455. if (ftdm_configure_span_signaling(span, "isdn", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
  3456. LOAD_ERROR("Error configuring FreeTDM span %s\n", name);
  3457. continue;
  3458. }
  3459. SPAN_CONFIG[span_id].span = span;
  3460. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  3461. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  3462. switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
  3463. ftdm_span_start(span);
  3464. }
  3465. }
  3466. if ((spans = switch_xml_child(cfg, "pritap_spans"))) {
  3467. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3468. char *name = (char *) switch_xml_attr(myspan, "name");
  3469. ftdm_status_t zstatus = FTDM_FAIL;
  3470. unsigned paramindex = 0;
  3471. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  3472. const char *context = "default";
  3473. const char *dialplan = "XML";
  3474. ftdm_span_t *span = NULL;
  3475. int span_id = 0;
  3476. if (!name) {
  3477. LOAD_ERROR("span missing required attribute 'name'\n");
  3478. continue;
  3479. }
  3480. memset(spanparameters, 0, sizeof(spanparameters));
  3481. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3482. char *var = (char *) switch_xml_attr_soft(param, "name");
  3483. char *val = (char *) switch_xml_attr_soft(param, "value");
  3484. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  3485. LOAD_ERROR("Too many parameters for pritap span '%s', ignoring everything after '%s'\n", name, var);
  3486. break;
  3487. }
  3488. if (!strcasecmp(var, "context")) {
  3489. context = val;
  3490. } else if (!strcasecmp(var, "dialplan")) {
  3491. dialplan = val;
  3492. } else {
  3493. spanparameters[paramindex].var = var;
  3494. spanparameters[paramindex].val = val;
  3495. paramindex++;
  3496. }
  3497. }
  3498. zstatus = ftdm_span_find_by_name(name, &span);
  3499. if (zstatus != FTDM_SUCCESS) {
  3500. LOAD_ERROR("Error finding FreeTDM span %s\n", name);
  3501. continue;
  3502. }
  3503. span_id = ftdm_span_get_id(span);
  3504. if (ftdm_configure_span_signaling(span, "pritap", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
  3505. LOAD_ERROR("Error configuring FreeTDM span %s\n", name);
  3506. continue;
  3507. }
  3508. SPAN_CONFIG[span_id].span = span;
  3509. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  3510. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  3511. switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
  3512. ftdm_span_start(span);
  3513. }
  3514. }
  3515. if ((spans = switch_xml_child(cfg, "libpri_spans"))) {
  3516. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3517. char *name = (char *) switch_xml_attr(myspan, "name");
  3518. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  3519. ftdm_status_t zstatus = FTDM_FAIL;
  3520. const char *context = "default";
  3521. const char *dialplan = "XML";
  3522. unsigned paramindex = 0;
  3523. ftdm_span_t *span = NULL;
  3524. uint32_t span_id = 0;
  3525. if (!name) {
  3526. LOAD_ERROR("span missing required attribute 'name'\n");
  3527. continue;
  3528. }
  3529. memset(spanparameters, 0, sizeof(spanparameters));
  3530. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3531. char *var = (char *) switch_xml_attr_soft(param, "name");
  3532. char *val = (char *) switch_xml_attr_soft(param, "value");
  3533. if (ftdm_array_len(spanparameters) - 1 == paramindex) {
  3534. LOAD_ERROR("Too many parameters for libpri span, ignoring everything after '%s'\n", var);
  3535. break;
  3536. }
  3537. if (ftdm_strlen_zero(var) || ftdm_strlen_zero(val)) {
  3538. ftdm_log(FTDM_LOG_WARNING, "Skipping parameter with empty name or value\n");
  3539. continue;
  3540. }
  3541. if (!strcasecmp(var, "context")) {
  3542. context = val;
  3543. } else if (!strcasecmp(var, "dialplan")) {
  3544. dialplan = val;
  3545. } else {
  3546. spanparameters[paramindex].var = var;
  3547. spanparameters[paramindex].val = val;
  3548. paramindex++;
  3549. }
  3550. }
  3551. zstatus = ftdm_span_find_by_name(name, &span);
  3552. if (zstatus != FTDM_SUCCESS) {
  3553. LOAD_ERROR("Error finding FreeTDM span %s\n", name);
  3554. continue;
  3555. }
  3556. span_id = ftdm_span_get_id(span);
  3557. if (ftdm_configure_span_signaling(span, "libpri", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
  3558. LOAD_ERROR("Error configuring FreeTDM span %s\n", name);
  3559. continue;
  3560. }
  3561. SPAN_CONFIG[span_id].span = span;
  3562. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  3563. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  3564. switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
  3565. ftdm_span_start(span);
  3566. }
  3567. }
  3568. if ((spans = switch_xml_child(cfg, "r2_spans"))) {
  3569. for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
  3570. char *name = (char *) switch_xml_attr(myspan, "name");
  3571. char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
  3572. ftdm_status_t zstatus = FTDM_FAIL;
  3573. /* common non r2 stuff */
  3574. const char *context = "default";
  3575. const char *dialplan = "XML";
  3576. char *dial_regex = NULL;
  3577. char *fail_dial_regex = NULL;
  3578. uint32_t span_id = 0;
  3579. ftdm_span_t *span = NULL;
  3580. ftdm_conf_parameter_t spanparameters[FTDM_MAX_SIG_PARAMETERS];
  3581. unsigned paramindex = 0;
  3582. if (!name) {
  3583. LOAD_ERROR("'name' attribute required for R2 spans!\n");
  3584. continue;
  3585. }
  3586. memset(spanparameters, 0, sizeof(spanparameters));
  3587. if (configname) {
  3588. paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
  3589. if (paramindex) {
  3590. ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
  3591. }
  3592. }
  3593. for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
  3594. char *var = (char *) switch_xml_attr_soft(param, "name");
  3595. char *val = (char *) switch_xml_attr_soft(param, "value");
  3596. /* string parameters */
  3597. if (!strcasecmp(var, "context")) {
  3598. context = val;
  3599. } else if (!strcasecmp(var, "dialplan")) {
  3600. dialplan = val;
  3601. } else if (!strcasecmp(var, "dial-regex")) {
  3602. dial_regex = val;
  3603. } else if (!strcasecmp(var, "fail-dial-regex")) {
  3604. fail_dial_regex = val;
  3605. } else {
  3606. spanparameters[paramindex].var = var;
  3607. spanparameters[paramindex].val = val;
  3608. paramindex++;
  3609. }
  3610. }
  3611. zstatus = ftdm_span_find_by_name(name, &span);
  3612. if (zstatus != FTDM_SUCCESS) {
  3613. LOAD_ERROR("Error finding FreeTDM R2 Span '%s'\n", name);
  3614. continue;
  3615. }
  3616. span_id = ftdm_span_get_id(span);
  3617. if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, spanparameters) != FTDM_SUCCESS) {
  3618. LOAD_ERROR("Error configuring FreeTDM R2 span %s, error: %s\n", name, ftdm_span_get_last_error(span));
  3619. continue;
  3620. }
  3621. if (dial_regex) {
  3622. switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
  3623. }
  3624. if (fail_dial_regex) {
  3625. switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
  3626. }
  3627. SPAN_CONFIG[span_id].span = span;
  3628. switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
  3629. switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
  3630. switch_copy_string(SPAN_CONFIG[span_id].type, "R2", sizeof(SPAN_CONFIG[span_id].type));
  3631. if (ftdm_span_start(span) == FTDM_FAIL) {
  3632. LOAD_ERROR("Error starting FreeTDM R2 span %s, error: %s\n", name, ftdm_span_get_last_error(span));
  3633. continue;
  3634. }
  3635. }
  3636. }
  3637. if (globals.crash_on_assert) {
  3638. ftdm_log(FTDM_LOG_WARNING, "Crash on assert enabled\n");
  3639. ftdm_global_set_crash_policy(FTDM_CRASH_ON_ASSERT);
  3640. }
  3641. switch_xml_free(xml);
  3642. if (globals.fail_on_error && globals.config_error) {
  3643. ftdm_log(FTDM_LOG_ERROR, "Refusing to load module with errors\n");
  3644. return SWITCH_STATUS_TERM;
  3645. }
  3646. return SWITCH_STATUS_SUCCESS;
  3647. }
  3648. void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream)
  3649. {
  3650. uint32_t span_id;
  3651. uint32_t phspan_id, phchan_id;
  3652. const char *chan_type;
  3653. const char *state;
  3654. const char *last_state;
  3655. const char *uuid = NULL;
  3656. char sessionid[255];
  3657. float txgain, rxgain;
  3658. switch_core_session_t *session = NULL;
  3659. ftdm_alarm_flag_t alarmflag;
  3660. ftdm_caller_data_t *caller_data;
  3661. ftdm_channel_t *ftdmchan;
  3662. ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
  3663. if (chan_id > ftdm_span_get_chan_count(span)) {
  3664. return;
  3665. }
  3666. strcpy(sessionid, "(none)");
  3667. ftdmchan = ftdm_span_get_channel(span, chan_id);
  3668. span_id = ftdm_span_get_id(span);
  3669. phspan_id = ftdm_channel_get_ph_span_id(ftdmchan);
  3670. phchan_id = ftdm_channel_get_ph_id(ftdmchan);
  3671. chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan));
  3672. state = ftdm_channel_get_state_str(ftdmchan);
  3673. last_state = ftdm_channel_get_last_state_str(ftdmchan);
  3674. ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain);
  3675. ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain);
  3676. caller_data = ftdm_channel_get_caller_data(ftdmchan);
  3677. ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
  3678. ftdm_channel_get_alarms(ftdmchan, &alarmflag);
  3679. uuid = ftdm_channel_get_uuid(ftdmchan, 0);
  3680. if (!zstr(uuid)) {
  3681. if (!(session = switch_core_session_locate(uuid))) {
  3682. snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid);
  3683. } else {
  3684. snprintf(sessionid, sizeof(sessionid), "%s", uuid);
  3685. switch_core_session_rwunlock(session);
  3686. }
  3687. }
  3688. stream->write_function(stream,
  3689. "span_id: %u\n"
  3690. "chan_id: %u\n"
  3691. "physical_span_id: %u\n"
  3692. "physical_chan_id: %u\n"
  3693. "physical_status: %s\n"
  3694. "physical_status_red: %d\n"
  3695. "physical_status_yellow: %d\n"
  3696. "physical_status_rai: %d\n"
  3697. "physical_status_blue: %d\n"
  3698. "physical_status_ais: %d\n"
  3699. "physical_status_general: %d\n"
  3700. "signaling_status: %s\n"
  3701. "type: %s\n"
  3702. "state: %s\n"
  3703. "last_state: %s\n"
  3704. "txgain: %3.2f\n"
  3705. "rxgain: %3.2f\n"
  3706. "cid_date: %s\n"
  3707. "cid_name: %s\n"
  3708. "cid_num: %s\n"
  3709. "ani: %s\n"
  3710. "aniII: %s\n"
  3711. "dnis: %s\n"
  3712. "rdnis: %s\n"
  3713. "cause: %s\n"
  3714. "session: %s\n\n",
  3715. span_id,
  3716. chan_id,
  3717. phspan_id,
  3718. phchan_id,
  3719. alarmflag ? "alarmed" : "ok",
  3720. (alarmflag & FTDM_ALARM_RED) ? 1 : 0,
  3721. (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0,
  3722. (alarmflag & FTDM_ALARM_RAI) ? 1 : 0,
  3723. (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0,
  3724. (alarmflag & FTDM_ALARM_AIS) ? 1 : 0,
  3725. (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0,
  3726. ftdm_signaling_status2str(sigstatus),
  3727. chan_type,
  3728. state,
  3729. last_state,
  3730. txgain,
  3731. rxgain,
  3732. caller_data->cid_date,
  3733. caller_data->cid_name,
  3734. caller_data->cid_num.digits,
  3735. caller_data->ani.digits,
  3736. caller_data->aniII,
  3737. caller_data->dnis.digits,
  3738. caller_data->rdnis.digits,
  3739. switch_channel_cause2str(caller_data->hangup_cause),
  3740. sessionid);
  3741. }
  3742. void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream)
  3743. {
  3744. uint32_t span_id;
  3745. uint32_t phspan_id, phchan_id;
  3746. const char *chan_type;
  3747. const char *state;
  3748. const char *last_state;
  3749. float txgain, rxgain;
  3750. ftdm_caller_data_t *caller_data;
  3751. ftdm_channel_t *ftdmchan;
  3752. ftdm_alarm_flag_t alarmflag;
  3753. ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
  3754. if (chan_id > ftdm_span_get_chan_count(span)) {
  3755. return;
  3756. }
  3757. ftdmchan = ftdm_span_get_channel(span, chan_id);
  3758. span_id = ftdm_span_get_id(span);
  3759. phspan_id = ftdm_channel_get_ph_span_id(ftdmchan);
  3760. phchan_id = ftdm_channel_get_ph_id(ftdmchan);
  3761. chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan));
  3762. state = ftdm_channel_get_state_str(ftdmchan);
  3763. last_state = ftdm_channel_get_last_state_str(ftdmchan);
  3764. ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain);
  3765. ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain);
  3766. caller_data = ftdm_channel_get_caller_data(ftdmchan);
  3767. ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
  3768. ftdm_channel_get_alarms(ftdmchan, &alarmflag);
  3769. stream->write_function(stream,
  3770. " <channel>\n"
  3771. " <span-id>%u</span-id>\n"
  3772. " <chan-id>%u</chan-id>>\n"
  3773. " <physical-span-id>%u</physical-span-id>\n"
  3774. " <physical-chan-id>%u</physical-chan-id>\n"
  3775. " <physical-status>%s</physical-status>\n"
  3776. " <physical-status-red>%d</physical-status-red>\n"
  3777. " <physical-status-yellow>%d</physical-status-yellow>\n"
  3778. " <physical-status-rai>%d</physical-status-rai>\n"
  3779. " <physical-status-blue>%d</physical-status-blue>\n"
  3780. " <physical-status-ais>%d</physical-status-ais>\n"
  3781. " <physical-status-general>%d</physical-status-general>\n"
  3782. " <signaling-status>%s</signaling-status>\n"
  3783. " <type>%s</type>\n"
  3784. " <state>%s</state>\n"
  3785. " <last-state>%s</last-state>\n"
  3786. " <txgain>%3.2f</txgain>\n"
  3787. " <rxgain>%3.2f</rxgain>\n"
  3788. " <cid-date>%s</cid-date>\n"
  3789. " <cid-name>%s</cid-name>\n"
  3790. " <cid-num>%s</cid-num>\n"
  3791. " <ani>%s</ani>\n"
  3792. " <aniII>%s</aniII>\n"
  3793. " <dnis>%s</dnis>\n"
  3794. " <rdnis>%s</rdnis>\n"
  3795. " <cause>%s</cause>\n"
  3796. " </channel>\n",
  3797. span_id,
  3798. chan_id,
  3799. phspan_id,
  3800. phchan_id,
  3801. alarmflag ? "alarmed" : "ok",
  3802. (alarmflag & FTDM_ALARM_RED) ? 1 : 0,
  3803. (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0,
  3804. (alarmflag & FTDM_ALARM_RAI) ? 1 : 0,
  3805. (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0,
  3806. (alarmflag & FTDM_ALARM_AIS) ? 1 : 0,
  3807. (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0,
  3808. ftdm_signaling_status2str(sigstatus),
  3809. chan_type,
  3810. state,
  3811. last_state,
  3812. txgain,
  3813. rxgain,
  3814. caller_data->cid_date,
  3815. caller_data->cid_name,
  3816. caller_data->cid_num.digits,
  3817. caller_data->ani.digits,
  3818. caller_data->aniII,
  3819. caller_data->dnis.digits,
  3820. caller_data->rdnis.digits,
  3821. switch_channel_cause2str(caller_data->hangup_cause));
  3822. }
  3823. typedef struct ftdm_cli_entry ftdm_cli_entry_t;
  3824. typedef switch_status_t (*ftdm_cli_function_t)(ftdm_cli_entry_t *cli, const char *cmd, switch_core_session_t *session,
  3825. switch_stream_handle_t *stream, int argc, char *argv[]);
  3826. #define FTDM_CLI_DECLARE(name) static switch_status_t name(ftdm_cli_entry_t *cli, const char *cmd, \
  3827. switch_core_session_t *session, switch_stream_handle_t *stream, \
  3828. int argc, char *argv[])
  3829. static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli);
  3830. typedef struct cmd_ioread_data {
  3831. int num_times;
  3832. uint32_t interval;
  3833. ftdm_span_t *span;
  3834. ftdm_channel_t *fchan;
  3835. switch_memory_pool_t *pool;
  3836. int already_open;
  3837. } cmd_ioread_data_t;
  3838. static void *SWITCH_THREAD_FUNC ioread_thread(switch_thread_t *thread, void *obj)
  3839. {
  3840. ftdm_wait_flag_t wflags = FTDM_READ;
  3841. ftdm_status_t status = FTDM_FAIL;
  3842. unsigned char iobuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
  3843. cmd_ioread_data_t *data = obj;
  3844. int span_id = ftdm_span_get_id(data->span);
  3845. int chan_id = ftdm_channel_get_id(data->fchan);
  3846. ftdm_size_t len = ftdm_channel_get_io_packet_len(data->fchan);
  3847. ftdm_size_t origlen = len;
  3848. unsigned int pbuf[5];
  3849. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
  3850. "Started ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
  3851. data->num_times, data->interval, len, span_id, chan_id);
  3852. while (ftdm_running() && data->num_times > 0) {
  3853. data->num_times--;
  3854. wflags = FTDM_READ;
  3855. status = ftdm_channel_wait(data->fchan, &wflags, (data->interval * 10));
  3856. if (status == FTDM_FAIL) {
  3857. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to wait for IO in device %d:%d!\n", span_id, chan_id);
  3858. continue;
  3859. }
  3860. if (status == FTDM_TIMEOUT) {
  3861. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timed out while waiting I/O in device %d:%d!\n", span_id, chan_id);
  3862. continue;
  3863. }
  3864. len = origlen;
  3865. if (ftdm_channel_read(data->fchan, iobuf, &len) != FTDM_SUCCESS) {
  3866. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from device %d:%d!\n", span_id, chan_id);
  3867. continue;
  3868. }
  3869. pbuf[0] = iobuf[0];
  3870. pbuf[1] = iobuf[1];
  3871. pbuf[2] = iobuf[2];
  3872. pbuf[3] = iobuf[3];
  3873. pbuf[4] = iobuf[4];
  3874. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read 0x%1X 0x%1X 0x%1X 0x%1X 0x%1X\n",
  3875. pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4]);
  3876. }
  3877. if (!data->already_open) {
  3878. ftdm_channel_close(&data->fchan);
  3879. }
  3880. switch_core_destroy_memory_pool(&data->pool);
  3881. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
  3882. "Done ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
  3883. data->num_times, data->interval, origlen, span_id, chan_id);
  3884. return NULL;
  3885. }
  3886. FTDM_CLI_DECLARE(ftdm_cmd_ioread)
  3887. {
  3888. char *span_name = NULL;
  3889. int channo = 0;
  3890. ftdm_status_t status = FTDM_SUCCESS;
  3891. switch_threadattr_t *attr = NULL;
  3892. switch_thread_t *thread = NULL;
  3893. cmd_ioread_data_t *thdata;
  3894. cmd_ioread_data_t data;
  3895. memset(&data, 0, sizeof(data));
  3896. data.num_times = 1;
  3897. if (argc < 3) {
  3898. print_usage(stream, cli);
  3899. goto end;
  3900. }
  3901. span_name = argv[1];
  3902. ftdm_span_find_by_name(span_name, &data.span);
  3903. if (!data.span) {
  3904. stream->write_function(stream, "-ERR span %s not found\n", span_name);
  3905. goto end;
  3906. }
  3907. channo = atoi(argv[2]);
  3908. status = ftdm_channel_open(ftdm_span_get_id(data.span), channo, &data.fchan);
  3909. if (!data.fchan || (status != FTDM_SUCCESS && status != FTDM_EBUSY)) {
  3910. stream->write_function(stream, "-ERR Failed to open channel %d in span %s\n", channo, span_name);
  3911. goto end;
  3912. }
  3913. if (status == FTDM_EBUSY) {
  3914. data.already_open = 1;
  3915. }
  3916. if (argc > 3) {
  3917. data.num_times = atoi(argv[3]);
  3918. if (data.num_times < 1) {
  3919. data.num_times = 1;
  3920. }
  3921. }
  3922. if (argc > 4) {
  3923. data.interval = atoi(argv[4]);
  3924. }
  3925. if (data.interval <= 0 || data.interval > 10000) {
  3926. data.interval = ftdm_channel_get_io_interval(data.fchan);
  3927. }
  3928. switch_core_new_memory_pool(&data.pool);
  3929. thdata = switch_core_alloc(data.pool, sizeof(data));
  3930. memcpy(thdata, &data, sizeof(*thdata));
  3931. switch_threadattr_create(&attr, data.pool);
  3932. switch_threadattr_detach_set(attr, 1);
  3933. switch_threadattr_stacksize_set(attr, SWITCH_THREAD_STACKSIZE);
  3934. switch_thread_create(&thread, attr, ioread_thread, thdata, data.pool);
  3935. end:
  3936. return SWITCH_STATUS_SUCCESS;
  3937. }
  3938. FTDM_CLI_DECLARE(ftdm_cmd_list)
  3939. {
  3940. int j;
  3941. for (j = 0 ; j < FTDM_MAX_SPANS_INTERFACE; j++) {
  3942. ftdm_channel_t *fchan;
  3943. ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
  3944. const char *flags = "none";
  3945. ftdm_signaling_status_t sigstatus;
  3946. if (!SPAN_CONFIG[j].span) {
  3947. continue;
  3948. }
  3949. if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_3WAY) {
  3950. flags = "3way";
  3951. } else if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_CALL_SWAP) {
  3952. flags = "call swap";
  3953. }
  3954. fchan = ftdm_span_get_channel(SPAN_CONFIG[j].span, 1);
  3955. ftdm_channel_get_alarms(fchan, &alarmbits);
  3956. if ((FTDM_SUCCESS == ftdm_span_get_sig_status(SPAN_CONFIG[j].span, &sigstatus))) {
  3957. stream->write_function(stream,
  3958. "+OK\n"
  3959. "span: %u (%s)\n"
  3960. "type: %s\n"
  3961. "physical_status: %s\n"
  3962. "signaling_status: %s\n"
  3963. "chan_count: %u\n"
  3964. "dialplan: %s\n"
  3965. "context: %s\n"
  3966. "dial_regex: %s\n"
  3967. "fail_dial_regex: %s\n"
  3968. "hold_music: %s\n"
  3969. "analog_options: %s\n",
  3970. j,
  3971. ftdm_span_get_name(SPAN_CONFIG[j].span),
  3972. SPAN_CONFIG[j].type,
  3973. alarmbits ? "alarmed" : "ok",
  3974. ftdm_signaling_status2str(sigstatus),
  3975. ftdm_span_get_chan_count(SPAN_CONFIG[j].span),
  3976. SPAN_CONFIG[j].dialplan,
  3977. SPAN_CONFIG[j].context,
  3978. SPAN_CONFIG[j].dial_regex,
  3979. SPAN_CONFIG[j].fail_dial_regex,
  3980. SPAN_CONFIG[j].hold_music,
  3981. flags
  3982. );
  3983. } else {
  3984. stream->write_function(stream,
  3985. "+OK\n"
  3986. "span: %u (%s)\n"
  3987. "type: %s\n"
  3988. "physical_status: %s\n"
  3989. "chan_count: %u\n"
  3990. "dialplan: %s\n"
  3991. "context: %s\n"
  3992. "dial_regex: %s\n"
  3993. "fail_dial_regex: %s\n"
  3994. "hold_music: %s\n"
  3995. "analog_options: %s\n",
  3996. j,
  3997. ftdm_span_get_name(SPAN_CONFIG[j].span),
  3998. SPAN_CONFIG[j].type,
  3999. alarmbits ? "alarmed" : "ok",
  4000. ftdm_span_get_chan_count(SPAN_CONFIG[j].span),
  4001. SPAN_CONFIG[j].dialplan,
  4002. SPAN_CONFIG[j].context,
  4003. SPAN_CONFIG[j].dial_regex,
  4004. SPAN_CONFIG[j].fail_dial_regex,
  4005. SPAN_CONFIG[j].hold_music,
  4006. flags);
  4007. }
  4008. }
  4009. return SWITCH_STATUS_SUCCESS;
  4010. }
  4011. FTDM_CLI_DECLARE(ftdm_cmd_start_stop)
  4012. {
  4013. char *span_name = argv[1];
  4014. ftdm_span_t *span = NULL;
  4015. ftdm_status_t status;
  4016. if (argc < 2) {
  4017. print_usage(stream, cli);
  4018. goto end;
  4019. }
  4020. ftdm_span_find_by_name(span_name, &span);
  4021. if (!span) {
  4022. stream->write_function(stream, "-ERR span %s not found\n", span_name);
  4023. goto end;
  4024. }
  4025. if (!strcasecmp(argv[0], "stop")) {
  4026. status = ftdm_span_stop(span);
  4027. } else {
  4028. status = ftdm_span_start(span);
  4029. }
  4030. stream->write_function(stream, status == FTDM_SUCCESS ? "+OK\n" : "-ERR failure\n");
  4031. end:
  4032. return SWITCH_STATUS_SUCCESS;
  4033. }
  4034. FTDM_CLI_DECLARE(ftdm_cmd_reset)
  4035. {
  4036. uint32_t chan_id = 0;
  4037. uint32_t ccount = 0;
  4038. ftdm_channel_t *chan;
  4039. ftdm_span_t *span = NULL;
  4040. if (argc < 2) {
  4041. print_usage(stream, cli);
  4042. goto end;
  4043. }
  4044. ftdm_span_find_by_name(argv[1], &span);
  4045. if (!span) {
  4046. stream->write_function(stream, "-ERR span %s not found\n", argv[1]);
  4047. goto end;
  4048. }
  4049. if (argc > 2) {
  4050. chan_id = atoi(argv[2]);
  4051. if (chan_id > ftdm_span_get_chan_count(span)) {
  4052. stream->write_function(stream, "-ERR invalid channel %d\n", chan_id);
  4053. goto end;
  4054. }
  4055. }
  4056. if (chan_id) {
  4057. chan = ftdm_span_get_channel(span, chan_id);
  4058. if (!chan) {
  4059. stream->write_function(stream, "-ERR Could not find channel %d\n", chan_id);
  4060. goto end;
  4061. }
  4062. stream->write_function(stream, "Resetting channel %s:%s\n", argv[1], argv[2]);
  4063. ftdm_channel_reset(chan);
  4064. } else {
  4065. uint32_t i = 0;
  4066. ccount = ftdm_span_get_chan_count(span);
  4067. for (i = 1; i < ccount; i++) {
  4068. chan = ftdm_span_get_channel(span, i);
  4069. stream->write_function(stream, "Resetting channel %s:%d\n", argv[1], i);
  4070. ftdm_channel_reset(chan);
  4071. }
  4072. }
  4073. end:
  4074. return SWITCH_STATUS_SUCCESS;
  4075. }
  4076. FTDM_CLI_DECLARE(ftdm_cmd_dump)
  4077. {
  4078. ftdm_iterator_t *chaniter = NULL;
  4079. ftdm_iterator_t *curr = NULL;
  4080. uint32_t chan_id = 0;
  4081. ftdm_span_t *span;
  4082. char *as = NULL;
  4083. if (argc < 2) {
  4084. print_usage(stream, cli);
  4085. goto end;
  4086. }
  4087. ftdm_span_find_by_name(argv[1], &span);
  4088. if (argc > 2) {
  4089. if (argv[3] && !strcasecmp(argv[2], "as")) {
  4090. as = argv[3];
  4091. } else {
  4092. chan_id = atoi(argv[2]);
  4093. }
  4094. }
  4095. if (argv[4] && !strcasecmp(argv[3], "as")) {
  4096. as = argv[4];
  4097. }
  4098. if (!zstr(as) && !strcasecmp(as, "xml")) {
  4099. stream->write_function(stream, "<channels>\n");
  4100. if (!span) {
  4101. stream->write_function(stream, "<error>invalid span</error>\n");
  4102. } else {
  4103. if (chan_id) {
  4104. if (chan_id > ftdm_span_get_chan_count(span)) {
  4105. stream->write_function(stream, "<error>invalid channel</error>\n");
  4106. } else {
  4107. dump_chan_xml(span, chan_id, stream);
  4108. }
  4109. } else {
  4110. chaniter = ftdm_span_get_chan_iterator(span, NULL);
  4111. for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
  4112. dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
  4113. }
  4114. ftdm_iterator_free(chaniter);
  4115. }
  4116. }
  4117. stream->write_function(stream, "</channels>\n");
  4118. } else {
  4119. if (!span) {
  4120. stream->write_function(stream, "-ERR invalid span\n");
  4121. } else {
  4122. if (chan_id) {
  4123. if (chan_id > ftdm_span_get_chan_count(span)) {
  4124. stream->write_function(stream, "-ERR invalid channel\n");
  4125. } else {
  4126. char *dbgstr = NULL;
  4127. ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
  4128. dump_chan(span, chan_id, stream);
  4129. dbgstr = ftdm_channel_get_history_str(fchan);
  4130. stream->write_function(stream, "%s\n", dbgstr);
  4131. ftdm_free(dbgstr);
  4132. }
  4133. } else {
  4134. stream->write_function(stream, "+OK\n");
  4135. chaniter = ftdm_span_get_chan_iterator(span, NULL);
  4136. for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
  4137. dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
  4138. }
  4139. ftdm_iterator_free(chaniter);
  4140. }
  4141. }
  4142. }
  4143. end:
  4144. return SWITCH_STATUS_SUCCESS;
  4145. }
  4146. FTDM_CLI_DECLARE(ftdm_cmd_alarms)
  4147. {
  4148. ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
  4149. uint32_t chan_id = 0;
  4150. ftdm_span_t *span;
  4151. if (argc < 3) {
  4152. print_usage(stream, cli);
  4153. goto end;
  4154. }
  4155. ftdm_span_find_by_name(argv[1], &span);
  4156. chan_id = atoi(argv[2]);
  4157. if (!span) {
  4158. stream->write_function(stream, "-ERR invalid span\n");
  4159. } else if (chan_id) {
  4160. if (chan_id > ftdm_span_get_chan_count(span)) {
  4161. stream->write_function(stream, "-ERR invalid channel\n");
  4162. } else {
  4163. ftdm_channel_t *chan = ftdm_span_get_channel(span, chan_id);
  4164. if (!chan) {
  4165. stream->write_function(stream, "-ERR channel not configured\n");
  4166. } else {
  4167. ftdm_channel_get_alarms(chan, &alarmbits);
  4168. if (!strlen(ftdm_channel_get_last_error(chan))) {
  4169. stream->write_function(stream, "+OK No alarms\n");
  4170. } else {
  4171. stream->write_function(stream, "-ERR %s on %s:%d\n", ftdm_channel_get_last_error(chan), argv[1], chan);
  4172. }
  4173. }
  4174. }
  4175. }
  4176. end:
  4177. return SWITCH_STATUS_SUCCESS;
  4178. }
  4179. FTDM_CLI_DECLARE(ftdm_cmd_sigstatus)
  4180. {
  4181. ftdm_span_t *span = NULL;
  4182. ftdm_signaling_status_t sigstatus;
  4183. if (argc < 3) {
  4184. print_usage(stream, cli);
  4185. goto end;
  4186. }
  4187. if (!strcasecmp(argv[1], "get") && argc < 3) {
  4188. print_usage(stream, cli);
  4189. goto end;
  4190. }
  4191. if (!strcasecmp(argv[1], "set") && argc != 5) {
  4192. print_usage(stream, cli);
  4193. goto end;
  4194. }
  4195. ftdm_span_find_by_name(argv[2], &span);
  4196. if (!span) {
  4197. stream->write_function(stream, "-ERR invalid span %s\n", argv[2]);
  4198. goto end;
  4199. }
  4200. if (!strcasecmp(argv[1], "get")) {
  4201. if (argc == 4) {
  4202. uint32_t chan_id = atol(argv[3]);
  4203. ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
  4204. if (!fchan) {
  4205. stream->write_function(stream, "-ERR invalid channel id '%d'\n", chan_id);
  4206. goto end;
  4207. }
  4208. if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) {
  4209. stream->write_function(stream, "Channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus));
  4210. } else {
  4211. stream->write_function(stream, "-ERR failed to get channel signaling status\n");
  4212. }
  4213. goto end;
  4214. } else {
  4215. if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) {
  4216. stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus));
  4217. } else {
  4218. stream->write_function(stream, "-ERR failed to read span signaling status: %s\n", ftdm_span_get_last_error(span));
  4219. }
  4220. }
  4221. goto end;
  4222. }
  4223. if (!strcasecmp(argv[1], "set")) {
  4224. sigstatus = ftdm_str2ftdm_signaling_status(argv[4]);
  4225. if (!strcasecmp(argv[3], "all")) {
  4226. if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) {
  4227. stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n",
  4228. ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus));
  4229. } else {
  4230. stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
  4231. }
  4232. goto end;
  4233. } else {
  4234. uint32_t chan_id = atol(argv[3]);
  4235. ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
  4236. if (!fchan) {
  4237. stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id);
  4238. goto end;
  4239. }
  4240. if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) {
  4241. stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id,
  4242. ftdm_signaling_status2str(sigstatus));
  4243. } else {
  4244. stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus));
  4245. }
  4246. goto end;
  4247. }
  4248. }
  4249. end:
  4250. return SWITCH_STATUS_SUCCESS;
  4251. }
  4252. FTDM_CLI_DECLARE(ftdm_cmd_trace)
  4253. {
  4254. char tracepath[255];
  4255. unsigned i = 0;
  4256. uint32_t chan_id = 0;
  4257. uint32_t span_id = 0;
  4258. uint32_t chan_count = 0;
  4259. ftdm_status_t status;
  4260. ftdm_span_t *span = NULL;
  4261. ftdm_channel_t *chan = NULL;
  4262. if (argc < 3) {
  4263. print_usage(stream, cli);
  4264. goto end;
  4265. }
  4266. ftdm_span_find_by_name(argv[2], &span);
  4267. if (!span) {
  4268. stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
  4269. goto end;
  4270. }
  4271. chan_count = ftdm_span_get_chan_count(span);
  4272. if (argc > 3) {
  4273. chan_id = atoi(argv[3]);
  4274. if (chan_id > chan_count) {
  4275. stream->write_function(stream, "-ERR invalid channel\n");
  4276. goto end;
  4277. }
  4278. }
  4279. span_id = ftdm_span_get_id(span);
  4280. if (chan_id) {
  4281. chan = ftdm_span_get_channel(span, chan_id);
  4282. snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, chan_id);
  4283. status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath);
  4284. if (status != FTDM_SUCCESS) {
  4285. stream->write_function(stream, "-ERR failed to enable input trace at path %s\n", tracepath);
  4286. goto end;
  4287. }
  4288. snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, chan_id);
  4289. status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath);
  4290. if (status != FTDM_SUCCESS) {
  4291. stream->write_function(stream, "-ERR failed to enable output trace at path %s\n", tracepath);
  4292. ftdm_channel_command(chan, FTDM_COMMAND_TRACE_END_ALL, NULL);
  4293. goto end;
  4294. }
  4295. } else {
  4296. for (i = 1; i <= chan_count; i++) {
  4297. chan = ftdm_span_get_channel(span, i);
  4298. snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, i);
  4299. status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath);
  4300. if (status != FTDM_SUCCESS) {
  4301. stream->write_function(stream, "-ERR failed to enable input trace at path %s\n", tracepath);
  4302. goto end;
  4303. }
  4304. snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, i);
  4305. status = ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath);
  4306. if (status != FTDM_SUCCESS) {
  4307. stream->write_function(stream, "-ERR failed to enable output trace at path %s\n", tracepath);
  4308. ftdm_channel_command(chan, FTDM_COMMAND_TRACE_END_ALL, NULL);
  4309. goto end;
  4310. }
  4311. }
  4312. }
  4313. stream->write_function(stream, "+OK trace enabled with prefix path %s\n", argv[1]);
  4314. end:
  4315. return SWITCH_STATUS_SUCCESS;
  4316. }
  4317. FTDM_CLI_DECLARE(ftdm_cmd_notrace)
  4318. {
  4319. uint32_t i = 0;
  4320. uint32_t chan_id = 0;
  4321. uint32_t chan_count = 0;
  4322. ftdm_channel_t *fchan = NULL;
  4323. ftdm_span_t *span = NULL;
  4324. if (argc < 2) {
  4325. print_usage(stream, cli);
  4326. goto end;
  4327. }
  4328. ftdm_span_find_by_name(argv[1], &span);
  4329. if (!span) {
  4330. stream->write_function(stream, "-ERR failed to find span %s\n", argv[1]);
  4331. goto end;
  4332. }
  4333. chan_count = ftdm_span_get_chan_count(span);
  4334. if (argc > 2) {
  4335. chan_id = atoi(argv[2]);
  4336. if (chan_id > chan_count) {
  4337. stream->write_function(stream, "-ERR invalid channel\n");
  4338. goto end;
  4339. }
  4340. }
  4341. if (chan_id) {
  4342. fchan = ftdm_span_get_channel(span, chan_id);
  4343. ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL);
  4344. } else {
  4345. for (i = 1; i <= chan_count; i++) {
  4346. fchan = ftdm_span_get_channel(span, i);
  4347. ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL);
  4348. }
  4349. }
  4350. stream->write_function(stream, "+OK trace disabled\n");
  4351. end:
  4352. return SWITCH_STATUS_SUCCESS;
  4353. }
  4354. FTDM_CLI_DECLARE(ftdm_cmd_gains)
  4355. {
  4356. unsigned int i = 0;
  4357. float txgain = 0.0;
  4358. float rxgain = 0.0;
  4359. uint32_t chan_id = 0;
  4360. uint32_t ccount = 0;
  4361. ftdm_channel_t *chan;
  4362. ftdm_span_t *span = NULL;
  4363. if (argc < 4) {
  4364. print_usage(stream, cli);
  4365. goto end;
  4366. }
  4367. ftdm_span_find_by_name(argv[3], &span);
  4368. if (!span) {
  4369. stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]);
  4370. goto end;
  4371. }
  4372. if (argc > 4) {
  4373. chan_id = atoi(argv[4]);
  4374. if (chan_id > ftdm_span_get_chan_count(span)) {
  4375. stream->write_function(stream, "-ERR invalid channel\n");
  4376. goto end;
  4377. }
  4378. }
  4379. i = sscanf(argv[1], "%f", &rxgain);
  4380. i += sscanf(argv[2], "%f", &txgain);
  4381. if (i != 2) {
  4382. stream->write_function(stream, "-ERR invalid gains\n");
  4383. goto end;
  4384. }
  4385. if (chan_id) {
  4386. chan = ftdm_span_get_channel(span, chan_id);
  4387. ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain);
  4388. ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain);
  4389. } else {
  4390. ccount = ftdm_span_get_chan_count(span);
  4391. for (i = 1; i < ccount; i++) {
  4392. chan = ftdm_span_get_channel(span, i);
  4393. ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain);
  4394. ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain);
  4395. }
  4396. }
  4397. stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
  4398. end:
  4399. return SWITCH_STATUS_SUCCESS;
  4400. }
  4401. FTDM_CLI_DECLARE(ftdm_cmd_dtmf)
  4402. {
  4403. unsigned i = 0;
  4404. uint32_t chan_id = 0;
  4405. unsigned schan_count = 0;
  4406. ftdm_span_t *span = NULL;
  4407. ftdm_command_t fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT;
  4408. ftdm_channel_t *fchan;
  4409. if (argc < 3) {
  4410. print_usage(stream, cli);
  4411. goto end;
  4412. }
  4413. if (switch_true(argv[1])) {
  4414. fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT;
  4415. } else {
  4416. fcmd = FTDM_COMMAND_DISABLE_DTMF_DETECT;
  4417. }
  4418. ftdm_span_find_by_name(argv[2], &span);
  4419. if (!span) {
  4420. stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
  4421. goto end;
  4422. }
  4423. schan_count = ftdm_span_get_chan_count(span);
  4424. if (argc > 3) {
  4425. chan_id = atoi(argv[3]);
  4426. if (chan_id > schan_count) {
  4427. stream->write_function(stream, "-ERR invalid channel\n");
  4428. goto end;
  4429. }
  4430. }
  4431. if (chan_id) {
  4432. fchan = ftdm_span_get_channel(span, chan_id);
  4433. ftdm_channel_command(fchan, fcmd, NULL);
  4434. } else {
  4435. for (i = 1; i <= schan_count; i++) {
  4436. fchan = ftdm_span_get_channel(span, i);
  4437. ftdm_channel_command(fchan, fcmd, NULL);
  4438. }
  4439. }
  4440. stream->write_function(stream, "+OK DTMF detection was %s\n", fcmd == FTDM_COMMAND_ENABLE_DTMF_DETECT ? "enabled" : "disabled");
  4441. end:
  4442. return SWITCH_STATUS_SUCCESS;
  4443. }
  4444. FTDM_CLI_DECLARE(ftdm_cmd_queuesize)
  4445. {
  4446. unsigned int i = 0;
  4447. uint32_t rxsize = 10;
  4448. uint32_t txsize = 10;
  4449. uint32_t chan_id = 0;
  4450. uint32_t ccount = 0;
  4451. ftdm_channel_t *chan;
  4452. ftdm_span_t *span = NULL;
  4453. if (argc < 4) {
  4454. print_usage(stream, cli);
  4455. goto end;
  4456. }
  4457. ftdm_span_find_by_name(argv[3], &span);
  4458. if (!span) {
  4459. stream->write_function(stream, "-ERR failed to find span %s\n", argv[3]);
  4460. goto end;
  4461. }
  4462. if (argc > 4) {
  4463. chan_id = atoi(argv[4]);
  4464. if (chan_id > ftdm_span_get_chan_count(span)) {
  4465. stream->write_function(stream, "-ERR invalid channel\n");
  4466. goto end;
  4467. }
  4468. }
  4469. i = sscanf(argv[1], "%u", &rxsize);
  4470. i += sscanf(argv[2], "%u", &txsize);
  4471. if (i != 2) {
  4472. stream->write_function(stream, "-ERR invalid queue sizes provided\n");
  4473. goto end;
  4474. }
  4475. if (chan_id) {
  4476. chan = ftdm_span_get_channel(span, chan_id);
  4477. ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &rxsize);
  4478. ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txsize);
  4479. } else {
  4480. ccount = ftdm_span_get_chan_count(span);
  4481. for (i = 1; i < ccount; i++) {
  4482. chan = ftdm_span_get_channel(span, i);
  4483. ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &rxsize);
  4484. ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txsize);
  4485. }
  4486. }
  4487. stream->write_function(stream, "+OK queue sizes set to Rx %d and Tx %d\n", rxsize, txsize);
  4488. end:
  4489. return SWITCH_STATUS_SUCCESS;
  4490. }
  4491. static void exec_io_command(const char *cmd, switch_stream_handle_t *stream, ftdm_channel_t *fchan)
  4492. {
  4493. int enable = 0;
  4494. ftdm_channel_iostats_t stats;
  4495. if (!strcasecmp("enable", cmd)) {
  4496. enable = 1;
  4497. ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable);
  4498. } else if (!strcasecmp("disable", cmd)) {
  4499. enable = 0;
  4500. ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable);
  4501. } else if (!strcasecmp("flush", cmd)) {
  4502. ftdm_channel_command(fchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
  4503. } else {
  4504. ftdm_channel_command(fchan, FTDM_COMMAND_GET_IOSTATS, &stats);
  4505. stream->write_function(stream, "-- IO statistics for channel %d:%d --\n",
  4506. ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
  4507. stream->write_function(stream, "Rx errors: %u\n", stats.rx.errors);
  4508. stream->write_function(stream, "Rx queue size: %u\n", stats.rx.queue_size);
  4509. stream->write_function(stream, "Rx queue len: %u\n", stats.rx.queue_len);
  4510. stream->write_function(stream, "Rx count: %lu\n", stats.rx.packets);
  4511. stream->write_function(stream, "Tx errors: %u\n", stats.tx.errors);
  4512. stream->write_function(stream, "Tx queue size: %u\n", stats.tx.queue_size);
  4513. stream->write_function(stream, "Tx queue len: %u\n", stats.tx.queue_len);
  4514. stream->write_function(stream, "Tx count: %lu\n", stats.tx.packets);
  4515. stream->write_function(stream, "Tx idle: %u\n", stats.tx.idle_packets);
  4516. }
  4517. }
  4518. FTDM_CLI_DECLARE(ftdm_cmd_iostats)
  4519. {
  4520. uint32_t chan_id = 0;
  4521. ftdm_channel_t *chan;
  4522. ftdm_iterator_t *iter = NULL;
  4523. ftdm_iterator_t *curr = NULL;
  4524. ftdm_span_t *span = NULL;
  4525. if (argc < 3) {
  4526. print_usage(stream, cli);
  4527. goto end;
  4528. }
  4529. ftdm_span_find_by_name(argv[2], &span);
  4530. if (!span) {
  4531. stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
  4532. goto end;
  4533. }
  4534. if (argc > 3) {
  4535. chan_id = atoi(argv[3]);
  4536. if (chan_id > ftdm_span_get_chan_count(span)) {
  4537. stream->write_function(stream, "-ERR invalid channel\n");
  4538. goto end;
  4539. }
  4540. chan = ftdm_span_get_channel(span, chan_id);
  4541. exec_io_command(argv[1], stream, chan);
  4542. } else {
  4543. iter = ftdm_span_get_chan_iterator(span, NULL);
  4544. for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
  4545. chan = ftdm_iterator_current(curr);
  4546. exec_io_command(argv[1], stream, chan);
  4547. }
  4548. ftdm_iterator_free(iter);
  4549. }
  4550. stream->write_function(stream, "+OK\n");
  4551. end:
  4552. return SWITCH_STATUS_SUCCESS;
  4553. }
  4554. #define CASINTS(cas) ((cas) & (1 << 3)) ? 1 : 0, \
  4555. ((cas) & (1 << 2)) ? 1 : 0, \
  4556. ((cas) & (1 << 1)) ? 1 : 0, \
  4557. ((cas) & (1 << 0)) ? 1 : 0
  4558. FTDM_CLI_DECLARE(ftdm_cmd_cas)
  4559. {
  4560. uint32_t chan_id = 0;
  4561. switch_bool_t do_read = SWITCH_FALSE;
  4562. ftdm_channel_t *chan;
  4563. ftdm_iterator_t *iter = NULL;
  4564. ftdm_iterator_t *curr = NULL;
  4565. ftdm_span_t *span = NULL;
  4566. const char *write_bits_str = "";
  4567. int32_t abcd_bits = 0;
  4568. if (argc < 3) {
  4569. print_usage(stream, cli);
  4570. goto end;
  4571. }
  4572. if (!strcasecmp(argv[1], "read")) {
  4573. do_read = SWITCH_TRUE;
  4574. chan_id = argc > 3 ? atoi(argv[3]) : 0;
  4575. } else if (!strcasecmp(argv[1], "write") && argc >= 4) {
  4576. const char *str = NULL;
  4577. int mask = 0x08;
  4578. do_read = SWITCH_FALSE;
  4579. if (argc == 4) {
  4580. chan_id = 0;
  4581. write_bits_str = argv[3];
  4582. } else {
  4583. chan_id = atoi(argv[3]);
  4584. write_bits_str = argv[4];
  4585. }
  4586. if (strlen(write_bits_str) != 4) {
  4587. stream->write_function(stream, "-ERR Invalid CAS bits '%s'. CAS ABCD string must be composed of only four 1's and 0's (e.g. 1101)\n", write_bits_str);
  4588. goto end;
  4589. }
  4590. str = write_bits_str;
  4591. while (*str) {
  4592. if (*str == '1') {
  4593. abcd_bits |= mask;
  4594. } else if (*str != '0') {
  4595. stream->write_function(stream, "-ERR Invalid CAS bits '%s'. CAS ABCD string must be composed of only four 1's and 0's (e.g. 1101)\n", write_bits_str);
  4596. goto end;
  4597. }
  4598. str++;
  4599. mask = (mask >> 1);
  4600. }
  4601. } else {
  4602. print_usage(stream, cli);
  4603. goto end;
  4604. }
  4605. ftdm_span_find_by_name(argv[2], &span);
  4606. if (!span) {
  4607. stream->write_function(stream, "-ERR failed to find span %s\n", argv[2]);
  4608. goto end;
  4609. }
  4610. if (chan_id) {
  4611. if (chan_id > ftdm_span_get_chan_count(span)) {
  4612. stream->write_function(stream, "-ERR invalid channel\n");
  4613. goto end;
  4614. }
  4615. chan = ftdm_span_get_channel(span, chan_id);
  4616. if (do_read) {
  4617. ftdm_channel_command(chan, FTDM_COMMAND_GET_CAS_BITS, &abcd_bits);
  4618. stream->write_function(stream, "Read CAS bits from channel %d: %d%d%d%d (0x0%X)\n", chan_id, CASINTS(abcd_bits), abcd_bits);
  4619. } else {
  4620. stream->write_function(stream, "Writing 0x0%X to channel %d\n", abcd_bits, chan_id);
  4621. }
  4622. } else {
  4623. iter = ftdm_span_get_chan_iterator(span, NULL);
  4624. for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
  4625. chan = ftdm_iterator_current(curr);
  4626. //ftdm_channel_command();
  4627. chan_id = ftdm_channel_get_id(chan);
  4628. if (do_read) {
  4629. ftdm_channel_command(chan, FTDM_COMMAND_GET_CAS_BITS, &abcd_bits);
  4630. stream->write_function(stream, "Read CAS bits from channel %d: %d%d%d%d (0x0%X)\n", chan_id, CASINTS(abcd_bits), abcd_bits);
  4631. } else {
  4632. stream->write_function(stream, "Writing 0x0%X to channel %d\n", abcd_bits, chan_id);
  4633. }
  4634. }
  4635. ftdm_iterator_free(iter);
  4636. }
  4637. stream->write_function(stream, "+OK\n");
  4638. end:
  4639. return SWITCH_STATUS_SUCCESS;
  4640. }
  4641. SWITCH_STANDARD_API(ftdm_api_exec_usage)
  4642. {
  4643. char *mycmd = NULL, *argv[10] = { 0 };
  4644. int argc = 0;
  4645. uint32_t chan_id = 0;
  4646. ftdm_channel_t *chan = NULL;
  4647. ftdm_span_t *span = NULL;
  4648. uint32_t tokencnt = 0;
  4649. /*ftdm_cli_entry_t *entry = NULL;*/
  4650. if (!zstr(cmd) && (mycmd = strdup(cmd))) {
  4651. argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
  4652. }
  4653. if (!argc) {
  4654. stream->write_function(stream, "-ERR invalid args\n");
  4655. goto end;
  4656. }
  4657. if (argc < 2) {
  4658. stream->write_function(stream, "-ERR invalid args\n");
  4659. goto end;
  4660. }
  4661. ftdm_span_find_by_name(argv[0], &span);
  4662. chan_id = atoi(argv[1]);
  4663. if (!span) {
  4664. stream->write_function(stream, "-ERR invalid span\n");
  4665. goto end;
  4666. }
  4667. if (chan_id <= 0) {
  4668. stream->write_function(stream, "-ERR invalid channel\n");
  4669. goto end;
  4670. }
  4671. if (chan_id > ftdm_span_get_chan_count(span)) {
  4672. stream->write_function(stream, "-ERR invalid channel\n");
  4673. goto end;
  4674. }
  4675. chan = ftdm_span_get_channel(span, chan_id);
  4676. if (!chan) {
  4677. stream->write_function(stream, "-ERR channel not configured\n");
  4678. goto end;
  4679. }
  4680. tokencnt = ftdm_channel_get_token_count(chan);
  4681. stream->write_function(stream, "%d", tokencnt);
  4682. end:
  4683. switch_safe_free(mycmd);
  4684. return SWITCH_STATUS_SUCCESS;
  4685. }
  4686. struct ftdm_cli_entry {
  4687. const char *name;
  4688. const char *args;
  4689. const char *complete;
  4690. const char *desc;
  4691. ftdm_cli_function_t execute;
  4692. switch_api_function_t execute_api;
  4693. };
  4694. static ftdm_cli_entry_t ftdm_cli_options[] =
  4695. {
  4696. { "list", "", "", NULL, ftdm_cmd_list, NULL },
  4697. { "start", "<span_id|span_name>", "", NULL, ftdm_cmd_start_stop, NULL },
  4698. { "stop", "<span_id|span_name>", "", NULL, ftdm_cmd_start_stop, NULL },
  4699. { "reset", "<span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_reset, NULL },
  4700. { "alarms", "<span_id> <chan_id>", "", NULL, ftdm_cmd_alarms, NULL },
  4701. { "dump", "<span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_dump, NULL },
  4702. { "sigstatus", "get|set <span_id|span_name> [<chan_id>] [<sigstatus>]", "::[set:get", NULL, ftdm_cmd_sigstatus, NULL },
  4703. { "trace", "<path> <span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_trace, NULL },
  4704. { "notrace", "<span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_notrace, NULL },
  4705. { "gains", "<rxgain> <txgain> <span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_gains, NULL },
  4706. { "dtmf", "on|off <span_id|span_name> [<chan_id>]", "::[on:off", NULL, ftdm_cmd_dtmf, NULL },
  4707. { "queuesize", "<rxsize> <txsize> <span_id|span_name> [<chan_id>]", "", NULL, ftdm_cmd_queuesize, NULL },
  4708. { "iostats", "enable|disable|flush|print <span_id|span_name> <chan_id>", "::[enable:disable:flush:print", NULL, ftdm_cmd_iostats, NULL },
  4709. { "ioread", "<span_id|span_name> <chan_id> [num_times] [interval]", "", NULL, ftdm_cmd_ioread, NULL },
  4710. { "cas", "read|write <span_id|span_name> [<chan_id>] [<write_bits>]", "::[read:write", NULL, ftdm_cmd_cas, NULL },
  4711. /* Stand-alone commands (not part of the generic ftdm API */
  4712. { "ftdm_usage", "<span_id|span_name> <chan_id>", "", "Return channel call count", NULL, ftdm_api_exec_usage },
  4713. /* Fake handlers as they are handled within freetdm library,
  4714. * we should provide a way inside freetdm to query for completions from signaling modules */
  4715. { "core state", "[!]<state_name>", "", NULL, NULL, NULL },
  4716. { "core flag", "[!]<flag-int-value|flag-name> [<span_id|span_name>] [<chan_id>]", "", NULL, NULL, NULL },
  4717. { "core spanflag", "[!]<flag-int-value|flag-name> [<span_id|span_name>]", "", NULL, NULL, NULL },
  4718. { "core calls", "", "", NULL, NULL, NULL },
  4719. };
  4720. static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli)
  4721. {
  4722. stream->write_function(stream, "-ERR Usage: ftdm %s %s\n", cli->name, cli->args);
  4723. }
  4724. static void print_full_usage(switch_stream_handle_t *stream)
  4725. {
  4726. int i = 0;
  4727. ftdm_cli_entry_t *entry = NULL;
  4728. stream->write_function(stream, "USAGE:\n");
  4729. stream->write_function(stream, "--------------------------------------------------------------------------------\n");
  4730. for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) {
  4731. entry = &ftdm_cli_options[i];
  4732. if (entry->execute_api) {
  4733. continue;
  4734. }
  4735. stream->write_function(stream, "ftdm %s %s\n", entry->name, entry->args);
  4736. }
  4737. stream->write_function(stream, "--------------------------------------------------------------------------------\n");
  4738. }
  4739. SWITCH_STANDARD_API(ftdm_api_exec)
  4740. {
  4741. char *mycmd = NULL, *argv[10] = { 0 };
  4742. int argc = 0;
  4743. int i = 0;
  4744. ftdm_cli_entry_t *entry = NULL;
  4745. if (!zstr(cmd) && (mycmd = strdup(cmd))) {
  4746. argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
  4747. }
  4748. if (!argc) {
  4749. print_full_usage(stream);
  4750. goto end;
  4751. }
  4752. for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) {
  4753. entry = &ftdm_cli_options[i];
  4754. if (!strcasecmp(argv[0], entry->name) && entry->execute) {
  4755. entry->execute(entry, cmd, session, stream, argc, argv);
  4756. break;
  4757. }
  4758. }
  4759. /* if the command was not found in the main CLI entries, try to execute it as a FreeTDM API */
  4760. if (i == ftdm_array_len(ftdm_cli_options)) {
  4761. char *rply = ftdm_api_execute(cmd);
  4762. if (rply) {
  4763. stream->write_function(stream, "%s", rply);
  4764. ftdm_free(rply);
  4765. } else {
  4766. print_full_usage(stream);
  4767. }
  4768. }
  4769. end:
  4770. switch_safe_free(mycmd);
  4771. return SWITCH_STATUS_SUCCESS;
  4772. }
  4773. SWITCH_STANDARD_APP(enable_dtmf_function)
  4774. {
  4775. private_t *tech_pvt;
  4776. if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
  4777. ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
  4778. return;
  4779. }
  4780. tech_pvt = switch_core_session_get_private(session);
  4781. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  4782. switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
  4783. return;
  4784. }
  4785. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL);
  4786. ftdm_log(FTDM_LOG_INFO, "DTMF detection enabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan));
  4787. }
  4788. SWITCH_STANDARD_APP(disable_dtmf_function)
  4789. {
  4790. private_t *tech_pvt;
  4791. if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
  4792. ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
  4793. return;
  4794. }
  4795. tech_pvt = switch_core_session_get_private(session);
  4796. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  4797. switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
  4798. return;
  4799. }
  4800. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
  4801. ftdm_log(FTDM_LOG_INFO, "DTMF detection Disabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan));
  4802. }
  4803. SWITCH_STANDARD_APP(disable_ec_function)
  4804. {
  4805. private_t *tech_pvt;
  4806. int x = 0;
  4807. if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
  4808. ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
  4809. return;
  4810. }
  4811. tech_pvt = switch_core_session_get_private(session);
  4812. if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
  4813. switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
  4814. return;
  4815. }
  4816. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOCANCEL, &x);
  4817. ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOTRAIN, &x);
  4818. ftdm_log(FTDM_LOG_INFO, "Echo Canceller Disabled\n");
  4819. }
  4820. SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
  4821. {
  4822. int i = 0;
  4823. ftdm_cli_entry_t *entry = NULL;
  4824. switch_api_interface_t *commands_api_interface = NULL;
  4825. switch_application_interface_t *app_interface = NULL;
  4826. module_pool = pool;
  4827. ftdm_global_set_logger(ftdm_logger);
  4828. ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir);
  4829. ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir);
  4830. if (load_config_path() != SWITCH_STATUS_SUCCESS) {
  4831. ftdm_global_destroy();
  4832. return SWITCH_STATUS_TERM;
  4833. }
  4834. if (ftdm_global_init() != FTDM_SUCCESS) {
  4835. ftdm_global_destroy();
  4836. ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n");
  4837. return SWITCH_STATUS_TERM;
  4838. }
  4839. if (ftdm_global_configuration() != FTDM_SUCCESS) {
  4840. ftdm_global_destroy();
  4841. ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM\n");
  4842. return SWITCH_STATUS_TERM;
  4843. }
  4844. if (load_config() != SWITCH_STATUS_SUCCESS) {
  4845. ftdm_global_destroy();
  4846. return SWITCH_STATUS_TERM;
  4847. }
  4848. *module_interface = switch_loadable_module_create_module_interface(pool, modname);
  4849. freetdm_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
  4850. freetdm_endpoint_interface->interface_name = "freetdm";
  4851. freetdm_endpoint_interface->io_routines = &freetdm_io_routines;
  4852. freetdm_endpoint_interface->state_handler = &freetdm_state_handlers;
  4853. SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ftdm_api_exec, "<cmd> <args>");
  4854. for (i = 0 ; i < ftdm_array_len(ftdm_cli_options); i++) {
  4855. char complete_cli[512];
  4856. entry = &ftdm_cli_options[i];
  4857. if (entry->execute_api) {
  4858. /* This is a stand-alone API */
  4859. SWITCH_ADD_API(commands_api_interface, entry->name, entry->desc, ftdm_api_exec_usage, entry->args);
  4860. snprintf(complete_cli, sizeof(complete_cli), "add %s %s", entry->name, entry->complete);
  4861. switch_console_set_complete(complete_cli);
  4862. } else {
  4863. snprintf(complete_cli, sizeof(complete_cli), "add ftdm %s %s", entry->name, entry->complete);
  4864. switch_console_set_complete(complete_cli);
  4865. }
  4866. }
  4867. SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE);
  4868. SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE);
  4869. SWITCH_ADD_APP(app_interface, "enable_dtmf", "Enable DTMF Detection", "Enable DTMF Detection", enable_dtmf_function, "", SAF_NONE);
  4870. #if 0
  4871. ctdm_init(*module_interface);
  4872. #endif
  4873. /* indicate that the module should continue to be loaded */
  4874. return SWITCH_STATUS_SUCCESS;
  4875. }
  4876. SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown)
  4877. {
  4878. switch_hash_index_t *hi;
  4879. const void *var;
  4880. void *val;
  4881. /* destroy ss7 configs */
  4882. for (hi = switch_core_hash_first(globals.ss7_configs); hi; hi = switch_core_hash_next(&hi)) {
  4883. switch_core_hash_this(hi, &var, NULL, &val);
  4884. ftdm_conf_node_destroy(val);
  4885. }
  4886. switch_core_hash_destroy(&globals.ss7_configs);
  4887. ftdm_global_destroy();
  4888. // this breaks pika but they are MIA so *shrug*
  4889. //return SWITCH_STATUS_NOUNLOAD;
  4890. return SWITCH_STATUS_SUCCESS;
  4891. }
  4892. /* For Emacs:
  4893. * Local Variables:
  4894. * mode:c
  4895. * indent-tabs-mode:t
  4896. * tab-width:4
  4897. * c-basic-offset:4
  4898. * End:
  4899. * For VIM:
  4900. * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
  4901. */