chan_dahdi.c 598 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2008, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief DAHDI for Pseudo TDM
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. *
  24. * Connects to the DAHDI telephony library as well as
  25. * libpri. Libpri is optional and needed only if you are
  26. * going to use ISDN connections.
  27. *
  28. * You need to install libraries before you attempt to compile
  29. * and install the DAHDI channel.
  30. *
  31. * \ingroup channel_drivers
  32. *
  33. * \todo Deprecate the "musiconhold" configuration option post 1.4
  34. */
  35. /*! \li \ref chan_dahdi.c uses the configuration file \ref chan_dahdi.conf
  36. * \addtogroup configuration_file
  37. */
  38. /*! \page chan_dahdi.conf chan_dahdi.conf
  39. * \verbinclude chan_dahdi.conf.sample
  40. */
  41. /*** MODULEINFO
  42. <use type="module">res_smdi</use>
  43. <depend>dahdi</depend>
  44. <depend>tonezone</depend>
  45. <use type="external">pri</use>
  46. <use type="external">ss7</use>
  47. <use type="external">openr2</use>
  48. <support_level>core</support_level>
  49. ***/
  50. #include "asterisk.h"
  51. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  52. #if defined(__NetBSD__) || defined(__FreeBSD__)
  53. #include <pthread.h>
  54. #include <signal.h>
  55. #else
  56. #include <sys/signal.h>
  57. #endif
  58. #include <sys/stat.h>
  59. #include <math.h>
  60. #include "sig_analog.h"
  61. /* Analog signaling is currently still present in chan_dahdi for use with
  62. * radio. Sig_analog does not currently handle any radio operations. If
  63. * radio only uses analog signaling, then the radio handling logic could
  64. * be placed in sig_analog and the duplicated code could be removed.
  65. */
  66. #if defined(HAVE_PRI)
  67. #include "sig_pri.h"
  68. #ifndef PRI_RESTART
  69. #error "Upgrade your libpri"
  70. #endif
  71. #endif /* defined(HAVE_PRI) */
  72. #if defined(HAVE_SS7)
  73. #include "sig_ss7.h"
  74. #if !defined(LIBSS7_ABI_COMPATIBILITY)
  75. #error "Upgrade your libss7"
  76. #elif LIBSS7_ABI_COMPATIBILITY != 2
  77. #error "Your installed libss7 is not compatible"
  78. #endif
  79. #endif /* defined(HAVE_SS7) */
  80. #if defined(HAVE_OPENR2)
  81. /* put this here until sig_mfcr2 comes along */
  82. #define SIG_MFCR2_MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
  83. #endif /* defined(HAVE_OPENR2) */
  84. #include "asterisk/lock.h"
  85. #include "asterisk/channel.h"
  86. #include "asterisk/config.h"
  87. #include "asterisk/module.h"
  88. #include "asterisk/pbx.h"
  89. #include "asterisk/file.h"
  90. #include "asterisk/ulaw.h"
  91. #include "asterisk/alaw.h"
  92. #include "asterisk/callerid.h"
  93. #include "asterisk/adsi.h"
  94. #include "asterisk/cli.h"
  95. #include "asterisk/pickup.h"
  96. #include "asterisk/features.h"
  97. #include "asterisk/musiconhold.h"
  98. #include "asterisk/say.h"
  99. #include "asterisk/tdd.h"
  100. #include "asterisk/app.h"
  101. #include "asterisk/dsp.h"
  102. #include "asterisk/astdb.h"
  103. #include "asterisk/manager.h"
  104. #include "asterisk/causes.h"
  105. #include "asterisk/term.h"
  106. #include "asterisk/utils.h"
  107. #include "asterisk/transcap.h"
  108. #include "asterisk/stringfields.h"
  109. #include "asterisk/abstract_jb.h"
  110. #include "asterisk/smdi.h"
  111. #include "asterisk/devicestate.h"
  112. #include "asterisk/paths.h"
  113. #include "asterisk/ccss.h"
  114. #include "asterisk/data.h"
  115. #include "asterisk/features_config.h"
  116. #include "asterisk/bridge.h"
  117. #include "asterisk/stasis_channels.h"
  118. #include "asterisk/parking.h"
  119. #include "asterisk/format_cache.h"
  120. #include "chan_dahdi.h"
  121. #include "dahdi/bridge_native_dahdi.h"
  122. /*** DOCUMENTATION
  123. <application name="DAHDISendKeypadFacility" language="en_US">
  124. <synopsis>
  125. Send digits out of band over a PRI.
  126. </synopsis>
  127. <syntax>
  128. <parameter name="digits" required="true" />
  129. </syntax>
  130. <description>
  131. <para>This application will send the given string of digits in a Keypad
  132. Facility IE over the current channel.</para>
  133. </description>
  134. </application>
  135. <application name="DAHDISendCallreroutingFacility" language="en_US">
  136. <synopsis>
  137. Send an ISDN call rerouting/deflection facility message.
  138. </synopsis>
  139. <syntax argsep=",">
  140. <parameter name="destination" required="true">
  141. <para>Destination number.</para>
  142. </parameter>
  143. <parameter name="original">
  144. <para>Original called number.</para>
  145. </parameter>
  146. <parameter name="reason">
  147. <para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
  148. </parameter>
  149. </syntax>
  150. <description>
  151. <para>This application will send an ISDN switch specific call
  152. rerouting/deflection facility message over the current channel.
  153. Supported switches depend upon the version of libpri in use.</para>
  154. </description>
  155. </application>
  156. <application name="DAHDIAcceptR2Call" language="en_US">
  157. <synopsis>
  158. Accept an R2 call if its not already accepted (you still need to answer it)
  159. </synopsis>
  160. <syntax>
  161. <parameter name="charge" required="true">
  162. <para>Yes or No.</para>
  163. <para>Whether you want to accept the call with charge or without charge.</para>
  164. </parameter>
  165. </syntax>
  166. <description>
  167. <para>This application will Accept the R2 call either with charge or no charge.</para>
  168. </description>
  169. </application>
  170. <manager name="DAHDITransfer" language="en_US">
  171. <synopsis>
  172. Transfer DAHDI Channel.
  173. </synopsis>
  174. <syntax>
  175. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  176. <parameter name="DAHDIChannel" required="true">
  177. <para>DAHDI channel number to transfer.</para>
  178. </parameter>
  179. </syntax>
  180. <description>
  181. <para>Simulate a flash hook event by the user connected to the channel.</para>
  182. <note><para>Valid only for analog channels.</para></note>
  183. </description>
  184. </manager>
  185. <manager name="DAHDIHangup" language="en_US">
  186. <synopsis>
  187. Hangup DAHDI Channel.
  188. </synopsis>
  189. <syntax>
  190. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  191. <parameter name="DAHDIChannel" required="true">
  192. <para>DAHDI channel number to hangup.</para>
  193. </parameter>
  194. </syntax>
  195. <description>
  196. <para>Simulate an on-hook event by the user connected to the channel.</para>
  197. <note><para>Valid only for analog channels.</para></note>
  198. </description>
  199. </manager>
  200. <manager name="DAHDIDialOffhook" language="en_US">
  201. <synopsis>
  202. Dial over DAHDI channel while offhook.
  203. </synopsis>
  204. <syntax>
  205. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  206. <parameter name="DAHDIChannel" required="true">
  207. <para>DAHDI channel number to dial digits.</para>
  208. </parameter>
  209. <parameter name="Number" required="true">
  210. <para>Digits to dial.</para>
  211. </parameter>
  212. </syntax>
  213. <description>
  214. <para>Generate DTMF control frames to the bridged peer.</para>
  215. </description>
  216. </manager>
  217. <manager name="DAHDIDNDon" language="en_US">
  218. <synopsis>
  219. Toggle DAHDI channel Do Not Disturb status ON.
  220. </synopsis>
  221. <syntax>
  222. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  223. <parameter name="DAHDIChannel" required="true">
  224. <para>DAHDI channel number to set DND on.</para>
  225. </parameter>
  226. </syntax>
  227. <description>
  228. <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
  229. <note><para>Feature only supported by analog channels.</para></note>
  230. </description>
  231. </manager>
  232. <manager name="DAHDIDNDoff" language="en_US">
  233. <synopsis>
  234. Toggle DAHDI channel Do Not Disturb status OFF.
  235. </synopsis>
  236. <syntax>
  237. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  238. <parameter name="DAHDIChannel" required="true">
  239. <para>DAHDI channel number to set DND off.</para>
  240. </parameter>
  241. </syntax>
  242. <description>
  243. <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
  244. <note><para>Feature only supported by analog channels.</para></note>
  245. </description>
  246. </manager>
  247. <manager name="DAHDIShowChannels" language="en_US">
  248. <synopsis>
  249. Show status of DAHDI channels.
  250. </synopsis>
  251. <syntax>
  252. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  253. <parameter name="DAHDIChannel">
  254. <para>Specify the specific channel number to show. Show all channels if zero or not present.</para>
  255. </parameter>
  256. </syntax>
  257. <description>
  258. <para>Similar to the CLI command "dahdi show channels".</para>
  259. </description>
  260. </manager>
  261. <manager name="DAHDIRestart" language="en_US">
  262. <synopsis>
  263. Fully Restart DAHDI channels (terminates calls).
  264. </synopsis>
  265. <syntax>
  266. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  267. </syntax>
  268. <description>
  269. <para>Equivalent to the CLI command "dahdi restart".</para>
  270. </description>
  271. </manager>
  272. <manager name="PRIShowSpans" language="en_US">
  273. <synopsis>
  274. Show status of PRI spans.
  275. </synopsis>
  276. <syntax>
  277. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  278. <parameter name="Span">
  279. <para>Specify the specific span to show. Show all spans if zero or not present.</para>
  280. </parameter>
  281. </syntax>
  282. <description>
  283. <para>Similar to the CLI command "pri show spans".</para>
  284. </description>
  285. </manager>
  286. <manager name="PRIDebugSet" language="en_US">
  287. <synopsis>
  288. Set PRI debug levels for a span
  289. </synopsis>
  290. <syntax>
  291. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  292. <parameter name="Span" required="true">
  293. <para>Which span to affect.</para>
  294. </parameter>
  295. <parameter name="Level" required="true">
  296. <para>What debug level to set. May be a numerical value or a text value from the list below</para>
  297. <enumlist>
  298. <enum name="off" />
  299. <enum name="on" />
  300. <enum name="hex" />
  301. <enum name="intense" />
  302. </enumlist>
  303. </parameter>
  304. </syntax>
  305. <description>
  306. <para>Equivalent to the CLI command "pri set debug &lt;level&gt; span &lt;span&gt;".</para>
  307. </description>
  308. </manager>
  309. <manager name="PRIDebugFileSet" language="en_US">
  310. <synopsis>
  311. Set the file used for PRI debug message output
  312. </synopsis>
  313. <syntax>
  314. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  315. <parameter name="File" required="true">
  316. <para>Path of file to write debug output.</para>
  317. </parameter>
  318. </syntax>
  319. <description>
  320. <para>Equivalent to the CLI command "pri set debug file &lt;output-file&gt;"</para>
  321. </description>
  322. </manager>
  323. <manager name="PRIDebugFileUnset" language="en_US">
  324. <synopsis>
  325. Disables file output for PRI debug messages
  326. </synopsis>
  327. <syntax>
  328. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  329. </syntax>
  330. </manager>
  331. <managerEvent language="en_US" name="AlarmClear">
  332. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  333. <synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
  334. <syntax>
  335. <parameter name="DAHDIChannel">
  336. <para>The DAHDI channel on which the alarm was cleared.</para>
  337. <note><para>This is not an Asterisk channel identifier.</para></note>
  338. </parameter>
  339. </syntax>
  340. </managerEventInstance>
  341. </managerEvent>
  342. <managerEvent language="en_US" name="SpanAlarmClear">
  343. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  344. <synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
  345. <syntax>
  346. <parameter name="Span">
  347. <para>The span on which the alarm was cleared.</para>
  348. </parameter>
  349. </syntax>
  350. </managerEventInstance>
  351. </managerEvent>
  352. <managerEvent language="en_US" name="DNDState">
  353. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  354. <synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
  355. <syntax>
  356. <parameter name="DAHDIChannel">
  357. <para>The DAHDI channel on which DND status changed.</para>
  358. <note><para>This is not an Asterisk channel identifier.</para></note>
  359. </parameter>
  360. <parameter name="Status">
  361. <enumlist>
  362. <enum name="enabled"/>
  363. <enum name="disabled"/>
  364. </enumlist>
  365. </parameter>
  366. </syntax>
  367. </managerEventInstance>
  368. </managerEvent>
  369. <managerEvent language="en_US" name="Alarm">
  370. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  371. <synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
  372. <syntax>
  373. <parameter name="DAHDIChannel">
  374. <para>The channel on which the alarm occurred.</para>
  375. <note><para>This is not an Asterisk channel identifier.</para></note>
  376. </parameter>
  377. <parameter name="Alarm">
  378. <para>A textual description of the alarm that occurred.</para>
  379. </parameter>
  380. </syntax>
  381. </managerEventInstance>
  382. </managerEvent>
  383. <managerEvent language="en_US" name="SpanAlarm">
  384. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  385. <synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
  386. <syntax>
  387. <parameter name="Span">
  388. <para>The span on which the alarm occurred.</para>
  389. </parameter>
  390. <parameter name="Alarm">
  391. <para>A textual description of the alarm that occurred.</para>
  392. </parameter>
  393. </syntax>
  394. </managerEventInstance>
  395. </managerEvent>
  396. <managerEvent language="en_US" name="DAHDIChannel">
  397. <managerEventInstance class="EVENT_FLAG_CALL">
  398. <synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
  399. <syntax>
  400. <channel_snapshot/>
  401. <parameter name="DAHDISpan">
  402. <para>The DAHDI span associated with this channel.</para>
  403. </parameter>
  404. <parameter name="DAHDIChannel">
  405. <para>The DAHDI channel associated with this channel.</para>
  406. </parameter>
  407. </syntax>
  408. </managerEventInstance>
  409. </managerEvent>
  410. ***/
  411. #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
  412. static const char * const lbostr[] = {
  413. "0 db (CSU)/0-133 feet (DSX-1)",
  414. "133-266 feet (DSX-1)",
  415. "266-399 feet (DSX-1)",
  416. "399-533 feet (DSX-1)",
  417. "533-655 feet (DSX-1)",
  418. "-7.5db (CSU)",
  419. "-15db (CSU)",
  420. "-22.5db (CSU)"
  421. };
  422. /*! Global jitterbuffer configuration - by default, jb is disabled
  423. * \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
  424. static struct ast_jb_conf default_jbconf =
  425. {
  426. .flags = 0,
  427. .max_size = 200,
  428. .resync_threshold = 1000,
  429. .impl = "fixed",
  430. .target_extra = 40,
  431. };
  432. static struct ast_jb_conf global_jbconf;
  433. /*!
  434. * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
  435. * the user hangs up to reset the state machine so ring works properly.
  436. * This is used to be able to support kewlstart by putting the zhone in
  437. * groundstart mode since their forward disconnect supervision is entirely
  438. * broken even though their documentation says it isn't and their support
  439. * is entirely unwilling to provide any assistance with their channel banks
  440. * even though their web site says they support their products for life.
  441. */
  442. /* #define ZHONE_HACK */
  443. /*! \brief Typically, how many rings before we should send Caller*ID */
  444. #define DEFAULT_CIDRINGS 1
  445. #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
  446. /*! \brief Signaling types that need to use MF detection should be placed in this macro */
  447. #define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB))
  448. static const char tdesc[] = "DAHDI Telephony"
  449. #if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
  450. " w/"
  451. #if defined(HAVE_PRI)
  452. "PRI"
  453. #endif /* defined(HAVE_PRI) */
  454. #if defined(HAVE_SS7)
  455. #if defined(HAVE_PRI)
  456. " & "
  457. #endif /* defined(HAVE_PRI) */
  458. "SS7"
  459. #endif /* defined(HAVE_SS7) */
  460. #if defined(HAVE_OPENR2)
  461. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  462. " & "
  463. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  464. "MFC/R2"
  465. #endif /* defined(HAVE_OPENR2) */
  466. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
  467. ;
  468. static const char config[] = "chan_dahdi.conf";
  469. #ifdef LOTS_OF_SPANS
  470. #define NUM_SPANS DAHDI_MAX_SPANS
  471. #else
  472. #define NUM_SPANS 32
  473. #endif
  474. #define CHAN_PSEUDO -2
  475. #define CALLPROGRESS_PROGRESS 1
  476. #define CALLPROGRESS_FAX_OUTGOING 2
  477. #define CALLPROGRESS_FAX_INCOMING 4
  478. #define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
  479. #define NUM_CADENCE_MAX 25
  480. static int num_cadence = 4;
  481. static int user_has_defined_cadences = 0;
  482. static int has_pseudo;
  483. static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
  484. { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
  485. { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
  486. { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
  487. { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
  488. };
  489. /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
  490. * is 1, the second pause is 2 and so on.
  491. */
  492. static int cidrings[NUM_CADENCE_MAX] = {
  493. 2, /*!< Right after first long ring */
  494. 4, /*!< Right after long part */
  495. 3, /*!< After third chirp */
  496. 2, /*!< Second spell */
  497. };
  498. /* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
  499. static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
  500. #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
  501. (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
  502. #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
  503. #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
  504. static char defaultcic[64] = "";
  505. static char defaultozz[64] = "";
  506. /*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
  507. static char mwimonitornotify[PATH_MAX] = "";
  508. #ifndef HAVE_DAHDI_LINEREVERSE_VMWI
  509. static int mwisend_rpas = 0;
  510. #endif
  511. static char progzone[10] = "";
  512. static int usedistinctiveringdetection = 0;
  513. static int distinctiveringaftercid = 0;
  514. static int numbufs = 4;
  515. static int mwilevel = 512;
  516. static int dtmfcid_level = 256;
  517. #define REPORT_CHANNEL_ALARMS 1
  518. #define REPORT_SPAN_ALARMS 2
  519. static int report_alarms = REPORT_CHANNEL_ALARMS;
  520. #ifdef HAVE_PRI
  521. static int pridebugfd = -1;
  522. static char pridebugfilename[1024] = "";
  523. #endif
  524. /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
  525. static int firstdigittimeout = 16000;
  526. /*! \brief How long to wait for following digits (FXO logic) */
  527. static int gendigittimeout = 8000;
  528. /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
  529. static int matchdigittimeout = 3000;
  530. /*! \brief Protect the interface list (of dahdi_pvt's) */
  531. AST_MUTEX_DEFINE_STATIC(iflock);
  532. static int ifcount = 0;
  533. #ifdef HAVE_PRI
  534. AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
  535. #endif
  536. /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
  537. when it's doing something critical. */
  538. AST_MUTEX_DEFINE_STATIC(monlock);
  539. /*! \brief This is the thread for the monitor which checks for input on the channels
  540. which are not currently in use. */
  541. static pthread_t monitor_thread = AST_PTHREADT_NULL;
  542. static ast_cond_t ss_thread_complete;
  543. AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
  544. AST_MUTEX_DEFINE_STATIC(restart_lock);
  545. static int ss_thread_count = 0;
  546. static int num_restart_pending = 0;
  547. static int restart_monitor(void);
  548. static int dahdi_sendtext(struct ast_channel *c, const char *text);
  549. static void mwi_event_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
  550. {
  551. /* This module does not handle MWI in an event-based manner. However, it
  552. * subscribes to MWI for each mailbox that is configured so that the core
  553. * knows that we care about it. Then, chan_dahdi will get the MWI from the
  554. * event cache instead of checking the mailbox directly. */
  555. }
  556. /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
  557. static inline int dahdi_get_event(int fd)
  558. {
  559. int j;
  560. if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
  561. return -1;
  562. return j;
  563. }
  564. /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
  565. static inline int dahdi_wait_event(int fd)
  566. {
  567. int i, j = 0;
  568. i = DAHDI_IOMUX_SIGEVENT;
  569. if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
  570. return -1;
  571. if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
  572. return -1;
  573. return j;
  574. }
  575. /*! Chunk size to read -- we use 20ms chunks to make things happy. */
  576. #define READ_SIZE 160
  577. #define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
  578. #define MASK_INUSE (1 << 1) /*!< Channel currently in use */
  579. #define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE) /*!< 300 ms */
  580. #define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
  581. #define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) /*!< 100 ms */
  582. #define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) /*!< 500 ms */
  583. #define MIN_MS_SINCE_FLASH ((2000) ) /*!< 2000 ms */
  584. #define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
  585. #define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
  586. /*!
  587. * \brief Configured ring timeout base.
  588. * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
  589. */
  590. static int ringt_base = DEFAULT_RINGT;
  591. #if defined(HAVE_SS7)
  592. struct dahdi_ss7 {
  593. struct sig_ss7_linkset ss7;
  594. };
  595. static struct dahdi_ss7 linksets[NUM_SPANS];
  596. static int cur_ss7type = -1;
  597. static int cur_slc = -1;
  598. static int cur_linkset = -1;
  599. static int cur_pointcode = -1;
  600. static int cur_cicbeginswith = -1;
  601. static int cur_adjpointcode = -1;
  602. static int cur_networkindicator = -1;
  603. static int cur_defaultdpc = -1;
  604. #endif /* defined(HAVE_SS7) */
  605. #ifdef HAVE_OPENR2
  606. struct dahdi_mfcr2_conf {
  607. openr2_variant_t variant;
  608. int mfback_timeout;
  609. int metering_pulse_timeout;
  610. int max_ani;
  611. int max_dnis;
  612. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  613. int dtmf_time_on;
  614. int dtmf_time_off;
  615. #endif
  616. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
  617. int dtmf_end_timeout;
  618. #endif
  619. signed int get_ani_first:2;
  620. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  621. signed int skip_category_request:2;
  622. #endif
  623. unsigned int call_files:1;
  624. unsigned int allow_collect_calls:1;
  625. unsigned int charge_calls:1;
  626. unsigned int accept_on_offer:1;
  627. unsigned int forced_release:1;
  628. unsigned int double_answer:1;
  629. signed int immediate_accept:2;
  630. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  631. signed int dtmf_dialing:2;
  632. signed int dtmf_detection:2;
  633. #endif
  634. char logdir[OR2_MAX_PATH];
  635. char r2proto_file[OR2_MAX_PATH];
  636. openr2_log_level_t loglevel;
  637. openr2_calling_party_category_t category;
  638. };
  639. /* MFC-R2 pseudo-link structure */
  640. struct dahdi_mfcr2 {
  641. pthread_t r2master; /*!< Thread of master */
  642. openr2_context_t *protocol_context; /*!< OpenR2 context handle */
  643. struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
  644. int numchans; /*!< Number of channels in this R2 block */
  645. struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */
  646. };
  647. /* malloc'd array of malloc'd r2links */
  648. static struct dahdi_mfcr2 **r2links;
  649. /* how many r2links have been malloc'd */
  650. static int r2links_count = 0;
  651. #endif /* HAVE_OPENR2 */
  652. #ifdef HAVE_PRI
  653. struct dahdi_pri {
  654. int dchannels[SIG_PRI_NUM_DCHANS]; /*!< What channel are the dchannels on */
  655. int mastertrunkgroup; /*!< What trunk group is our master */
  656. int prilogicalspan; /*!< Logical span number within trunk group */
  657. struct sig_pri_span pri;
  658. };
  659. static struct dahdi_pri pris[NUM_SPANS];
  660. #if defined(HAVE_PRI_CCSS)
  661. /*! DAHDI PRI CCSS agent and monitor type name. */
  662. static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
  663. #endif /* defined(HAVE_PRI_CCSS) */
  664. #else
  665. /*! Shut up the compiler */
  666. struct dahdi_pri;
  667. #endif
  668. /* Polarity states */
  669. #define POLARITY_IDLE 0
  670. #define POLARITY_REV 1
  671. const char * const subnames[] = {
  672. "Real",
  673. "Callwait",
  674. "Threeway"
  675. };
  676. #define DATA_EXPORT_DAHDI_PVT(MEMBER) \
  677. MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE) \
  678. MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE) \
  679. MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE) \
  680. MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE) \
  681. MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE) \
  682. MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN) \
  683. MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN) \
  684. MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN) \
  685. MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN) \
  686. MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN) \
  687. MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN) \
  688. MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN) \
  689. MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN) \
  690. MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN) \
  691. MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN) \
  692. MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN) \
  693. MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN) \
  694. MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN) \
  695. MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN) \
  696. MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN) \
  697. MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN) \
  698. MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN) \
  699. MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN) \
  700. MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN) \
  701. MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN) \
  702. MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN) \
  703. MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN) \
  704. MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN) \
  705. MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN) \
  706. MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN) \
  707. MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN) \
  708. MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN) \
  709. MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN) \
  710. MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN) \
  711. MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN) \
  712. MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN) \
  713. MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN) \
  714. MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN) \
  715. MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN) \
  716. MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN) \
  717. MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN) \
  718. MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN) \
  719. MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN) \
  720. MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN) \
  721. MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN) \
  722. MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN) \
  723. MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN) \
  724. MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN) \
  725. MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN) \
  726. MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN) \
  727. MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN) \
  728. MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN) \
  729. MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN) \
  730. MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN) \
  731. MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN) \
  732. MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN) \
  733. MEMBER(dahdi_pvt, locallyblocked, AST_DATA_UNSIGNED_INTEGER) \
  734. MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_UNSIGNED_INTEGER) \
  735. MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN) \
  736. MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN) \
  737. MEMBER(dahdi_pvt, context, AST_DATA_STRING) \
  738. MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING) \
  739. MEMBER(dahdi_pvt, description, AST_DATA_STRING) \
  740. MEMBER(dahdi_pvt, exten, AST_DATA_STRING) \
  741. MEMBER(dahdi_pvt, language, AST_DATA_STRING) \
  742. MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING) \
  743. MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING) \
  744. MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
  745. AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
  746. static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
  747. static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
  748. #if defined(HAVE_PRI)
  749. struct doomed_pri {
  750. struct sig_pri_span *pri;
  751. AST_LIST_ENTRY(doomed_pri) list;
  752. };
  753. static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
  754. static void pri_destroy_span(struct sig_pri_span *pri);
  755. static struct dahdi_parms_pseudo {
  756. int buf_no; /*!< Number of buffers */
  757. int buf_policy; /*!< Buffer policy */
  758. int faxbuf_no; /*!< Number of Fax buffers */
  759. int faxbuf_policy; /*!< Fax buffer policy */
  760. } dahdi_pseudo_parms;
  761. #endif /* defined(HAVE_PRI) */
  762. /*! \brief Channel configuration from chan_dahdi.conf .
  763. * This struct is used for parsing the [channels] section of chan_dahdi.conf.
  764. * Generally there is a field here for every possible configuration item.
  765. *
  766. * The state of fields is saved along the parsing and whenever a 'channel'
  767. * statement is reached, the current dahdi_chan_conf is used to configure the
  768. * channel (struct dahdi_pvt)
  769. *
  770. * \see dahdi_chan_init for the default values.
  771. */
  772. struct dahdi_chan_conf {
  773. struct dahdi_pvt chan;
  774. #ifdef HAVE_PRI
  775. struct dahdi_pri pri;
  776. #endif
  777. #if defined(HAVE_SS7)
  778. struct dahdi_ss7 ss7;
  779. #endif /* defined(HAVE_SS7) */
  780. #ifdef HAVE_OPENR2
  781. struct dahdi_mfcr2_conf mfcr2;
  782. #endif
  783. struct dahdi_params timing;
  784. int is_sig_auto; /*!< Use channel signalling from DAHDI? */
  785. /*! Continue configuration even if a channel is not there. */
  786. int ignore_failed_channels;
  787. /*!
  788. * \brief The serial port to listen for SMDI data on
  789. * \note Set from the "smdiport" string read in from chan_dahdi.conf
  790. */
  791. char smdi_port[SMDI_MAX_FILENAME_LEN];
  792. /*!
  793. * \brief Don't create channels below this number
  794. * \note by default is 0 (no limit)
  795. */
  796. int wanted_channels_start;
  797. /*!
  798. * \brief Don't create channels above this number (infinity by default)
  799. * \note by default is 0 (special value that means "no limit").
  800. */
  801. int wanted_channels_end;
  802. };
  803. /*! returns a new dahdi_chan_conf with default values (by-value) */
  804. static struct dahdi_chan_conf dahdi_chan_conf_default(void)
  805. {
  806. /* recall that if a field is not included here it is initialized
  807. * to 0 or equivalent
  808. */
  809. struct dahdi_chan_conf conf = {
  810. #ifdef HAVE_PRI
  811. .pri.pri = {
  812. .nsf = PRI_NSF_NONE,
  813. .switchtype = PRI_SWITCH_NI2,
  814. .dialplan = PRI_UNKNOWN + 1,
  815. .localdialplan = PRI_NATIONAL_ISDN + 1,
  816. .nodetype = PRI_CPE,
  817. .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
  818. #if defined(HAVE_PRI_CCSS)
  819. .cc_ptmp_recall_mode = 1,/* specificRecall */
  820. .cc_qsig_signaling_link_req = 1,/* retain */
  821. .cc_qsig_signaling_link_rsp = 1,/* retain */
  822. #endif /* defined(HAVE_PRI_CCSS) */
  823. .minunused = 2,
  824. .idleext = "",
  825. .idledial = "",
  826. .internationalprefix = "",
  827. .nationalprefix = "",
  828. .localprefix = "",
  829. .privateprefix = "",
  830. .unknownprefix = "",
  831. .colp_send = SIG_PRI_COLP_UPDATE,
  832. .resetinterval = -1,
  833. },
  834. #endif
  835. #if defined(HAVE_SS7)
  836. .ss7.ss7 = {
  837. .called_nai = SS7_NAI_NATIONAL,
  838. .calling_nai = SS7_NAI_NATIONAL,
  839. .internationalprefix = "",
  840. .nationalprefix = "",
  841. .subscriberprefix = "",
  842. .unknownprefix = "",
  843. .networkroutedprefix = ""
  844. },
  845. #endif /* defined(HAVE_SS7) */
  846. #ifdef HAVE_OPENR2
  847. .mfcr2 = {
  848. .variant = OR2_VAR_ITU,
  849. .mfback_timeout = -1,
  850. .metering_pulse_timeout = -1,
  851. .max_ani = 10,
  852. .max_dnis = 4,
  853. .get_ani_first = -1,
  854. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  855. .skip_category_request = -1,
  856. #endif
  857. .call_files = 0,
  858. .allow_collect_calls = 0,
  859. .charge_calls = 1,
  860. .accept_on_offer = 1,
  861. .forced_release = 0,
  862. .double_answer = 0,
  863. .immediate_accept = -1,
  864. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  865. .dtmf_dialing = -1,
  866. .dtmf_detection = -1,
  867. .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
  868. .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
  869. #endif
  870. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
  871. .dtmf_end_timeout = -1,
  872. #endif
  873. .logdir = "",
  874. .r2proto_file = "",
  875. .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
  876. .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
  877. },
  878. #endif
  879. .chan = {
  880. .context = "default",
  881. .cid_num = "",
  882. .cid_name = "",
  883. .cid_tag = "",
  884. .mohinterpret = "default",
  885. .mohsuggest = "",
  886. .parkinglot = "",
  887. .transfertobusy = 1,
  888. .cid_signalling = CID_SIG_BELL,
  889. .cid_start = CID_START_RING,
  890. .dahditrcallerid = 0,
  891. .use_callerid = 1,
  892. .sig = -1,
  893. .outsigmod = -1,
  894. .cid_rxgain = +5.0,
  895. .tonezone = -1,
  896. .echocancel.head.tap_length = 1,
  897. .busycount = 3,
  898. .accountcode = "",
  899. .mailbox = "",
  900. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  901. .mwisend_fsk = 1,
  902. #endif
  903. .polarityonanswerdelay = 600,
  904. .sendcalleridafter = DEFAULT_CIDRINGS,
  905. .buf_policy = DAHDI_POLICY_IMMEDIATE,
  906. .buf_no = numbufs,
  907. .usefaxbuffers = 0,
  908. .cc_params = ast_cc_config_params_init(),
  909. },
  910. .timing = {
  911. .prewinktime = -1,
  912. .preflashtime = -1,
  913. .winktime = -1,
  914. .flashtime = -1,
  915. .starttime = -1,
  916. .rxwinktime = -1,
  917. .rxflashtime = -1,
  918. .debouncetime = -1
  919. },
  920. .is_sig_auto = 1,
  921. .ignore_failed_channels = 1,
  922. .smdi_port = "/dev/ttyS0",
  923. };
  924. return conf;
  925. }
  926. static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap,
  927. const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
  928. const char *data, int *cause);
  929. static int dahdi_digit_begin(struct ast_channel *ast, char digit);
  930. static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
  931. static int dahdi_sendtext(struct ast_channel *c, const char *text);
  932. static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout);
  933. static int dahdi_hangup(struct ast_channel *ast);
  934. static int dahdi_answer(struct ast_channel *ast);
  935. static struct ast_frame *dahdi_read(struct ast_channel *ast);
  936. static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
  937. static struct ast_frame *dahdi_exception(struct ast_channel *ast);
  938. static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
  939. static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  940. static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
  941. static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
  942. static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
  943. static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
  944. static int dahdi_devicestate(const char *data);
  945. static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
  946. static struct ast_channel_tech dahdi_tech = {
  947. .type = "DAHDI",
  948. .description = tdesc,
  949. .requester = dahdi_request,
  950. .send_digit_begin = dahdi_digit_begin,
  951. .send_digit_end = dahdi_digit_end,
  952. .send_text = dahdi_sendtext,
  953. .call = dahdi_call,
  954. .hangup = dahdi_hangup,
  955. .answer = dahdi_answer,
  956. .read = dahdi_read,
  957. .write = dahdi_write,
  958. .exception = dahdi_exception,
  959. .indicate = dahdi_indicate,
  960. .fixup = dahdi_fixup,
  961. .setoption = dahdi_setoption,
  962. .queryoption = dahdi_queryoption,
  963. .func_channel_read = dahdi_func_read,
  964. .func_channel_write = dahdi_func_write,
  965. .devicestate = dahdi_devicestate,
  966. .cc_callback = dahdi_cc_callback,
  967. };
  968. #define GET_CHANNEL(p) ((p)->channel)
  969. static enum analog_sigtype dahdisig_to_analogsig(int sig)
  970. {
  971. switch (sig) {
  972. case SIG_FXOLS:
  973. return ANALOG_SIG_FXOLS;
  974. case SIG_FXOGS:
  975. return ANALOG_SIG_FXOGS;
  976. case SIG_FXOKS:
  977. return ANALOG_SIG_FXOKS;
  978. case SIG_FXSLS:
  979. return ANALOG_SIG_FXSLS;
  980. case SIG_FXSGS:
  981. return ANALOG_SIG_FXSGS;
  982. case SIG_FXSKS:
  983. return ANALOG_SIG_FXSKS;
  984. case SIG_EMWINK:
  985. return ANALOG_SIG_EMWINK;
  986. case SIG_EM:
  987. return ANALOG_SIG_EM;
  988. case SIG_EM_E1:
  989. return ANALOG_SIG_EM_E1;
  990. case SIG_FEATD:
  991. return ANALOG_SIG_FEATD;
  992. case SIG_FEATDMF:
  993. return ANALOG_SIG_FEATDMF;
  994. case SIG_E911:
  995. return SIG_E911;
  996. case SIG_FGC_CAMA:
  997. return ANALOG_SIG_FGC_CAMA;
  998. case SIG_FGC_CAMAMF:
  999. return ANALOG_SIG_FGC_CAMAMF;
  1000. case SIG_FEATB:
  1001. return ANALOG_SIG_FEATB;
  1002. case SIG_SFWINK:
  1003. return ANALOG_SIG_SFWINK;
  1004. case SIG_SF:
  1005. return ANALOG_SIG_SF;
  1006. case SIG_SF_FEATD:
  1007. return ANALOG_SIG_SF_FEATD;
  1008. case SIG_SF_FEATDMF:
  1009. return ANALOG_SIG_SF_FEATDMF;
  1010. case SIG_FEATDMF_TA:
  1011. return ANALOG_SIG_FEATDMF_TA;
  1012. case SIG_SF_FEATB:
  1013. return ANALOG_SIG_FEATB;
  1014. default:
  1015. return -1;
  1016. }
  1017. }
  1018. static int analog_tone_to_dahditone(enum analog_tone tone)
  1019. {
  1020. switch (tone) {
  1021. case ANALOG_TONE_RINGTONE:
  1022. return DAHDI_TONE_RINGTONE;
  1023. case ANALOG_TONE_STUTTER:
  1024. return DAHDI_TONE_STUTTER;
  1025. case ANALOG_TONE_CONGESTION:
  1026. return DAHDI_TONE_CONGESTION;
  1027. case ANALOG_TONE_DIALTONE:
  1028. return DAHDI_TONE_DIALTONE;
  1029. case ANALOG_TONE_DIALRECALL:
  1030. return DAHDI_TONE_DIALRECALL;
  1031. case ANALOG_TONE_INFO:
  1032. return DAHDI_TONE_INFO;
  1033. default:
  1034. return -1;
  1035. }
  1036. }
  1037. static int analogsub_to_dahdisub(enum analog_sub analogsub)
  1038. {
  1039. int index;
  1040. switch (analogsub) {
  1041. case ANALOG_SUB_REAL:
  1042. index = SUB_REAL;
  1043. break;
  1044. case ANALOG_SUB_CALLWAIT:
  1045. index = SUB_CALLWAIT;
  1046. break;
  1047. case ANALOG_SUB_THREEWAY:
  1048. index = SUB_THREEWAY;
  1049. break;
  1050. default:
  1051. ast_log(LOG_ERROR, "Unidentified sub!\n");
  1052. index = SUB_REAL;
  1053. }
  1054. return index;
  1055. }
  1056. /*!
  1057. * \internal
  1058. * \brief release all members on the doomed pris list
  1059. * \since 13.0
  1060. *
  1061. * Called priodically by the monitor threads to release spans marked for
  1062. * removal.
  1063. */
  1064. static void release_doomed_pris(void)
  1065. {
  1066. #ifdef HAVE_PRI
  1067. struct doomed_pri *entry;
  1068. AST_LIST_LOCK(&doomed_pris);
  1069. while ((entry = AST_LIST_REMOVE_HEAD(&doomed_pris, list))) {
  1070. /* The span destruction must be done with this lock not held */
  1071. AST_LIST_UNLOCK(&doomed_pris);
  1072. ast_debug(4, "Destroying span %d from doomed queue.\n",
  1073. entry->pri->span);
  1074. pri_destroy_span(entry->pri);
  1075. ast_free(entry);
  1076. AST_LIST_LOCK(&doomed_pris);
  1077. }
  1078. AST_LIST_UNLOCK(&doomed_pris);
  1079. #endif
  1080. }
  1081. #ifdef HAVE_PRI
  1082. /*!
  1083. * \brief Queue a span for destruction
  1084. * \since 13.0
  1085. *
  1086. * \param pri the span to destroy
  1087. *
  1088. * Add a span to the list of spans to be destroyed later on
  1089. * by the monitor thread. Allows destroying a span while holding its
  1090. * lock.
  1091. */
  1092. static void pri_queue_for_destruction(struct sig_pri_span *pri)
  1093. {
  1094. struct doomed_pri *entry;
  1095. AST_LIST_LOCK(&doomed_pris);
  1096. AST_LIST_TRAVERSE(&doomed_pris, entry, list) {
  1097. if (entry->pri == pri) {
  1098. AST_LIST_UNLOCK(&doomed_pris);
  1099. return;
  1100. }
  1101. }
  1102. entry = ast_calloc(sizeof(struct doomed_pri), 1);
  1103. if (!entry) {
  1104. /* Nothing useful to do here. Panic? */
  1105. ast_log(LOG_WARNING, "Failed allocating memory for a doomed_pri.\n");
  1106. AST_LIST_UNLOCK(&doomed_pris);
  1107. return;
  1108. }
  1109. entry->pri = pri;
  1110. ast_debug(4, "Queue span %d for destruction.\n", pri->span);
  1111. AST_LIST_INSERT_TAIL(&doomed_pris, entry, list);
  1112. AST_LIST_UNLOCK(&doomed_pris);
  1113. }
  1114. #endif
  1115. /*!
  1116. * \internal
  1117. * \brief Send a dial string to DAHDI.
  1118. * \since 12.0.0
  1119. *
  1120. * \param pvt DAHDI private pointer
  1121. * \param operation DAHDI dial operation to do to string
  1122. * \param dial_str Dial string to send
  1123. *
  1124. * \retval 0 on success.
  1125. * \retval non-zero on error.
  1126. */
  1127. static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
  1128. {
  1129. int res;
  1130. int offset;
  1131. const char *pos;
  1132. struct dahdi_dialoperation zo = {
  1133. .op = operation,
  1134. };
  1135. /* Convert the W's to ww. */
  1136. pos = dial_str;
  1137. for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) {
  1138. if (!*pos) {
  1139. break;
  1140. }
  1141. if (*pos == 'W') {
  1142. /* Convert 'W' to "ww" */
  1143. ++pos;
  1144. if (offset >= sizeof(zo.dialstr) - 3) {
  1145. /* No room to expand */
  1146. break;
  1147. }
  1148. zo.dialstr[offset] = 'w';
  1149. ++offset;
  1150. zo.dialstr[offset] = 'w';
  1151. continue;
  1152. }
  1153. zo.dialstr[offset] = *pos++;
  1154. }
  1155. /* The zo initialization has already terminated the dialstr. */
  1156. ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
  1157. pvt->channel, dial_str, zo.dialstr);
  1158. res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
  1159. if (res) {
  1160. ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
  1161. pvt->channel, dial_str, strerror(errno));
  1162. }
  1163. return res;
  1164. }
  1165. static enum analog_event dahdievent_to_analogevent(int event);
  1166. static int bump_gains(struct dahdi_pvt *p);
  1167. static int dahdi_setlinear(int dfd, int linear);
  1168. static int my_start_cid_detect(void *pvt, int cid_signalling)
  1169. {
  1170. struct dahdi_pvt *p = pvt;
  1171. int index = SUB_REAL;
  1172. p->cs = callerid_new(cid_signalling);
  1173. if (!p->cs) {
  1174. ast_log(LOG_ERROR, "Unable to alloc callerid\n");
  1175. return -1;
  1176. }
  1177. bump_gains(p);
  1178. dahdi_setlinear(p->subs[index].dfd, 0);
  1179. return 0;
  1180. }
  1181. static int my_stop_cid_detect(void *pvt)
  1182. {
  1183. struct dahdi_pvt *p = pvt;
  1184. int index = SUB_REAL;
  1185. if (p->cs)
  1186. callerid_free(p->cs);
  1187. dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
  1188. return 0;
  1189. }
  1190. static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
  1191. {
  1192. struct dahdi_pvt *p = pvt;
  1193. struct analog_pvt *analog_p = p->sig_pvt;
  1194. struct pollfd poller;
  1195. char *name, *num;
  1196. int index = SUB_REAL;
  1197. int res;
  1198. unsigned char buf[256];
  1199. int flags;
  1200. poller.fd = p->subs[SUB_REAL].dfd;
  1201. poller.events = POLLPRI | POLLIN;
  1202. poller.revents = 0;
  1203. res = poll(&poller, 1, timeout);
  1204. if (poller.revents & POLLPRI) {
  1205. *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
  1206. return 1;
  1207. }
  1208. if (poller.revents & POLLIN) {
  1209. /*** NOTES ***/
  1210. /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
  1211. * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
  1212. * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
  1213. * a failure and die, and returning 2 means no event was received. */
  1214. res = read(p->subs[index].dfd, buf, sizeof(buf));
  1215. if (res < 0) {
  1216. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  1217. return -1;
  1218. }
  1219. if (analog_p->ringt > 0) {
  1220. if (!(--analog_p->ringt)) {
  1221. /* only return if we timeout from a ring event */
  1222. return -1;
  1223. }
  1224. }
  1225. if (p->cid_signalling == CID_SIG_V23_JP) {
  1226. res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
  1227. } else {
  1228. res = callerid_feed(p->cs, buf, res, AST_LAW(p));
  1229. }
  1230. if (res < 0) {
  1231. /*
  1232. * The previous diagnostic message output likely
  1233. * explains why it failed.
  1234. */
  1235. ast_log(LOG_WARNING, "Failed to decode CallerID\n");
  1236. return -1;
  1237. }
  1238. if (res == 1) {
  1239. callerid_get(p->cs, &name, &num, &flags);
  1240. if (name)
  1241. ast_copy_string(namebuf, name, ANALOG_MAX_CID);
  1242. if (num)
  1243. ast_copy_string(numbuf, num, ANALOG_MAX_CID);
  1244. ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
  1245. return 0;
  1246. }
  1247. }
  1248. *ev = ANALOG_EVENT_NONE;
  1249. return 2;
  1250. }
  1251. static const char *event2str(int event);
  1252. static int restore_gains(struct dahdi_pvt *p);
  1253. static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
  1254. {
  1255. unsigned char buf[256];
  1256. int distMatches;
  1257. int curRingData[RING_PATTERNS];
  1258. int receivedRingT;
  1259. int counter1;
  1260. int counter;
  1261. int i;
  1262. int res;
  1263. int checkaftercid = 0;
  1264. struct dahdi_pvt *p = pvt;
  1265. struct analog_pvt *analog_p = p->sig_pvt;
  1266. if (ringdata == NULL) {
  1267. ringdata = curRingData;
  1268. } else {
  1269. checkaftercid = 1;
  1270. }
  1271. /* We must have a ring by now, so, if configured, lets try to listen for
  1272. * distinctive ringing */
  1273. if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
  1274. /* Clear the current ring data array so we don't have old data in it. */
  1275. for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
  1276. ringdata[receivedRingT] = 0;
  1277. receivedRingT = 0;
  1278. if (checkaftercid && distinctiveringaftercid)
  1279. ast_verb(3, "Detecting post-CID distinctive ring\n");
  1280. /* Check to see if context is what it should be, if not set to be. */
  1281. else if (strcmp(p->context,p->defcontext) != 0) {
  1282. ast_copy_string(p->context, p->defcontext, sizeof(p->context));
  1283. ast_channel_context_set(chan, p->defcontext);
  1284. }
  1285. for (;;) {
  1286. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  1287. if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
  1288. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  1289. ast_hangup(chan);
  1290. return 1;
  1291. }
  1292. if (i & DAHDI_IOMUX_SIGEVENT) {
  1293. res = dahdi_get_event(p->subs[idx].dfd);
  1294. if (res == DAHDI_EVENT_NOALARM) {
  1295. p->inalarm = 0;
  1296. analog_p->inalarm = 0;
  1297. }
  1298. ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
  1299. res = 0;
  1300. /* Let us detect distinctive ring */
  1301. ringdata[receivedRingT] = analog_p->ringt;
  1302. if (analog_p->ringt < analog_p->ringt_base/2)
  1303. break;
  1304. /* Increment the ringT counter so we can match it against
  1305. values in chan_dahdi.conf for distinctive ring */
  1306. if (++receivedRingT == RING_PATTERNS)
  1307. break;
  1308. } else if (i & DAHDI_IOMUX_READ) {
  1309. res = read(p->subs[idx].dfd, buf, sizeof(buf));
  1310. if (res < 0) {
  1311. if (errno != ELAST) {
  1312. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  1313. ast_hangup(chan);
  1314. return 1;
  1315. }
  1316. break;
  1317. }
  1318. if (analog_p->ringt > 0) {
  1319. if (!(--analog_p->ringt)) {
  1320. res = -1;
  1321. break;
  1322. }
  1323. }
  1324. }
  1325. }
  1326. }
  1327. if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
  1328. /* this only shows up if you have n of the dring patterns filled in */
  1329. ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
  1330. for (counter = 0; counter < 3; counter++) {
  1331. /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
  1332. distMatches = 0;
  1333. /* this only shows up if you have n of the dring patterns filled in */
  1334. ast_verb(3, "Checking %d,%d,%d\n",
  1335. p->drings.ringnum[counter].ring[0],
  1336. p->drings.ringnum[counter].ring[1],
  1337. p->drings.ringnum[counter].ring[2]);
  1338. for (counter1 = 0; counter1 < 3; counter1++) {
  1339. ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
  1340. if (p->drings.ringnum[counter].ring[counter1] == -1) {
  1341. ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
  1342. ringdata[counter1]);
  1343. distMatches++;
  1344. } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
  1345. ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
  1346. ast_verb(3, "Ring pattern matched in range: %d to %d\n",
  1347. (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
  1348. (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
  1349. distMatches++;
  1350. }
  1351. }
  1352. if (distMatches == 3) {
  1353. /* The ring matches, set the context to whatever is for distinctive ring.. */
  1354. ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
  1355. ast_channel_context_set(chan, S_OR(p->drings.ringContext[counter].contextData, p->defcontext));
  1356. ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
  1357. break;
  1358. }
  1359. }
  1360. }
  1361. /* Restore linear mode (if appropriate) for Caller*ID processing */
  1362. dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  1363. restore_gains(p);
  1364. return 0;
  1365. }
  1366. static int my_stop_callwait(void *pvt)
  1367. {
  1368. struct dahdi_pvt *p = pvt;
  1369. p->callwaitingrepeat = 0;
  1370. p->cidcwexpire = 0;
  1371. p->cid_suppress_expire = 0;
  1372. return 0;
  1373. }
  1374. static int send_callerid(struct dahdi_pvt *p);
  1375. static int save_conference(struct dahdi_pvt *p);
  1376. static int restore_conference(struct dahdi_pvt *p);
  1377. static int my_callwait(void *pvt)
  1378. {
  1379. struct dahdi_pvt *p = pvt;
  1380. p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
  1381. if (p->cidspill) {
  1382. ast_log(LOG_WARNING, "Spill already exists?!?\n");
  1383. ast_free(p->cidspill);
  1384. }
  1385. /*
  1386. * SAS: Subscriber Alert Signal, 440Hz for 300ms
  1387. * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
  1388. */
  1389. if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
  1390. return -1;
  1391. save_conference(p);
  1392. /* Silence */
  1393. memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
  1394. if (!p->callwaitrings && p->callwaitingcallerid) {
  1395. ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
  1396. p->callwaitcas = 1;
  1397. p->cidlen = 2400 + 680 + READ_SIZE * 4;
  1398. } else {
  1399. ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
  1400. p->callwaitcas = 0;
  1401. p->cidlen = 2400 + READ_SIZE * 4;
  1402. }
  1403. p->cidpos = 0;
  1404. send_callerid(p);
  1405. return 0;
  1406. }
  1407. static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
  1408. {
  1409. struct dahdi_pvt *p = pvt;
  1410. ast_debug(2, "Starting cid spill\n");
  1411. if (p->cidspill) {
  1412. ast_log(LOG_WARNING, "cidspill already exists??\n");
  1413. ast_free(p->cidspill);
  1414. }
  1415. if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
  1416. if (cwcid == 0) {
  1417. p->cidlen = ast_callerid_generate(p->cidspill,
  1418. caller->id.name.str,
  1419. caller->id.number.str,
  1420. AST_LAW(p));
  1421. } else {
  1422. ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
  1423. caller->id.name.str, caller->id.number.str);
  1424. p->callwaitcas = 0;
  1425. p->cidcwexpire = 0;
  1426. p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
  1427. caller->id.name.str,
  1428. caller->id.number.str,
  1429. AST_LAW(p));
  1430. p->cidlen += READ_SIZE * 4;
  1431. }
  1432. p->cidpos = 0;
  1433. p->cid_suppress_expire = 0;
  1434. send_callerid(p);
  1435. }
  1436. return 0;
  1437. }
  1438. static int my_dsp_reset_and_flush_digits(void *pvt)
  1439. {
  1440. struct dahdi_pvt *p = pvt;
  1441. if (p->dsp)
  1442. ast_dsp_digitreset(p->dsp);
  1443. return 0;
  1444. }
  1445. static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
  1446. {
  1447. struct dahdi_pvt *p = pvt;
  1448. if (p->channel == CHAN_PSEUDO)
  1449. ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
  1450. if (mode == ANALOG_DIGITMODE_DTMF) {
  1451. /* If we do hardware dtmf, no need for a DSP */
  1452. if (p->hardwaredtmf) {
  1453. if (p->dsp) {
  1454. ast_dsp_free(p->dsp);
  1455. p->dsp = NULL;
  1456. }
  1457. return 0;
  1458. }
  1459. if (!p->dsp) {
  1460. p->dsp = ast_dsp_new();
  1461. if (!p->dsp) {
  1462. ast_log(LOG_ERROR, "Unable to allocate DSP\n");
  1463. return -1;
  1464. }
  1465. }
  1466. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
  1467. } else if (mode == ANALOG_DIGITMODE_MF) {
  1468. if (!p->dsp) {
  1469. p->dsp = ast_dsp_new();
  1470. if (!p->dsp) {
  1471. ast_log(LOG_ERROR, "Unable to allocate DSP\n");
  1472. return -1;
  1473. }
  1474. }
  1475. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
  1476. }
  1477. return 0;
  1478. }
  1479. static int dahdi_wink(struct dahdi_pvt *p, int index);
  1480. static int my_wink(void *pvt, enum analog_sub sub)
  1481. {
  1482. struct dahdi_pvt *p = pvt;
  1483. int index = analogsub_to_dahdisub(sub);
  1484. if (index != SUB_REAL) {
  1485. ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
  1486. }
  1487. return dahdi_wink(p, index);
  1488. }
  1489. static void wakeup_sub(struct dahdi_pvt *p, int a);
  1490. static int reset_conf(struct dahdi_pvt *p);
  1491. static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
  1492. static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
  1493. {
  1494. struct ast_frame *f = *dest;
  1495. struct dahdi_pvt *p = pvt;
  1496. int idx = analogsub_to_dahdisub(analog_index);
  1497. ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
  1498. f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
  1499. (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
  1500. if (f->subclass.integer == 'f') {
  1501. if (f->frametype == AST_FRAME_DTMF_END) {
  1502. /* Fax tone -- Handle and return NULL */
  1503. if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
  1504. /* If faxbuffers are configured, use them for the fax transmission */
  1505. if (p->usefaxbuffers && !p->bufferoverrideinuse) {
  1506. struct dahdi_bufferinfo bi = {
  1507. .txbufpolicy = p->faxbuf_policy,
  1508. .bufsize = p->bufsize,
  1509. .numbufs = p->faxbuf_no
  1510. };
  1511. int res;
  1512. if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
  1513. ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
  1514. } else {
  1515. p->bufferoverrideinuse = 1;
  1516. }
  1517. }
  1518. p->faxhandled = 1;
  1519. if (p->dsp) {
  1520. p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
  1521. ast_dsp_set_features(p->dsp, p->dsp_features);
  1522. ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
  1523. }
  1524. if (strcmp(ast_channel_exten(ast), "fax")) {
  1525. const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
  1526. /* We need to unlock 'ast' here because ast_exists_extension has the
  1527. * potential to start autoservice on the channel. Such action is prone
  1528. * to deadlock.
  1529. */
  1530. ast_mutex_unlock(&p->lock);
  1531. ast_channel_unlock(ast);
  1532. if (ast_exists_extension(ast, target_context, "fax", 1,
  1533. S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
  1534. ast_channel_lock(ast);
  1535. ast_mutex_lock(&p->lock);
  1536. ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
  1537. /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
  1538. pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
  1539. if (ast_async_goto(ast, target_context, "fax", 1))
  1540. ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
  1541. } else {
  1542. ast_channel_lock(ast);
  1543. ast_mutex_lock(&p->lock);
  1544. ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
  1545. }
  1546. } else {
  1547. ast_debug(1, "Already in a fax extension, not redirecting\n");
  1548. }
  1549. } else {
  1550. ast_debug(1, "Fax already handled\n");
  1551. }
  1552. dahdi_confmute(p, 0);
  1553. }
  1554. p->subs[idx].f.frametype = AST_FRAME_NULL;
  1555. p->subs[idx].f.subclass.integer = 0;
  1556. *dest = &p->subs[idx].f;
  1557. }
  1558. }
  1559. static void my_lock_private(void *pvt)
  1560. {
  1561. struct dahdi_pvt *p = pvt;
  1562. ast_mutex_lock(&p->lock);
  1563. }
  1564. static void my_unlock_private(void *pvt)
  1565. {
  1566. struct dahdi_pvt *p = pvt;
  1567. ast_mutex_unlock(&p->lock);
  1568. }
  1569. static void my_deadlock_avoidance_private(void *pvt)
  1570. {
  1571. struct dahdi_pvt *p = pvt;
  1572. DEADLOCK_AVOIDANCE(&p->lock);
  1573. }
  1574. static struct ast_manager_event_blob *dahdichannel_to_ami(struct stasis_message *msg)
  1575. {
  1576. RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
  1577. struct ast_channel_blob *obj = stasis_message_data(msg);
  1578. struct ast_json *span, *channel;
  1579. channel_string = ast_manager_build_channel_state_string(obj->snapshot);
  1580. if (!channel_string) {
  1581. return NULL;
  1582. }
  1583. span = ast_json_object_get(obj->blob, "span");
  1584. channel = ast_json_object_get(obj->blob, "channel");
  1585. return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
  1586. "%s"
  1587. "DAHDISpan: %u\r\n"
  1588. "DAHDIChannel: %s\r\n",
  1589. ast_str_buffer(channel_string),
  1590. (unsigned int)ast_json_integer_get(span),
  1591. ast_json_string_get(channel));
  1592. }
  1593. STASIS_MESSAGE_TYPE_DEFN_LOCAL(dahdichannel_type,
  1594. .to_ami = dahdichannel_to_ami,
  1595. );
  1596. /*! \brief Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages */
  1597. static void publish_dahdichannel(struct ast_channel *chan, int span, const char *dahdi_channel)
  1598. {
  1599. RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
  1600. ast_assert(dahdi_channel != NULL);
  1601. blob = ast_json_pack("{s: i, s: s}",
  1602. "span", span,
  1603. "channel", dahdi_channel);
  1604. if (!blob) {
  1605. return;
  1606. }
  1607. ast_channel_lock(chan);
  1608. ast_channel_publish_blob(chan, dahdichannel_type(), blob);
  1609. ast_channel_unlock(chan);
  1610. }
  1611. /*!
  1612. * \internal
  1613. * \brief Post an AMI DAHDI channel association event.
  1614. * \since 1.8
  1615. *
  1616. * \param p DAHDI private pointer
  1617. * \param chan Channel associated with the private pointer
  1618. *
  1619. * \return Nothing
  1620. */
  1621. static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
  1622. {
  1623. char ch_name[20];
  1624. if (p->channel < CHAN_PSEUDO) {
  1625. /* No B channel */
  1626. snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
  1627. } else if (p->channel == CHAN_PSEUDO) {
  1628. /* Pseudo channel */
  1629. strcpy(ch_name, "pseudo");
  1630. } else {
  1631. /* Real channel */
  1632. snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
  1633. }
  1634. publish_dahdichannel(chan, p->span, ch_name);
  1635. }
  1636. #ifdef HAVE_PRI
  1637. /*!
  1638. * \internal
  1639. * \brief Post an AMI DAHDI channel association event.
  1640. * \since 1.8
  1641. *
  1642. * \param pvt DAHDI private pointer
  1643. * \param chan Channel associated with the private pointer
  1644. *
  1645. * \return Nothing
  1646. */
  1647. static void my_ami_channel_event(void *pvt, struct ast_channel *chan)
  1648. {
  1649. struct dahdi_pvt *p = pvt;
  1650. dahdi_ami_channel_event(p, chan);
  1651. }
  1652. #endif
  1653. /* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
  1654. * returns the last value of the linear setting
  1655. */
  1656. static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
  1657. {
  1658. struct dahdi_pvt *p = pvt;
  1659. int oldval;
  1660. int idx = analogsub_to_dahdisub(sub);
  1661. dahdi_setlinear(p->subs[idx].dfd, linear_mode);
  1662. oldval = p->subs[idx].linear;
  1663. p->subs[idx].linear = linear_mode ? 1 : 0;
  1664. return oldval;
  1665. }
  1666. static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
  1667. {
  1668. struct dahdi_pvt *p = pvt;
  1669. int idx = analogsub_to_dahdisub(sub);
  1670. p->subs[idx].inthreeway = inthreeway;
  1671. }
  1672. static int get_alarms(struct dahdi_pvt *p);
  1673. static void handle_alarms(struct dahdi_pvt *p, int alms);
  1674. static void my_get_and_handle_alarms(void *pvt)
  1675. {
  1676. int res;
  1677. struct dahdi_pvt *p = pvt;
  1678. res = get_alarms(p);
  1679. handle_alarms(p, res);
  1680. }
  1681. static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
  1682. {
  1683. RAII_VAR(struct ast_channel *, bridged, ast_channel_bridge_peer(chan), ast_channel_cleanup);
  1684. if (bridged && ast_channel_tech(bridged) == &dahdi_tech) {
  1685. struct dahdi_pvt *p = ast_channel_tech_pvt(bridged);
  1686. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  1687. return p->sig_pvt;
  1688. }
  1689. }
  1690. return NULL;
  1691. }
  1692. static int my_get_sub_fd(void *pvt, enum analog_sub sub)
  1693. {
  1694. struct dahdi_pvt *p = pvt;
  1695. int dahdi_sub = analogsub_to_dahdisub(sub);
  1696. return p->subs[dahdi_sub].dfd;
  1697. }
  1698. static void my_set_cadence(void *pvt, int *cid_rings, struct ast_channel *ast)
  1699. {
  1700. struct dahdi_pvt *p = pvt;
  1701. /* Choose proper cadence */
  1702. if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
  1703. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
  1704. ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
  1705. *cid_rings = cidrings[p->distinctivering - 1];
  1706. } else {
  1707. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
  1708. ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
  1709. *cid_rings = p->sendcalleridafter;
  1710. }
  1711. }
  1712. static void my_set_alarm(void *pvt, int in_alarm)
  1713. {
  1714. struct dahdi_pvt *p = pvt;
  1715. p->inalarm = in_alarm;
  1716. }
  1717. static void my_set_dialing(void *pvt, int is_dialing)
  1718. {
  1719. struct dahdi_pvt *p = pvt;
  1720. p->dialing = is_dialing;
  1721. }
  1722. static void my_set_outgoing(void *pvt, int is_outgoing)
  1723. {
  1724. struct dahdi_pvt *p = pvt;
  1725. p->outgoing = is_outgoing;
  1726. }
  1727. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  1728. static void my_set_digital(void *pvt, int is_digital)
  1729. {
  1730. struct dahdi_pvt *p = pvt;
  1731. p->digital = is_digital;
  1732. }
  1733. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  1734. #if defined(HAVE_SS7)
  1735. static void my_set_inservice(void *pvt, int is_inservice)
  1736. {
  1737. struct dahdi_pvt *p = pvt;
  1738. p->inservice = is_inservice;
  1739. }
  1740. #endif /* defined(HAVE_SS7) */
  1741. #if defined(HAVE_SS7)
  1742. static void my_set_locallyblocked(void *pvt, int is_blocked)
  1743. {
  1744. struct dahdi_pvt *p = pvt;
  1745. p->locallyblocked = is_blocked;
  1746. }
  1747. #endif /* defined(HAVE_SS7) */
  1748. #if defined(HAVE_SS7)
  1749. static void my_set_remotelyblocked(void *pvt, int is_blocked)
  1750. {
  1751. struct dahdi_pvt *p = pvt;
  1752. p->remotelyblocked = is_blocked;
  1753. }
  1754. #endif /* defined(HAVE_SS7) */
  1755. static void my_set_ringtimeout(void *pvt, int ringt)
  1756. {
  1757. struct dahdi_pvt *p = pvt;
  1758. p->ringt = ringt;
  1759. }
  1760. static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
  1761. {
  1762. struct dahdi_pvt *p = pvt;
  1763. if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
  1764. ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
  1765. gettimeofday(&p->waitingfordt, NULL);
  1766. ast_setstate(ast, AST_STATE_OFFHOOK);
  1767. }
  1768. }
  1769. static int my_check_waitingfordt(void *pvt)
  1770. {
  1771. struct dahdi_pvt *p = pvt;
  1772. if (p->waitingfordt.tv_sec) {
  1773. return 1;
  1774. }
  1775. return 0;
  1776. }
  1777. static void my_set_confirmanswer(void *pvt, int flag)
  1778. {
  1779. struct dahdi_pvt *p = pvt;
  1780. p->confirmanswer = flag;
  1781. }
  1782. static int my_check_confirmanswer(void *pvt)
  1783. {
  1784. struct dahdi_pvt *p = pvt;
  1785. if (p->confirmanswer) {
  1786. return 1;
  1787. }
  1788. return 0;
  1789. }
  1790. static void my_set_callwaiting(void *pvt, int callwaiting_enable)
  1791. {
  1792. struct dahdi_pvt *p = pvt;
  1793. p->callwaiting = callwaiting_enable;
  1794. }
  1795. static void my_cancel_cidspill(void *pvt)
  1796. {
  1797. struct dahdi_pvt *p = pvt;
  1798. ast_free(p->cidspill);
  1799. p->cidspill = NULL;
  1800. restore_conference(p);
  1801. }
  1802. static int my_confmute(void *pvt, int mute)
  1803. {
  1804. struct dahdi_pvt *p = pvt;
  1805. return dahdi_confmute(p, mute);
  1806. }
  1807. static void my_set_pulsedial(void *pvt, int flag)
  1808. {
  1809. struct dahdi_pvt *p = pvt;
  1810. p->pulsedial = flag;
  1811. }
  1812. static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
  1813. {
  1814. struct dahdi_pvt *p = pvt;
  1815. p->owner = new_owner;
  1816. }
  1817. static const char *my_get_orig_dialstring(void *pvt)
  1818. {
  1819. struct dahdi_pvt *p = pvt;
  1820. return p->dialstring;
  1821. }
  1822. static void my_increase_ss_count(void)
  1823. {
  1824. ast_mutex_lock(&ss_thread_lock);
  1825. ss_thread_count++;
  1826. ast_mutex_unlock(&ss_thread_lock);
  1827. }
  1828. static void my_decrease_ss_count(void)
  1829. {
  1830. ast_mutex_lock(&ss_thread_lock);
  1831. ss_thread_count--;
  1832. ast_cond_signal(&ss_thread_complete);
  1833. ast_mutex_unlock(&ss_thread_lock);
  1834. }
  1835. static void my_all_subchannels_hungup(void *pvt)
  1836. {
  1837. struct dahdi_pvt *p = pvt;
  1838. int res, law;
  1839. p->faxhandled = 0;
  1840. p->didtdd = 0;
  1841. if (p->dsp) {
  1842. ast_dsp_free(p->dsp);
  1843. p->dsp = NULL;
  1844. }
  1845. p->law = p->law_default;
  1846. law = p->law_default;
  1847. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
  1848. if (res < 0)
  1849. ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
  1850. dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
  1851. #if 1
  1852. {
  1853. int i;
  1854. p->owner = NULL;
  1855. /* Cleanup owners here */
  1856. for (i = 0; i < 3; i++) {
  1857. p->subs[i].owner = NULL;
  1858. }
  1859. }
  1860. #endif
  1861. reset_conf(p);
  1862. if (num_restart_pending == 0) {
  1863. restart_monitor();
  1864. }
  1865. }
  1866. static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
  1867. static int my_conf_del(void *pvt, enum analog_sub sub)
  1868. {
  1869. struct dahdi_pvt *p = pvt;
  1870. int x = analogsub_to_dahdisub(sub);
  1871. return conf_del(p, &p->subs[x], x);
  1872. }
  1873. static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
  1874. static int my_conf_add(void *pvt, enum analog_sub sub)
  1875. {
  1876. struct dahdi_pvt *p = pvt;
  1877. int x = analogsub_to_dahdisub(sub);
  1878. return conf_add(p, &p->subs[x], x, 0);
  1879. }
  1880. static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
  1881. static int my_complete_conference_update(void *pvt, int needconference)
  1882. {
  1883. struct dahdi_pvt *p = pvt;
  1884. int needconf = needconference;
  1885. int x;
  1886. int useslavenative;
  1887. struct dahdi_pvt *slave = NULL;
  1888. useslavenative = isslavenative(p, &slave);
  1889. /* If we have a slave, add him to our conference now. or DAX
  1890. if this is slave native */
  1891. for (x = 0; x < MAX_SLAVES; x++) {
  1892. if (p->slaves[x]) {
  1893. if (useslavenative)
  1894. conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
  1895. else {
  1896. conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
  1897. needconf++;
  1898. }
  1899. }
  1900. }
  1901. /* If we're supposed to be in there, do so now */
  1902. if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
  1903. if (useslavenative)
  1904. conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
  1905. else {
  1906. conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
  1907. needconf++;
  1908. }
  1909. }
  1910. /* If we have a master, add ourselves to his conference */
  1911. if (p->master) {
  1912. if (isslavenative(p->master, NULL)) {
  1913. conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
  1914. } else {
  1915. conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
  1916. }
  1917. }
  1918. if (!needconf) {
  1919. /* Nobody is left (or should be left) in our conference.
  1920. Kill it. */
  1921. p->confno = -1;
  1922. }
  1923. return 0;
  1924. }
  1925. static int check_for_conference(struct dahdi_pvt *p);
  1926. static int my_check_for_conference(void *pvt)
  1927. {
  1928. struct dahdi_pvt *p = pvt;
  1929. return check_for_conference(p);
  1930. }
  1931. static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a, enum analog_sub b, struct ast_channel *ast_b)
  1932. {
  1933. struct dahdi_pvt *p = pvt;
  1934. int da, db;
  1935. int tchan;
  1936. int tinthreeway;
  1937. da = analogsub_to_dahdisub(a);
  1938. db = analogsub_to_dahdisub(b);
  1939. tchan = p->subs[da].chan;
  1940. p->subs[da].chan = p->subs[db].chan;
  1941. p->subs[db].chan = tchan;
  1942. tinthreeway = p->subs[da].inthreeway;
  1943. p->subs[da].inthreeway = p->subs[db].inthreeway;
  1944. p->subs[db].inthreeway = tinthreeway;
  1945. p->subs[da].owner = ast_a;
  1946. p->subs[db].owner = ast_b;
  1947. if (ast_a)
  1948. ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
  1949. if (ast_b)
  1950. ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
  1951. wakeup_sub(p, a);
  1952. wakeup_sub(p, b);
  1953. return;
  1954. }
  1955. /*!
  1956. * \internal
  1957. * \brief performs duties of dahdi_new, but also removes and possibly unbinds (if callid_created is 1) before returning
  1958. * \note this variant of dahdi should only be used in conjunction with ast_callid_threadstorage_auto()
  1959. *
  1960. * \param callid_created value returned from ast_callid_threadstorage_auto()
  1961. */
  1962. static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid, int callid_created);
  1963. static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid);
  1964. static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
  1965. {
  1966. struct ast_callid *callid = NULL;
  1967. int callid_created = ast_callid_threadstorage_auto(&callid);
  1968. struct dahdi_pvt *p = pvt;
  1969. int dsub = analogsub_to_dahdisub(sub);
  1970. return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, NULL, requestor, callid, callid_created);
  1971. }
  1972. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  1973. static int dahdi_setlaw(int dfd, int law)
  1974. {
  1975. int res;
  1976. res = ioctl(dfd, DAHDI_SETLAW, &law);
  1977. if (res)
  1978. return res;
  1979. return 0;
  1980. }
  1981. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  1982. #if defined(HAVE_PRI)
  1983. static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state,
  1984. enum sig_pri_law law, char *exten, const struct ast_assigned_ids *assignedids,
  1985. const struct ast_channel *requestor)
  1986. {
  1987. struct dahdi_pvt *p = pvt;
  1988. int audio;
  1989. int newlaw = -1;
  1990. struct ast_callid *callid = NULL;
  1991. int callid_created = ast_callid_threadstorage_auto(&callid);
  1992. switch (p->sig) {
  1993. case SIG_PRI_LIB_HANDLE_CASES:
  1994. if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
  1995. /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
  1996. break;
  1997. }
  1998. /* Fall through */
  1999. default:
  2000. /* Set to audio mode at this point */
  2001. audio = 1;
  2002. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
  2003. ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
  2004. p->channel, audio, strerror(errno));
  2005. }
  2006. break;
  2007. }
  2008. if (law != SIG_PRI_DEFLAW) {
  2009. dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
  2010. }
  2011. ast_copy_string(p->exten, exten, sizeof(p->exten));
  2012. switch (law) {
  2013. case SIG_PRI_DEFLAW:
  2014. newlaw = 0;
  2015. break;
  2016. case SIG_PRI_ALAW:
  2017. newlaw = DAHDI_LAW_ALAW;
  2018. break;
  2019. case SIG_PRI_ULAW:
  2020. newlaw = DAHDI_LAW_MULAW;
  2021. break;
  2022. }
  2023. return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
  2024. }
  2025. #endif /* defined(HAVE_PRI) */
  2026. static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
  2027. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  2028. /*!
  2029. * \internal
  2030. * \brief Open the PRI/SS7 channel media path.
  2031. * \since 1.8
  2032. *
  2033. * \param p Channel private control structure.
  2034. *
  2035. * \return Nothing
  2036. */
  2037. static void my_pri_ss7_open_media(void *p)
  2038. {
  2039. struct dahdi_pvt *pvt = p;
  2040. int res;
  2041. int dfd;
  2042. int set_val;
  2043. dfd = pvt->subs[SUB_REAL].dfd;
  2044. /* Open the media path. */
  2045. set_val = 1;
  2046. res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
  2047. if (res < 0) {
  2048. ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
  2049. pvt->channel, strerror(errno));
  2050. }
  2051. /* Set correct companding law for this call. */
  2052. res = dahdi_setlaw(dfd, pvt->law);
  2053. if (res < 0) {
  2054. ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
  2055. }
  2056. /* Set correct gain for this call. */
  2057. if (pvt->digital) {
  2058. res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
  2059. } else {
  2060. res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
  2061. pvt->law);
  2062. }
  2063. if (res < 0) {
  2064. ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
  2065. }
  2066. if (pvt->dsp_features && pvt->dsp) {
  2067. ast_dsp_set_features(pvt->dsp, pvt->dsp_features);
  2068. pvt->dsp_features = 0;
  2069. }
  2070. }
  2071. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  2072. #if defined(HAVE_PRI)
  2073. /*!
  2074. * \internal
  2075. * \brief Ask DAHDI to dial the given dial string.
  2076. * \since 1.8.11
  2077. *
  2078. * \param p Channel private control structure.
  2079. * \param dial_string String to pass to DAHDI to dial.
  2080. *
  2081. * \note The channel private lock needs to be held when calling.
  2082. *
  2083. * \return Nothing
  2084. */
  2085. static void my_pri_dial_digits(void *p, const char *dial_string)
  2086. {
  2087. char dial_str[DAHDI_MAX_DTMF_BUF];
  2088. struct dahdi_pvt *pvt = p;
  2089. int res;
  2090. snprintf(dial_str, sizeof(dial_str), "T%s", dial_string);
  2091. res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
  2092. if (!res) {
  2093. pvt->dialing = 1;
  2094. }
  2095. }
  2096. #endif /* defined(HAVE_PRI) */
  2097. static int unalloc_sub(struct dahdi_pvt *p, int x);
  2098. static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
  2099. {
  2100. struct dahdi_pvt *p = pvt;
  2101. return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
  2102. }
  2103. static int alloc_sub(struct dahdi_pvt *p, int x);
  2104. static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
  2105. {
  2106. struct dahdi_pvt *p = pvt;
  2107. return alloc_sub(p, analogsub_to_dahdisub(analogsub));
  2108. }
  2109. static int has_voicemail(struct dahdi_pvt *p);
  2110. static int my_has_voicemail(void *pvt)
  2111. {
  2112. struct dahdi_pvt *p = pvt;
  2113. return has_voicemail(p);
  2114. }
  2115. static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
  2116. {
  2117. struct dahdi_pvt *p = pvt;
  2118. int index;
  2119. index = analogsub_to_dahdisub(sub);
  2120. return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
  2121. }
  2122. static enum analog_event dahdievent_to_analogevent(int event)
  2123. {
  2124. enum analog_event res;
  2125. switch (event) {
  2126. case DAHDI_EVENT_ONHOOK:
  2127. res = ANALOG_EVENT_ONHOOK;
  2128. break;
  2129. case DAHDI_EVENT_RINGOFFHOOK:
  2130. res = ANALOG_EVENT_RINGOFFHOOK;
  2131. break;
  2132. case DAHDI_EVENT_WINKFLASH:
  2133. res = ANALOG_EVENT_WINKFLASH;
  2134. break;
  2135. case DAHDI_EVENT_ALARM:
  2136. res = ANALOG_EVENT_ALARM;
  2137. break;
  2138. case DAHDI_EVENT_NOALARM:
  2139. res = ANALOG_EVENT_NOALARM;
  2140. break;
  2141. case DAHDI_EVENT_DIALCOMPLETE:
  2142. res = ANALOG_EVENT_DIALCOMPLETE;
  2143. break;
  2144. case DAHDI_EVENT_RINGERON:
  2145. res = ANALOG_EVENT_RINGERON;
  2146. break;
  2147. case DAHDI_EVENT_RINGEROFF:
  2148. res = ANALOG_EVENT_RINGEROFF;
  2149. break;
  2150. case DAHDI_EVENT_HOOKCOMPLETE:
  2151. res = ANALOG_EVENT_HOOKCOMPLETE;
  2152. break;
  2153. case DAHDI_EVENT_PULSE_START:
  2154. res = ANALOG_EVENT_PULSE_START;
  2155. break;
  2156. case DAHDI_EVENT_POLARITY:
  2157. res = ANALOG_EVENT_POLARITY;
  2158. break;
  2159. case DAHDI_EVENT_RINGBEGIN:
  2160. res = ANALOG_EVENT_RINGBEGIN;
  2161. break;
  2162. case DAHDI_EVENT_EC_DISABLED:
  2163. res = ANALOG_EVENT_EC_DISABLED;
  2164. break;
  2165. case DAHDI_EVENT_REMOVED:
  2166. res = ANALOG_EVENT_REMOVED;
  2167. break;
  2168. case DAHDI_EVENT_NEONMWI_ACTIVE:
  2169. res = ANALOG_EVENT_NEONMWI_ACTIVE;
  2170. break;
  2171. case DAHDI_EVENT_NEONMWI_INACTIVE:
  2172. res = ANALOG_EVENT_NEONMWI_INACTIVE;
  2173. break;
  2174. #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
  2175. case DAHDI_EVENT_TX_CED_DETECTED:
  2176. res = ANALOG_EVENT_TX_CED_DETECTED;
  2177. break;
  2178. case DAHDI_EVENT_RX_CED_DETECTED:
  2179. res = ANALOG_EVENT_RX_CED_DETECTED;
  2180. break;
  2181. case DAHDI_EVENT_EC_NLP_DISABLED:
  2182. res = ANALOG_EVENT_EC_NLP_DISABLED;
  2183. break;
  2184. case DAHDI_EVENT_EC_NLP_ENABLED:
  2185. res = ANALOG_EVENT_EC_NLP_ENABLED;
  2186. break;
  2187. #endif
  2188. case DAHDI_EVENT_PULSEDIGIT:
  2189. res = ANALOG_EVENT_PULSEDIGIT;
  2190. break;
  2191. case DAHDI_EVENT_DTMFDOWN:
  2192. res = ANALOG_EVENT_DTMFDOWN;
  2193. break;
  2194. case DAHDI_EVENT_DTMFUP:
  2195. res = ANALOG_EVENT_DTMFUP;
  2196. break;
  2197. default:
  2198. switch(event & 0xFFFF0000) {
  2199. case DAHDI_EVENT_PULSEDIGIT:
  2200. case DAHDI_EVENT_DTMFDOWN:
  2201. case DAHDI_EVENT_DTMFUP:
  2202. /* The event includes a digit number in the low word.
  2203. * Converting it to a 'enum analog_event' would remove
  2204. * that information. Thus it is returned as-is.
  2205. */
  2206. return event;
  2207. }
  2208. res = ANALOG_EVENT_ERROR;
  2209. break;
  2210. }
  2211. return res;
  2212. }
  2213. static inline int dahdi_wait_event(int fd);
  2214. static int my_wait_event(void *pvt)
  2215. {
  2216. struct dahdi_pvt *p = pvt;
  2217. return dahdi_wait_event(p->subs[SUB_REAL].dfd);
  2218. }
  2219. static int my_get_event(void *pvt)
  2220. {
  2221. struct dahdi_pvt *p = pvt;
  2222. int res;
  2223. if (p->fake_event) {
  2224. res = p->fake_event;
  2225. p->fake_event = 0;
  2226. } else
  2227. res = dahdi_get_event(p->subs[SUB_REAL].dfd);
  2228. return dahdievent_to_analogevent(res);
  2229. }
  2230. static int my_is_off_hook(void *pvt)
  2231. {
  2232. struct dahdi_pvt *p = pvt;
  2233. int res;
  2234. struct dahdi_params par;
  2235. memset(&par, 0, sizeof(par));
  2236. if (p->subs[SUB_REAL].dfd > -1)
  2237. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
  2238. else {
  2239. /* Assume not off hook on CVRS */
  2240. res = 0;
  2241. par.rxisoffhook = 0;
  2242. }
  2243. if (res) {
  2244. ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
  2245. }
  2246. if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
  2247. /* When "onhook" that means no battery on the line, and thus
  2248. it is out of service..., if it's on a TDM card... If it's a channel
  2249. bank, there is no telling... */
  2250. return (par.rxbits > -1) || par.rxisoffhook;
  2251. }
  2252. return par.rxisoffhook;
  2253. }
  2254. static int my_set_echocanceller(void *pvt, int enable)
  2255. {
  2256. struct dahdi_pvt *p = pvt;
  2257. if (enable)
  2258. dahdi_ec_enable(p);
  2259. else
  2260. dahdi_ec_disable(p);
  2261. return 0;
  2262. }
  2263. static int dahdi_ring_phone(struct dahdi_pvt *p);
  2264. static int my_ring(void *pvt)
  2265. {
  2266. struct dahdi_pvt *p = pvt;
  2267. return dahdi_ring_phone(p);
  2268. }
  2269. static int my_flash(void *pvt)
  2270. {
  2271. struct dahdi_pvt *p = pvt;
  2272. int func = DAHDI_FLASH;
  2273. return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
  2274. }
  2275. static inline int dahdi_set_hook(int fd, int hs);
  2276. static int my_off_hook(void *pvt)
  2277. {
  2278. struct dahdi_pvt *p = pvt;
  2279. return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  2280. }
  2281. static void my_set_needringing(void *pvt, int value)
  2282. {
  2283. struct dahdi_pvt *p = pvt;
  2284. p->subs[SUB_REAL].needringing = value;
  2285. }
  2286. static void my_set_polarity(void *pvt, int value)
  2287. {
  2288. struct dahdi_pvt *p = pvt;
  2289. if (p->channel == CHAN_PSEUDO) {
  2290. return;
  2291. }
  2292. p->polarity = value;
  2293. ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
  2294. }
  2295. static void my_start_polarityswitch(void *pvt)
  2296. {
  2297. struct dahdi_pvt *p = pvt;
  2298. if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
  2299. my_set_polarity(pvt, 0);
  2300. }
  2301. }
  2302. static void my_answer_polarityswitch(void *pvt)
  2303. {
  2304. struct dahdi_pvt *p = pvt;
  2305. if (!p->answeronpolarityswitch) {
  2306. return;
  2307. }
  2308. my_set_polarity(pvt, 1);
  2309. }
  2310. static void my_hangup_polarityswitch(void *pvt)
  2311. {
  2312. struct dahdi_pvt *p = pvt;
  2313. if (!p->hanguponpolarityswitch) {
  2314. return;
  2315. }
  2316. if (p->answeronpolarityswitch) {
  2317. my_set_polarity(pvt, 0);
  2318. } else {
  2319. my_set_polarity(pvt, 1);
  2320. }
  2321. }
  2322. static int my_start(void *pvt)
  2323. {
  2324. struct dahdi_pvt *p = pvt;
  2325. int x = DAHDI_START;
  2326. return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  2327. }
  2328. static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
  2329. {
  2330. struct dahdi_pvt *p = pvt;
  2331. if (dop->op != ANALOG_DIAL_OP_REPLACE) {
  2332. ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
  2333. return -1;
  2334. }
  2335. if (sub != ANALOG_SUB_REAL) {
  2336. ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %u\n",
  2337. dop->dialstr, p->channel, sub);
  2338. return -1;
  2339. }
  2340. return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr);
  2341. }
  2342. static void dahdi_train_ec(struct dahdi_pvt *p);
  2343. static int my_train_echocanceller(void *pvt)
  2344. {
  2345. struct dahdi_pvt *p = pvt;
  2346. dahdi_train_ec(p);
  2347. return 0;
  2348. }
  2349. static int my_is_dialing(void *pvt, enum analog_sub sub)
  2350. {
  2351. struct dahdi_pvt *p = pvt;
  2352. int index;
  2353. int x;
  2354. index = analogsub_to_dahdisub(sub);
  2355. if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
  2356. ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
  2357. return -1;
  2358. }
  2359. return x;
  2360. }
  2361. static int my_on_hook(void *pvt)
  2362. {
  2363. struct dahdi_pvt *p = pvt;
  2364. return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
  2365. }
  2366. #if defined(HAVE_PRI)
  2367. static void my_pri_fixup_chans(void *chan_old, void *chan_new)
  2368. {
  2369. struct dahdi_pvt *old_chan = chan_old;
  2370. struct dahdi_pvt *new_chan = chan_new;
  2371. new_chan->owner = old_chan->owner;
  2372. old_chan->owner = NULL;
  2373. if (new_chan->owner) {
  2374. ast_channel_tech_pvt_set(new_chan->owner, new_chan);
  2375. ast_channel_internal_fd_set(new_chan->owner, 0, new_chan->subs[SUB_REAL].dfd);
  2376. new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
  2377. old_chan->subs[SUB_REAL].owner = NULL;
  2378. }
  2379. /* Copy any DSP that may be present */
  2380. new_chan->dsp = old_chan->dsp;
  2381. new_chan->dsp_features = old_chan->dsp_features;
  2382. old_chan->dsp = NULL;
  2383. old_chan->dsp_features = 0;
  2384. /* Transfer flags from the old channel. */
  2385. new_chan->dialing = old_chan->dialing;
  2386. new_chan->digital = old_chan->digital;
  2387. new_chan->outgoing = old_chan->outgoing;
  2388. old_chan->dialing = 0;
  2389. old_chan->digital = 0;
  2390. old_chan->outgoing = 0;
  2391. /* More stuff to transfer to the new channel. */
  2392. new_chan->law = old_chan->law;
  2393. strcpy(new_chan->dialstring, old_chan->dialstring);
  2394. }
  2395. #endif /* defined(HAVE_PRI) */
  2396. #if defined(HAVE_PRI)
  2397. static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
  2398. {
  2399. switch (tone) {
  2400. case SIG_PRI_TONE_RINGTONE:
  2401. return DAHDI_TONE_RINGTONE;
  2402. case SIG_PRI_TONE_STUTTER:
  2403. return DAHDI_TONE_STUTTER;
  2404. case SIG_PRI_TONE_CONGESTION:
  2405. return DAHDI_TONE_CONGESTION;
  2406. case SIG_PRI_TONE_DIALTONE:
  2407. return DAHDI_TONE_DIALTONE;
  2408. case SIG_PRI_TONE_DIALRECALL:
  2409. return DAHDI_TONE_DIALRECALL;
  2410. case SIG_PRI_TONE_INFO:
  2411. return DAHDI_TONE_INFO;
  2412. case SIG_PRI_TONE_BUSY:
  2413. return DAHDI_TONE_BUSY;
  2414. default:
  2415. return -1;
  2416. }
  2417. }
  2418. #endif /* defined(HAVE_PRI) */
  2419. #if defined(HAVE_PRI)
  2420. static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
  2421. {
  2422. int x;
  2423. ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
  2424. switch (x) {
  2425. case DAHDI_EVENT_NONE:
  2426. break;
  2427. case DAHDI_EVENT_ALARM:
  2428. case DAHDI_EVENT_NOALARM:
  2429. if (sig_pri_is_alarm_ignored(pri)) {
  2430. break;
  2431. }
  2432. /* Fall through */
  2433. default:
  2434. ast_log(LOG_NOTICE, "Got DAHDI event: %s (%d) on D-channel of span %d\n",
  2435. event2str(x), x, pri->span);
  2436. break;
  2437. }
  2438. /* Keep track of alarm state */
  2439. switch (x) {
  2440. case DAHDI_EVENT_ALARM:
  2441. pri_event_alarm(pri, index, 0);
  2442. break;
  2443. case DAHDI_EVENT_NOALARM:
  2444. pri_event_noalarm(pri, index, 0);
  2445. break;
  2446. case DAHDI_EVENT_REMOVED:
  2447. pri_queue_for_destruction(pri);
  2448. break;
  2449. default:
  2450. break;
  2451. }
  2452. }
  2453. #endif /* defined(HAVE_PRI) */
  2454. #if defined(HAVE_PRI)
  2455. static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
  2456. {
  2457. struct dahdi_pvt *p = pvt;
  2458. return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
  2459. }
  2460. #endif /* defined(HAVE_PRI) */
  2461. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  2462. /*!
  2463. * \internal
  2464. * \brief Set the caller id information.
  2465. * \since 1.8
  2466. *
  2467. * \param pvt DAHDI private structure
  2468. * \param caller Caller-id information to set.
  2469. *
  2470. * \return Nothing
  2471. */
  2472. static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
  2473. {
  2474. struct dahdi_pvt *p = pvt;
  2475. ast_copy_string(p->cid_num,
  2476. S_COR(caller->id.number.valid, caller->id.number.str, ""),
  2477. sizeof(p->cid_num));
  2478. ast_copy_string(p->cid_name,
  2479. S_COR(caller->id.name.valid, caller->id.name.str, ""),
  2480. sizeof(p->cid_name));
  2481. ast_copy_string(p->cid_subaddr,
  2482. S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
  2483. sizeof(p->cid_subaddr));
  2484. p->cid_ton = caller->id.number.plan;
  2485. p->callingpres = ast_party_id_presentation(&caller->id);
  2486. if (caller->id.tag) {
  2487. ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
  2488. }
  2489. ast_copy_string(p->cid_ani,
  2490. S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
  2491. sizeof(p->cid_ani));
  2492. p->cid_ani2 = caller->ani2;
  2493. }
  2494. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  2495. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  2496. /*!
  2497. * \internal
  2498. * \brief Set the Dialed Number Identifier.
  2499. * \since 1.8
  2500. *
  2501. * \param pvt DAHDI private structure
  2502. * \param dnid Dialed Number Identifier string.
  2503. *
  2504. * \return Nothing
  2505. */
  2506. static void my_set_dnid(void *pvt, const char *dnid)
  2507. {
  2508. struct dahdi_pvt *p = pvt;
  2509. ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
  2510. }
  2511. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  2512. #if defined(HAVE_PRI)
  2513. /*!
  2514. * \internal
  2515. * \brief Set the Redirecting Directory Number Information Service (RDNIS).
  2516. * \since 1.8
  2517. *
  2518. * \param pvt DAHDI private structure
  2519. * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
  2520. *
  2521. * \return Nothing
  2522. */
  2523. static void my_set_rdnis(void *pvt, const char *rdnis)
  2524. {
  2525. struct dahdi_pvt *p = pvt;
  2526. ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
  2527. }
  2528. #endif /* defined(HAVE_PRI) */
  2529. #if defined(HAVE_PRI)
  2530. /*!
  2531. * \internal
  2532. * \brief Make a dialstring for native ISDN CC to recall properly.
  2533. * \since 1.8
  2534. *
  2535. * \param priv Channel private control structure.
  2536. * \param buf Where to put the modified dialstring.
  2537. * \param buf_size Size of modified dialstring buffer.
  2538. *
  2539. * \details
  2540. * original dialstring:
  2541. * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
  2542. *
  2543. * The modified dialstring will have prefixed the channel-group section
  2544. * with the ISDN channel restriction.
  2545. *
  2546. * buf:
  2547. * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
  2548. *
  2549. * The routine will check to see if the ISDN channel restriction is already
  2550. * in the original dialstring.
  2551. *
  2552. * \return Nothing
  2553. */
  2554. static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
  2555. {
  2556. char *dial;
  2557. struct dahdi_pvt *pvt;
  2558. AST_DECLARE_APP_ARGS(args,
  2559. AST_APP_ARG(tech); /* channel technology token */
  2560. AST_APP_ARG(group); /* channel/group token */
  2561. //AST_APP_ARG(ext); /* extension token */
  2562. //AST_APP_ARG(opts); /* options token */
  2563. //AST_APP_ARG(other); /* Any remining unused arguments */
  2564. );
  2565. pvt = priv;
  2566. dial = ast_strdupa(pvt->dialstring);
  2567. AST_NONSTANDARD_APP_ARGS(args, dial, '/');
  2568. if (!args.tech) {
  2569. ast_copy_string(buf, pvt->dialstring, buf_size);
  2570. return;
  2571. }
  2572. if (!args.group) {
  2573. /* Append the ISDN span channel restriction to the dialstring. */
  2574. snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
  2575. return;
  2576. }
  2577. if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
  2578. /* The ISDN span channel restriction is not needed or already
  2579. * in the dialstring. */
  2580. ast_copy_string(buf, pvt->dialstring, buf_size);
  2581. return;
  2582. }
  2583. /* Insert the ISDN span channel restriction into the dialstring. */
  2584. snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
  2585. }
  2586. #endif /* defined(HAVE_PRI) */
  2587. #if defined(HAVE_PRI)
  2588. /*!
  2589. * \internal
  2590. * \brief Reevaluate the PRI span device state.
  2591. * \since 1.8
  2592. *
  2593. * \param pri Asterisk D channel control structure.
  2594. *
  2595. * \return Nothing
  2596. *
  2597. * \note Assumes the pri->lock is already obtained.
  2598. */
  2599. static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
  2600. {
  2601. unsigned idx;
  2602. unsigned num_b_chans; /* Number of B channels provisioned on the span. */
  2603. unsigned in_use; /* Number of B channels in use on the span. */
  2604. unsigned in_alarm; /* TRUE if the span is in alarm condition. */
  2605. enum ast_device_state new_state;
  2606. /* Count the number of B channels and the number of B channels in use. */
  2607. num_b_chans = 0;
  2608. in_use = 0;
  2609. in_alarm = 1;
  2610. for (idx = pri->numchans; idx--;) {
  2611. if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
  2612. /* This is a B channel interface. */
  2613. ++num_b_chans;
  2614. if (!sig_pri_is_chan_available(pri->pvts[idx])) {
  2615. ++in_use;
  2616. }
  2617. if (!pri->pvts[idx]->inalarm) {
  2618. /* There is a channel that is not in alarm. */
  2619. in_alarm = 0;
  2620. }
  2621. }
  2622. }
  2623. /* Update the span congestion device state and report any change. */
  2624. if (in_alarm) {
  2625. new_state = AST_DEVICE_UNAVAILABLE;
  2626. } else {
  2627. new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
  2628. }
  2629. if (pri->congestion_devstate != new_state) {
  2630. pri->congestion_devstate = new_state;
  2631. ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
  2632. }
  2633. #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
  2634. /* Update the span threshold device state and report any change. */
  2635. if (in_alarm) {
  2636. new_state = AST_DEVICE_UNAVAILABLE;
  2637. } else if (!in_use) {
  2638. new_state = AST_DEVICE_NOT_INUSE;
  2639. } else if (!pri->user_busy_threshold) {
  2640. new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
  2641. } else {
  2642. new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
  2643. : AST_DEVICE_BUSY;
  2644. }
  2645. if (pri->threshold_devstate != new_state) {
  2646. pri->threshold_devstate = new_state;
  2647. ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
  2648. }
  2649. #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
  2650. }
  2651. #endif /* defined(HAVE_PRI) */
  2652. #if defined(HAVE_PRI)
  2653. /*!
  2654. * \internal
  2655. * \brief Reference this module.
  2656. * \since 1.8
  2657. *
  2658. * \return Nothing
  2659. */
  2660. static void my_module_ref(void)
  2661. {
  2662. ast_module_ref(ast_module_info->self);
  2663. }
  2664. #endif /* defined(HAVE_PRI) */
  2665. #if defined(HAVE_PRI)
  2666. /*!
  2667. * \internal
  2668. * \brief Unreference this module.
  2669. * \since 1.8
  2670. *
  2671. * \return Nothing
  2672. */
  2673. static void my_module_unref(void)
  2674. {
  2675. ast_module_unref(ast_module_info->self);
  2676. }
  2677. #endif /* defined(HAVE_PRI) */
  2678. #if defined(HAVE_PRI)
  2679. #if defined(HAVE_PRI_CALL_WAITING)
  2680. static void my_pri_init_config(void *priv, struct sig_pri_span *pri);
  2681. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  2682. static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri);
  2683. struct sig_pri_callback sig_pri_callbacks =
  2684. {
  2685. .handle_dchan_exception = my_handle_dchan_exception,
  2686. .play_tone = my_pri_play_tone,
  2687. .set_echocanceller = my_set_echocanceller,
  2688. .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
  2689. .lock_private = my_lock_private,
  2690. .unlock_private = my_unlock_private,
  2691. .deadlock_avoidance_private = my_deadlock_avoidance_private,
  2692. .new_ast_channel = my_new_pri_ast_channel,
  2693. .fixup_chans = my_pri_fixup_chans,
  2694. .set_alarm = my_set_alarm,
  2695. .set_dialing = my_set_dialing,
  2696. .set_outgoing = my_set_outgoing,
  2697. .set_digital = my_set_digital,
  2698. .set_callerid = my_set_callerid,
  2699. .set_dnid = my_set_dnid,
  2700. .set_rdnis = my_set_rdnis,
  2701. .new_nobch_intf = dahdi_new_pri_nobch_channel,
  2702. #if defined(HAVE_PRI_CALL_WAITING)
  2703. .init_config = my_pri_init_config,
  2704. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  2705. .get_orig_dialstring = my_get_orig_dialstring,
  2706. .make_cc_dialstring = my_pri_make_cc_dialstring,
  2707. .update_span_devstate = dahdi_pri_update_span_devstate,
  2708. .module_ref = my_module_ref,
  2709. .module_unref = my_module_unref,
  2710. .dial_digits = my_pri_dial_digits,
  2711. .open_media = my_pri_ss7_open_media,
  2712. .ami_channel_event = my_ami_channel_event,
  2713. .destroy_later = pri_queue_for_destruction,
  2714. };
  2715. #endif /* defined(HAVE_PRI) */
  2716. #if defined(HAVE_SS7)
  2717. /*!
  2718. * \internal
  2719. * \brief Handle the SS7 link exception.
  2720. * \since 1.8
  2721. *
  2722. * \param linkset Controlling linkset for the channel.
  2723. * \param which Link index of the signaling channel.
  2724. *
  2725. * \return Nothing
  2726. */
  2727. static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
  2728. {
  2729. int event;
  2730. if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
  2731. ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
  2732. linkset->span, which);
  2733. return;
  2734. }
  2735. switch (event) {
  2736. case DAHDI_EVENT_NONE:
  2737. break;
  2738. case DAHDI_EVENT_ALARM:
  2739. ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
  2740. event2str(event), event, linkset->span, which);
  2741. sig_ss7_link_alarm(linkset, which);
  2742. break;
  2743. case DAHDI_EVENT_NOALARM:
  2744. ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
  2745. event2str(event), event, linkset->span, which);
  2746. sig_ss7_link_noalarm(linkset, which);
  2747. break;
  2748. default:
  2749. ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
  2750. event2str(event), event, linkset->span, which);
  2751. break;
  2752. }
  2753. }
  2754. #endif /* defined(HAVE_SS7) */
  2755. #if defined(HAVE_SS7)
  2756. static void my_ss7_set_loopback(void *pvt, int enable)
  2757. {
  2758. struct dahdi_pvt *p = pvt;
  2759. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
  2760. ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
  2761. strerror(errno));
  2762. }
  2763. }
  2764. #endif /* defined(HAVE_SS7) */
  2765. #if defined(HAVE_SS7)
  2766. /*!
  2767. * \internal
  2768. * \brief Find the linkset to which SS7 belongs.
  2769. * \since 11.0
  2770. *
  2771. * \param ss7 structure to match on.
  2772. *
  2773. * \retval linkset if found.
  2774. * \retval NULL if not found.
  2775. */
  2776. static struct sig_ss7_linkset *my_ss7_find_linkset(struct ss7 *ss7)
  2777. {
  2778. int idx;
  2779. if (!ss7) {
  2780. return NULL;
  2781. }
  2782. for (idx = 0; idx < NUM_SPANS; ++idx) {
  2783. if (linksets[idx].ss7.ss7 == ss7) {
  2784. return &linksets[idx].ss7;
  2785. }
  2786. }
  2787. return NULL;
  2788. }
  2789. #endif /* defined(HAVE_SS7) */
  2790. #if defined(HAVE_SS7)
  2791. /*!
  2792. * \internal
  2793. * \brief Create a new asterisk channel structure for SS7.
  2794. * \since 1.8
  2795. *
  2796. * \param pvt Private channel structure.
  2797. * \param state Initial state of new channel.
  2798. * \param law Combanding law to use.
  2799. * \param exten Dialplan extension for incoming call.
  2800. * \param requestor Channel requesting this new channel.
  2801. *
  2802. * \retval ast_channel on success.
  2803. * \retval NULL on error.
  2804. */
  2805. static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
  2806. {
  2807. struct dahdi_pvt *p = pvt;
  2808. int audio;
  2809. int newlaw;
  2810. struct ast_callid *callid = NULL;
  2811. int callid_created = ast_callid_threadstorage_auto(&callid);
  2812. /* Set to audio mode at this point */
  2813. audio = 1;
  2814. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
  2815. ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
  2816. p->channel, audio, strerror(errno));
  2817. if (law != SIG_SS7_DEFLAW) {
  2818. dahdi_setlaw(p->subs[SUB_REAL].dfd,
  2819. (law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
  2820. }
  2821. ast_copy_string(p->exten, exten, sizeof(p->exten));
  2822. newlaw = -1;
  2823. switch (law) {
  2824. case SIG_SS7_DEFLAW:
  2825. newlaw = 0;
  2826. break;
  2827. case SIG_SS7_ALAW:
  2828. newlaw = DAHDI_LAW_ALAW;
  2829. break;
  2830. case SIG_SS7_ULAW:
  2831. newlaw = DAHDI_LAW_MULAW;
  2832. break;
  2833. }
  2834. return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
  2835. }
  2836. #endif /* defined(HAVE_SS7) */
  2837. #if defined(HAVE_SS7)
  2838. static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
  2839. {
  2840. switch (tone) {
  2841. case SIG_SS7_TONE_RINGTONE:
  2842. return DAHDI_TONE_RINGTONE;
  2843. case SIG_SS7_TONE_STUTTER:
  2844. return DAHDI_TONE_STUTTER;
  2845. case SIG_SS7_TONE_CONGESTION:
  2846. return DAHDI_TONE_CONGESTION;
  2847. case SIG_SS7_TONE_DIALTONE:
  2848. return DAHDI_TONE_DIALTONE;
  2849. case SIG_SS7_TONE_DIALRECALL:
  2850. return DAHDI_TONE_DIALRECALL;
  2851. case SIG_SS7_TONE_INFO:
  2852. return DAHDI_TONE_INFO;
  2853. case SIG_SS7_TONE_BUSY:
  2854. return DAHDI_TONE_BUSY;
  2855. default:
  2856. return -1;
  2857. }
  2858. }
  2859. #endif /* defined(HAVE_SS7) */
  2860. #if defined(HAVE_SS7)
  2861. static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
  2862. {
  2863. struct dahdi_pvt *p = pvt;
  2864. return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
  2865. }
  2866. #endif /* defined(HAVE_SS7) */
  2867. #if defined(HAVE_SS7)
  2868. struct sig_ss7_callback sig_ss7_callbacks =
  2869. {
  2870. .lock_private = my_lock_private,
  2871. .unlock_private = my_unlock_private,
  2872. .deadlock_avoidance_private = my_deadlock_avoidance_private,
  2873. .set_echocanceller = my_set_echocanceller,
  2874. .set_loopback = my_ss7_set_loopback,
  2875. .new_ast_channel = my_new_ss7_ast_channel,
  2876. .play_tone = my_ss7_play_tone,
  2877. .handle_link_exception = my_handle_link_exception,
  2878. .set_alarm = my_set_alarm,
  2879. .set_dialing = my_set_dialing,
  2880. .set_outgoing = my_set_outgoing,
  2881. .set_digital = my_set_digital,
  2882. .set_inservice = my_set_inservice,
  2883. .set_locallyblocked = my_set_locallyblocked,
  2884. .set_remotelyblocked = my_set_remotelyblocked,
  2885. .set_callerid = my_set_callerid,
  2886. .set_dnid = my_set_dnid,
  2887. .open_media = my_pri_ss7_open_media,
  2888. .find_linkset = my_ss7_find_linkset,
  2889. };
  2890. #endif /* defined(HAVE_SS7) */
  2891. /*!
  2892. * \brief Send MWI state change
  2893. *
  2894. * \param mailbox This is the mailbox associated with the FXO line that the
  2895. * MWI state has changed on.
  2896. * \param thereornot This argument should simply be set to 1 or 0, to indicate
  2897. * whether there are messages waiting or not.
  2898. *
  2899. * \return nothing
  2900. *
  2901. * This function does two things:
  2902. *
  2903. * 1) It generates an internal Asterisk event notifying any other module that
  2904. * cares about MWI that the state of a mailbox has changed.
  2905. *
  2906. * 2) It runs the script specified by the mwimonitornotify option to allow
  2907. * some custom handling of the state change.
  2908. */
  2909. static void notify_message(char *mailbox, int thereornot)
  2910. {
  2911. char s[sizeof(mwimonitornotify) + 80];
  2912. if (ast_strlen_zero(mailbox)) {
  2913. return;
  2914. }
  2915. ast_publish_mwi_state(mailbox, NULL, thereornot, thereornot);
  2916. if (!ast_strlen_zero(mwimonitornotify)) {
  2917. snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
  2918. ast_safe_system(s);
  2919. }
  2920. }
  2921. static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
  2922. {
  2923. struct dahdi_pvt *p = pvt;
  2924. if (neon_mwievent > -1 && !p->mwimonitor_neon)
  2925. return;
  2926. if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
  2927. ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
  2928. notify_message(p->mailbox, 1);
  2929. } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
  2930. ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
  2931. notify_message(p->mailbox, 0);
  2932. }
  2933. /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
  2934. /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
  2935. if (neon_mwievent == -1 && p->mwimonitor_rpas) {
  2936. ast_hangup(chan);
  2937. return;
  2938. }
  2939. }
  2940. static int my_have_progressdetect(void *pvt)
  2941. {
  2942. struct dahdi_pvt *p = pvt;
  2943. if ((p->callprogress & CALLPROGRESS_PROGRESS)
  2944. && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
  2945. return 1;
  2946. } else {
  2947. /* Don't have progress detection. */
  2948. return 0;
  2949. }
  2950. }
  2951. struct analog_callback analog_callbacks =
  2952. {
  2953. .play_tone = my_play_tone,
  2954. .get_event = my_get_event,
  2955. .wait_event = my_wait_event,
  2956. .is_off_hook = my_is_off_hook,
  2957. .set_echocanceller = my_set_echocanceller,
  2958. .ring = my_ring,
  2959. .flash = my_flash,
  2960. .off_hook = my_off_hook,
  2961. .dial_digits = my_dial_digits,
  2962. .train_echocanceller = my_train_echocanceller,
  2963. .on_hook = my_on_hook,
  2964. .is_dialing = my_is_dialing,
  2965. .allocate_sub = my_allocate_sub,
  2966. .unallocate_sub = my_unallocate_sub,
  2967. .swap_subs = my_swap_subchannels,
  2968. .has_voicemail = my_has_voicemail,
  2969. .check_for_conference = my_check_for_conference,
  2970. .conf_add = my_conf_add,
  2971. .conf_del = my_conf_del,
  2972. .complete_conference_update = my_complete_conference_update,
  2973. .start = my_start,
  2974. .all_subchannels_hungup = my_all_subchannels_hungup,
  2975. .lock_private = my_lock_private,
  2976. .unlock_private = my_unlock_private,
  2977. .deadlock_avoidance_private = my_deadlock_avoidance_private,
  2978. .handle_dtmf = my_handle_dtmf,
  2979. .wink = my_wink,
  2980. .new_ast_channel = my_new_analog_ast_channel,
  2981. .dsp_set_digitmode = my_dsp_set_digitmode,
  2982. .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
  2983. .send_callerid = my_send_callerid,
  2984. .callwait = my_callwait,
  2985. .stop_callwait = my_stop_callwait,
  2986. .get_callerid = my_get_callerid,
  2987. .start_cid_detect = my_start_cid_detect,
  2988. .stop_cid_detect = my_stop_cid_detect,
  2989. .handle_notify_message = my_handle_notify_message,
  2990. .increase_ss_count = my_increase_ss_count,
  2991. .decrease_ss_count = my_decrease_ss_count,
  2992. .distinctive_ring = my_distinctive_ring,
  2993. .set_linear_mode = my_set_linear_mode,
  2994. .set_inthreeway = my_set_inthreeway,
  2995. .get_and_handle_alarms = my_get_and_handle_alarms,
  2996. .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
  2997. .get_sub_fd = my_get_sub_fd,
  2998. .set_cadence = my_set_cadence,
  2999. .set_alarm = my_set_alarm,
  3000. .set_dialing = my_set_dialing,
  3001. .set_outgoing = my_set_outgoing,
  3002. .set_ringtimeout = my_set_ringtimeout,
  3003. .set_waitingfordt = my_set_waitingfordt,
  3004. .check_waitingfordt = my_check_waitingfordt,
  3005. .set_confirmanswer = my_set_confirmanswer,
  3006. .check_confirmanswer = my_check_confirmanswer,
  3007. .set_callwaiting = my_set_callwaiting,
  3008. .cancel_cidspill = my_cancel_cidspill,
  3009. .confmute = my_confmute,
  3010. .set_pulsedial = my_set_pulsedial,
  3011. .set_new_owner = my_set_new_owner,
  3012. .get_orig_dialstring = my_get_orig_dialstring,
  3013. .set_needringing = my_set_needringing,
  3014. .set_polarity = my_set_polarity,
  3015. .start_polarityswitch = my_start_polarityswitch,
  3016. .answer_polarityswitch = my_answer_polarityswitch,
  3017. .hangup_polarityswitch = my_hangup_polarityswitch,
  3018. .have_progressdetect = my_have_progressdetect,
  3019. };
  3020. /*! Round robin search locations. */
  3021. static struct dahdi_pvt *round_robin[32];
  3022. int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
  3023. {
  3024. int res;
  3025. if (p->subs[SUB_REAL].owner == ast)
  3026. res = 0;
  3027. else if (p->subs[SUB_CALLWAIT].owner == ast)
  3028. res = 1;
  3029. else if (p->subs[SUB_THREEWAY].owner == ast)
  3030. res = 2;
  3031. else {
  3032. res = -1;
  3033. if (!nullok)
  3034. ast_log(LOG_WARNING,
  3035. "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
  3036. ast ? ast_channel_name(ast) : "", p->channel, fname, line);
  3037. }
  3038. return res;
  3039. }
  3040. /*!
  3041. * \internal
  3042. * \brief Obtain the specified subchannel owner lock if the owner exists.
  3043. *
  3044. * \param pvt Channel private struct.
  3045. * \param sub_idx Subchannel owner to lock.
  3046. *
  3047. * \note Assumes the pvt->lock is already obtained.
  3048. *
  3049. * \note
  3050. * Because deadlock avoidance may have been necessary, you need to confirm
  3051. * the state of things before continuing.
  3052. *
  3053. * \return Nothing
  3054. */
  3055. static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
  3056. {
  3057. for (;;) {
  3058. if (!pvt->subs[sub_idx].owner) {
  3059. /* No subchannel owner pointer */
  3060. break;
  3061. }
  3062. if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
  3063. /* Got subchannel owner lock */
  3064. break;
  3065. }
  3066. /* We must unlock the private to avoid the possibility of a deadlock */
  3067. DEADLOCK_AVOIDANCE(&pvt->lock);
  3068. }
  3069. }
  3070. static void wakeup_sub(struct dahdi_pvt *p, int a)
  3071. {
  3072. dahdi_lock_sub_owner(p, a);
  3073. if (p->subs[a].owner) {
  3074. ast_queue_frame(p->subs[a].owner, &ast_null_frame);
  3075. ast_channel_unlock(p->subs[a].owner);
  3076. }
  3077. }
  3078. static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
  3079. {
  3080. for (;;) {
  3081. if (p->owner) {
  3082. if (ast_channel_trylock(p->owner)) {
  3083. DEADLOCK_AVOIDANCE(&p->lock);
  3084. } else {
  3085. ast_queue_frame(p->owner, f);
  3086. ast_channel_unlock(p->owner);
  3087. break;
  3088. }
  3089. } else
  3090. break;
  3091. }
  3092. }
  3093. static void publish_channel_alarm_clear(int channel)
  3094. {
  3095. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  3096. RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
  3097. if (!dahdi_chan) {
  3098. return;
  3099. }
  3100. ast_str_set(&dahdi_chan, 0, "%d", channel);
  3101. ast_log(LOG_NOTICE, "Alarm cleared on channel DAHDI/%d\n", channel);
  3102. body = ast_json_pack("{s: s}", "DAHDIChannel", ast_str_buffer(dahdi_chan));
  3103. if (!body) {
  3104. return;
  3105. }
  3106. ast_manager_publish_event("AlarmClear", EVENT_FLAG_SYSTEM, body);
  3107. }
  3108. static void publish_span_alarm_clear(int span)
  3109. {
  3110. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  3111. ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", span);
  3112. body = ast_json_pack("{s: i}", "Span", span);
  3113. if (!body) {
  3114. return;
  3115. }
  3116. ast_manager_publish_event("SpanAlarmClear", EVENT_FLAG_SYSTEM, body);
  3117. }
  3118. static void handle_clear_alarms(struct dahdi_pvt *p)
  3119. {
  3120. #if defined(HAVE_PRI)
  3121. if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) {
  3122. return;
  3123. }
  3124. #endif /* defined(HAVE_PRI) */
  3125. if (report_alarms & REPORT_CHANNEL_ALARMS) {
  3126. publish_channel_alarm_clear(p->channel);
  3127. }
  3128. if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
  3129. publish_span_alarm_clear(p->span);
  3130. }
  3131. }
  3132. #ifdef HAVE_OPENR2
  3133. static int dahdi_r2_answer(struct dahdi_pvt *p)
  3134. {
  3135. int res = 0;
  3136. /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
  3137. * and does not has support for openr2_chan_answer_call_with_mode
  3138. * */
  3139. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  3140. const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
  3141. int wants_double_answer = ast_true(double_answer) ? 1 : 0;
  3142. if (!double_answer) {
  3143. /* this still can result in double answer if the channel context
  3144. * was configured that way */
  3145. res = openr2_chan_answer_call(p->r2chan);
  3146. } else if (wants_double_answer) {
  3147. res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
  3148. } else {
  3149. res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
  3150. }
  3151. #else
  3152. res = openr2_chan_answer_call(p->r2chan);
  3153. #endif
  3154. return res;
  3155. }
  3156. /* should be called with the ast_channel locked */
  3157. static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
  3158. {
  3159. openr2_calling_party_category_t cat;
  3160. const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
  3161. struct dahdi_pvt *p = ast_channel_tech_pvt(c);
  3162. if (ast_strlen_zero(catstr)) {
  3163. ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
  3164. ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
  3165. return p->mfcr2_category;
  3166. }
  3167. if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
  3168. ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
  3169. catstr, ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
  3170. return p->mfcr2_category;
  3171. }
  3172. ast_debug(1, "Using category %s\n", catstr);
  3173. return cat;
  3174. }
  3175. static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
  3176. {
  3177. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3178. ast_mutex_lock(&p->lock);
  3179. if (p->mfcr2call) {
  3180. ast_mutex_unlock(&p->lock);
  3181. /* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
  3182. interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
  3183. can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
  3184. the other end will see our seize as a forced release and drop the call, we will see an invalid
  3185. pattern that will be seen and treated as protocol error. */
  3186. ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
  3187. return;
  3188. }
  3189. p->mfcr2call = 1;
  3190. /* better safe than sorry ... */
  3191. p->cid_name[0] = '\0';
  3192. p->cid_num[0] = '\0';
  3193. p->cid_subaddr[0] = '\0';
  3194. p->rdnis[0] = '\0';
  3195. p->exten[0] = '\0';
  3196. p->mfcr2_ani_index = '\0';
  3197. p->mfcr2_dnis_index = '\0';
  3198. p->mfcr2_dnis_matched = 0;
  3199. p->mfcr2_answer_pending = 0;
  3200. p->mfcr2_call_accepted = 0;
  3201. ast_mutex_unlock(&p->lock);
  3202. ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
  3203. }
  3204. static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
  3205. {
  3206. int res;
  3207. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3208. ast_mutex_lock(&p->lock);
  3209. p->inalarm = alarm ? 1 : 0;
  3210. if (p->inalarm) {
  3211. res = get_alarms(p);
  3212. handle_alarms(p, res);
  3213. } else {
  3214. handle_clear_alarms(p);
  3215. }
  3216. ast_mutex_unlock(&p->lock);
  3217. }
  3218. static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
  3219. {
  3220. ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
  3221. }
  3222. static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
  3223. {
  3224. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3225. ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
  3226. if (p->owner) {
  3227. ast_channel_hangupcause_set(p->owner, AST_CAUSE_PROTOCOL_ERROR);
  3228. ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
  3229. }
  3230. ast_mutex_lock(&p->lock);
  3231. p->mfcr2call = 0;
  3232. ast_mutex_unlock(&p->lock);
  3233. }
  3234. static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
  3235. {
  3236. if (openr2_chan_disconnect_call(p->r2chan, cause)) {
  3237. ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
  3238. p->channel, openr2_proto_get_disconnect_string(cause));
  3239. /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
  3240. openr2_chan_set_idle(p->r2chan);
  3241. ast_mutex_lock(&p->lock);
  3242. p->mfcr2call = 0;
  3243. ast_mutex_unlock(&p->lock);
  3244. }
  3245. }
  3246. static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
  3247. {
  3248. struct dahdi_pvt *p;
  3249. struct ast_channel *c;
  3250. struct ast_callid *callid = NULL;
  3251. int callid_created = ast_callid_threadstorage_auto(&callid);
  3252. ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
  3253. openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
  3254. openr2_proto_get_category_string(category));
  3255. p = openr2_chan_get_client_data(r2chan);
  3256. /* if collect calls are not allowed and this is a collect call, reject it! */
  3257. if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
  3258. ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
  3259. dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
  3260. goto dahdi_r2_on_call_offered_cleanup;
  3261. }
  3262. ast_mutex_lock(&p->lock);
  3263. p->mfcr2_recvd_category = category;
  3264. /* if we're not supposed to use CID, clear whatever we have */
  3265. if (!p->use_callerid) {
  3266. ast_debug(1, "No CID allowed in configuration, CID is being cleared!\n");
  3267. p->cid_num[0] = 0;
  3268. p->cid_name[0] = 0;
  3269. }
  3270. /* if we're supposed to answer immediately, clear DNIS and set 's' exten */
  3271. if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
  3272. ast_debug(1, "Setting exten => s because of immediate or 0 DNIS configured\n");
  3273. p->exten[0] = 's';
  3274. p->exten[1] = 0;
  3275. }
  3276. ast_mutex_unlock(&p->lock);
  3277. if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
  3278. ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
  3279. p->channel, p->exten, p->context);
  3280. dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
  3281. goto dahdi_r2_on_call_offered_cleanup;
  3282. }
  3283. if (!p->mfcr2_accept_on_offer) {
  3284. /* The user wants us to start the PBX thread right away without accepting the call first */
  3285. c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
  3286. if (c) {
  3287. /* Done here, don't disable reading now since we still need to generate MF tones to accept
  3288. the call or reject it and detect the tone off condition of the other end, all of this
  3289. will be done in the PBX thread now */
  3290. goto dahdi_r2_on_call_offered_cleanup;
  3291. }
  3292. ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
  3293. dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
  3294. } else if (p->mfcr2_charge_calls) {
  3295. ast_debug(1, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
  3296. openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
  3297. } else {
  3298. ast_debug(1, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
  3299. openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
  3300. }
  3301. dahdi_r2_on_call_offered_cleanup:
  3302. ast_callid_threadstorage_auto_clean(callid, callid_created);
  3303. }
  3304. static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
  3305. {
  3306. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3307. ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
  3308. ast_mutex_lock(&p->lock);
  3309. p->mfcr2call = 0;
  3310. ast_mutex_unlock(&p->lock);
  3311. }
  3312. static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
  3313. {
  3314. struct dahdi_pvt *p = NULL;
  3315. struct ast_channel *c = NULL;
  3316. struct ast_callid *callid = NULL;
  3317. int callid_created = ast_callid_threadstorage_auto(&callid);
  3318. p = openr2_chan_get_client_data(r2chan);
  3319. dahdi_ec_enable(p);
  3320. p->mfcr2_call_accepted = 1;
  3321. /* if it's an incoming call ... */
  3322. if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
  3323. ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
  3324. /* If accept on offer is not set, it means at this point the PBX thread is already
  3325. launched (was launched in the 'on call offered' handler) and therefore this callback
  3326. is being executed already in the PBX thread rather than the monitor thread, don't launch
  3327. any other thread, just disable the openr2 reading and answer the call if needed */
  3328. if (!p->mfcr2_accept_on_offer) {
  3329. openr2_chan_disable_read(r2chan);
  3330. if (p->mfcr2_answer_pending) {
  3331. ast_debug(1, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
  3332. dahdi_r2_answer(p);
  3333. }
  3334. goto dahdi_r2_on_call_accepted_cleanup;
  3335. }
  3336. c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
  3337. if (c) {
  3338. /* chan_dahdi will take care of reading from now on in the PBX thread, tell the
  3339. library to forget about it */
  3340. openr2_chan_disable_read(r2chan);
  3341. goto dahdi_r2_on_call_accepted_cleanup;
  3342. }
  3343. ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
  3344. /* failed to create the channel, bail out and report it as an out of order line */
  3345. dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
  3346. goto dahdi_r2_on_call_accepted_cleanup;
  3347. }
  3348. /* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
  3349. ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
  3350. p->subs[SUB_REAL].needringing = 1;
  3351. p->dialing = 0;
  3352. /* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
  3353. openr2_chan_disable_read(r2chan);
  3354. dahdi_r2_on_call_accepted_cleanup:
  3355. ast_callid_threadstorage_auto_clean(callid, callid_created);
  3356. }
  3357. static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
  3358. {
  3359. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3360. ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
  3361. p->subs[SUB_REAL].needanswer = 1;
  3362. }
  3363. static void dahdi_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
  3364. {
  3365. /*ast_debug(1, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/
  3366. }
  3367. static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
  3368. {
  3369. switch (cause) {
  3370. case OR2_CAUSE_BUSY_NUMBER:
  3371. return AST_CAUSE_BUSY;
  3372. case OR2_CAUSE_NETWORK_CONGESTION:
  3373. return AST_CAUSE_CONGESTION;
  3374. case OR2_CAUSE_OUT_OF_ORDER:
  3375. return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
  3376. case OR2_CAUSE_UNALLOCATED_NUMBER:
  3377. return AST_CAUSE_UNREGISTERED;
  3378. case OR2_CAUSE_NO_ANSWER:
  3379. return AST_CAUSE_NO_ANSWER;
  3380. case OR2_CAUSE_NORMAL_CLEARING:
  3381. return AST_CAUSE_NORMAL_CLEARING;
  3382. case OR2_CAUSE_UNSPECIFIED:
  3383. default:
  3384. return AST_CAUSE_NOTDEFINED;
  3385. }
  3386. }
  3387. static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
  3388. {
  3389. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3390. char cause_str[50];
  3391. struct ast_control_pvt_cause_code *cause_code;
  3392. int datalen = sizeof(*cause_code);
  3393. ast_verbose("MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
  3394. ast_mutex_lock(&p->lock);
  3395. if (!p->owner) {
  3396. ast_mutex_unlock(&p->lock);
  3397. /* no owner, therefore we can't use dahdi_hangup to disconnect, do it right now */
  3398. dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
  3399. return;
  3400. }
  3401. snprintf(cause_str, sizeof(cause_str), "R2 DISCONNECT (%s)", openr2_proto_get_disconnect_string(cause));
  3402. datalen += strlen(cause_str);
  3403. cause_code = ast_alloca(datalen);
  3404. memset(cause_code, 0, datalen);
  3405. cause_code->ast_cause = dahdi_r2_cause_to_ast_cause(cause);
  3406. ast_copy_string(cause_code->chan_name, ast_channel_name(p->owner), AST_CHANNEL_NAME);
  3407. ast_copy_string(cause_code->code, cause_str, datalen + 1 - sizeof(*cause_code));
  3408. ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
  3409. ast_channel_hangupcause_hash_set(p->owner, cause_code, datalen);
  3410. /* when we have an owner we don't call dahdi_r2_disconnect_call here, that will
  3411. be done in dahdi_hangup */
  3412. if (ast_channel_state(p->owner) == AST_STATE_UP) {
  3413. ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
  3414. ast_mutex_unlock(&p->lock);
  3415. } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
  3416. /* being the forward side we must report what happened to the call to whoever requested it */
  3417. switch (cause) {
  3418. case OR2_CAUSE_BUSY_NUMBER:
  3419. p->subs[SUB_REAL].needbusy = 1;
  3420. break;
  3421. case OR2_CAUSE_NETWORK_CONGESTION:
  3422. case OR2_CAUSE_OUT_OF_ORDER:
  3423. case OR2_CAUSE_UNALLOCATED_NUMBER:
  3424. case OR2_CAUSE_NO_ANSWER:
  3425. case OR2_CAUSE_UNSPECIFIED:
  3426. case OR2_CAUSE_NORMAL_CLEARING:
  3427. p->subs[SUB_REAL].needcongestion = 1;
  3428. break;
  3429. default:
  3430. ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
  3431. }
  3432. ast_mutex_unlock(&p->lock);
  3433. } else {
  3434. ast_mutex_unlock(&p->lock);
  3435. /* being the backward side and not UP yet, we only need to request hangup */
  3436. /* TODO: what about doing this same thing when were AST_STATE_UP? */
  3437. ast_queue_hangup_with_cause(p->owner, dahdi_r2_cause_to_ast_cause(cause));
  3438. }
  3439. }
  3440. static void dahdi_r2_write_log(openr2_log_level_t level, char *logmessage)
  3441. {
  3442. switch (level) {
  3443. case OR2_LOG_NOTICE:
  3444. ast_verbose("%s", logmessage);
  3445. break;
  3446. case OR2_LOG_WARNING:
  3447. ast_log(LOG_WARNING, "%s", logmessage);
  3448. break;
  3449. case OR2_LOG_ERROR:
  3450. ast_log(LOG_ERROR, "%s", logmessage);
  3451. break;
  3452. case OR2_LOG_STACK_TRACE:
  3453. case OR2_LOG_MF_TRACE:
  3454. case OR2_LOG_CAS_TRACE:
  3455. case OR2_LOG_DEBUG:
  3456. case OR2_LOG_EX_DEBUG:
  3457. ast_debug(1, "%s", logmessage);
  3458. break;
  3459. default:
  3460. ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level);
  3461. ast_debug(1, "%s", logmessage);
  3462. break;
  3463. }
  3464. }
  3465. static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
  3466. {
  3467. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3468. ast_mutex_lock(&p->lock);
  3469. p->remotelyblocked = 1;
  3470. ast_mutex_unlock(&p->lock);
  3471. ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
  3472. }
  3473. static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
  3474. {
  3475. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3476. ast_mutex_lock(&p->lock);
  3477. p->remotelyblocked = 0;
  3478. ast_mutex_unlock(&p->lock);
  3479. ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
  3480. }
  3481. static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
  3482. __attribute__((format (printf, 3, 0)));
  3483. static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
  3484. {
  3485. #define CONTEXT_TAG "Context - "
  3486. char logmsg[256];
  3487. char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1];
  3488. vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
  3489. snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg);
  3490. dahdi_r2_write_log(level, completemsg);
  3491. #undef CONTEXT_TAG
  3492. }
  3493. static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
  3494. __attribute__((format (printf, 3, 0)));
  3495. static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
  3496. {
  3497. #define CHAN_TAG "Chan "
  3498. char logmsg[256];
  3499. char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1];
  3500. vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
  3501. snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d - %s", openr2_chan_get_number(r2chan), logmsg);
  3502. dahdi_r2_write_log(level, completemsg);
  3503. }
  3504. static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
  3505. {
  3506. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3507. /* if 'immediate' is set, let's stop requesting DNIS */
  3508. if (p->immediate) {
  3509. return 0;
  3510. }
  3511. p->exten[p->mfcr2_dnis_index] = digit;
  3512. p->rdnis[p->mfcr2_dnis_index] = digit;
  3513. p->mfcr2_dnis_index++;
  3514. p->exten[p->mfcr2_dnis_index] = 0;
  3515. p->rdnis[p->mfcr2_dnis_index] = 0;
  3516. /* if the DNIS is a match and cannot match more, stop requesting DNIS */
  3517. if ((p->mfcr2_dnis_matched ||
  3518. (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) &&
  3519. !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
  3520. return 0;
  3521. }
  3522. /* otherwise keep going */
  3523. return 1;
  3524. }
  3525. static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
  3526. {
  3527. struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
  3528. p->cid_num[p->mfcr2_ani_index] = digit;
  3529. p->cid_name[p->mfcr2_ani_index] = digit;
  3530. p->mfcr2_ani_index++;
  3531. p->cid_num[p->mfcr2_ani_index] = 0;
  3532. p->cid_name[p->mfcr2_ani_index] = 0;
  3533. }
  3534. static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
  3535. {
  3536. ast_verbose("MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
  3537. }
  3538. static openr2_event_interface_t dahdi_r2_event_iface = {
  3539. .on_call_init = dahdi_r2_on_call_init,
  3540. .on_call_offered = dahdi_r2_on_call_offered,
  3541. .on_call_accepted = dahdi_r2_on_call_accepted,
  3542. .on_call_answered = dahdi_r2_on_call_answered,
  3543. .on_call_disconnect = dahdi_r2_on_call_disconnect,
  3544. .on_call_end = dahdi_r2_on_call_end,
  3545. .on_call_read = dahdi_r2_on_call_read,
  3546. .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
  3547. .on_os_error = dahdi_r2_on_os_error,
  3548. .on_protocol_error = dahdi_r2_on_protocol_error,
  3549. .on_line_blocked = dahdi_r2_on_line_blocked,
  3550. .on_line_idle = dahdi_r2_on_line_idle,
  3551. /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
  3552. .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
  3553. .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
  3554. .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
  3555. /* so far we do nothing with billing pulses */
  3556. .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
  3557. };
  3558. static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
  3559. {
  3560. return AST_ALAW(sample);
  3561. }
  3562. static inline uint8_t dahdi_r2_linear_to_alaw(int sample)
  3563. {
  3564. return AST_LIN2A(sample);
  3565. }
  3566. static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
  3567. dahdi_r2_alaw_to_linear,
  3568. dahdi_r2_linear_to_alaw
  3569. };
  3570. #endif /* HAVE_OPENR2 */
  3571. static void swap_subs(struct dahdi_pvt *p, int a, int b)
  3572. {
  3573. int tchan;
  3574. int tinthreeway;
  3575. struct ast_channel *towner;
  3576. ast_debug(1, "Swapping %d and %d\n", a, b);
  3577. tchan = p->subs[a].chan;
  3578. towner = p->subs[a].owner;
  3579. tinthreeway = p->subs[a].inthreeway;
  3580. p->subs[a].chan = p->subs[b].chan;
  3581. p->subs[a].owner = p->subs[b].owner;
  3582. p->subs[a].inthreeway = p->subs[b].inthreeway;
  3583. p->subs[b].chan = tchan;
  3584. p->subs[b].owner = towner;
  3585. p->subs[b].inthreeway = tinthreeway;
  3586. if (p->subs[a].owner)
  3587. ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
  3588. if (p->subs[b].owner)
  3589. ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
  3590. wakeup_sub(p, a);
  3591. wakeup_sub(p, b);
  3592. }
  3593. static int dahdi_open(char *fn)
  3594. {
  3595. int fd;
  3596. int isnum;
  3597. int chan = 0;
  3598. int bs;
  3599. int x;
  3600. isnum = 1;
  3601. for (x = 0; x < strlen(fn); x++) {
  3602. if (!isdigit(fn[x])) {
  3603. isnum = 0;
  3604. break;
  3605. }
  3606. }
  3607. if (isnum) {
  3608. chan = atoi(fn);
  3609. if (chan < 1) {
  3610. ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
  3611. return -1;
  3612. }
  3613. fn = "/dev/dahdi/channel";
  3614. }
  3615. fd = open(fn, O_RDWR | O_NONBLOCK);
  3616. if (fd < 0) {
  3617. ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
  3618. return -1;
  3619. }
  3620. if (chan) {
  3621. if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
  3622. x = errno;
  3623. close(fd);
  3624. errno = x;
  3625. ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
  3626. return -1;
  3627. }
  3628. }
  3629. bs = READ_SIZE;
  3630. if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
  3631. ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
  3632. x = errno;
  3633. close(fd);
  3634. errno = x;
  3635. return -1;
  3636. }
  3637. return fd;
  3638. }
  3639. static void dahdi_close(int fd)
  3640. {
  3641. if (fd > 0)
  3642. close(fd);
  3643. }
  3644. static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
  3645. {
  3646. dahdi_close(chan_pvt->subs[sub_num].dfd);
  3647. chan_pvt->subs[sub_num].dfd = -1;
  3648. }
  3649. #if defined(HAVE_PRI)
  3650. static void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num)
  3651. {
  3652. dahdi_close(pri->pri.fds[fd_num]);
  3653. pri->pri.fds[fd_num] = -1;
  3654. }
  3655. #endif /* defined(HAVE_PRI) */
  3656. #if defined(HAVE_SS7)
  3657. static void dahdi_close_ss7_fd(struct dahdi_ss7 *ss7, int fd_num)
  3658. {
  3659. dahdi_close(ss7->ss7.fds[fd_num]);
  3660. ss7->ss7.fds[fd_num] = -1;
  3661. }
  3662. #endif /* defined(HAVE_SS7) */
  3663. static int dahdi_setlinear(int dfd, int linear)
  3664. {
  3665. return ioctl(dfd, DAHDI_SETLINEAR, &linear);
  3666. }
  3667. static int alloc_sub(struct dahdi_pvt *p, int x)
  3668. {
  3669. struct dahdi_bufferinfo bi;
  3670. int res;
  3671. if (p->subs[x].dfd >= 0) {
  3672. ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
  3673. return -1;
  3674. }
  3675. p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
  3676. if (p->subs[x].dfd <= -1) {
  3677. ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
  3678. return -1;
  3679. }
  3680. res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
  3681. if (!res) {
  3682. bi.txbufpolicy = p->buf_policy;
  3683. bi.rxbufpolicy = p->buf_policy;
  3684. bi.numbufs = p->buf_no;
  3685. res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
  3686. if (res < 0) {
  3687. ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
  3688. }
  3689. } else
  3690. ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
  3691. if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
  3692. ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
  3693. dahdi_close_sub(p, x);
  3694. p->subs[x].dfd = -1;
  3695. return -1;
  3696. }
  3697. ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
  3698. return 0;
  3699. }
  3700. static int unalloc_sub(struct dahdi_pvt *p, int x)
  3701. {
  3702. if (!x) {
  3703. ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
  3704. return -1;
  3705. }
  3706. ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
  3707. dahdi_close_sub(p, x);
  3708. p->subs[x].linear = 0;
  3709. p->subs[x].chan = 0;
  3710. p->subs[x].owner = NULL;
  3711. p->subs[x].inthreeway = 0;
  3712. p->polarity = POLARITY_IDLE;
  3713. memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
  3714. return 0;
  3715. }
  3716. static int digit_to_dtmfindex(char digit)
  3717. {
  3718. if (isdigit(digit))
  3719. return DAHDI_TONE_DTMF_BASE + (digit - '0');
  3720. else if (digit >= 'A' && digit <= 'D')
  3721. return DAHDI_TONE_DTMF_A + (digit - 'A');
  3722. else if (digit >= 'a' && digit <= 'd')
  3723. return DAHDI_TONE_DTMF_A + (digit - 'a');
  3724. else if (digit == '*')
  3725. return DAHDI_TONE_DTMF_s;
  3726. else if (digit == '#')
  3727. return DAHDI_TONE_DTMF_p;
  3728. else
  3729. return -1;
  3730. }
  3731. static int dahdi_digit_begin(struct ast_channel *chan, char digit)
  3732. {
  3733. struct dahdi_pvt *pvt;
  3734. int idx;
  3735. int dtmf = -1;
  3736. int res;
  3737. pvt = ast_channel_tech_pvt(chan);
  3738. ast_mutex_lock(&pvt->lock);
  3739. idx = dahdi_get_index(chan, pvt, 0);
  3740. if ((idx != SUB_REAL) || !pvt->owner)
  3741. goto out;
  3742. #ifdef HAVE_PRI
  3743. switch (pvt->sig) {
  3744. case SIG_PRI_LIB_HANDLE_CASES:
  3745. res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit);
  3746. if (!res)
  3747. goto out;
  3748. break;
  3749. default:
  3750. break;
  3751. }
  3752. #endif
  3753. if ((dtmf = digit_to_dtmfindex(digit)) == -1)
  3754. goto out;
  3755. if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
  3756. char dial_str[] = { 'T', digit, '\0' };
  3757. res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
  3758. if (!res) {
  3759. pvt->dialing = 1;
  3760. }
  3761. } else {
  3762. ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
  3763. ast_channel_name(chan), digit);
  3764. pvt->dialing = 1;
  3765. pvt->begindigit = digit;
  3766. }
  3767. out:
  3768. ast_mutex_unlock(&pvt->lock);
  3769. return 0;
  3770. }
  3771. static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
  3772. {
  3773. struct dahdi_pvt *pvt;
  3774. int res = 0;
  3775. int idx;
  3776. int x;
  3777. pvt = ast_channel_tech_pvt(chan);
  3778. ast_mutex_lock(&pvt->lock);
  3779. idx = dahdi_get_index(chan, pvt, 0);
  3780. if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
  3781. goto out;
  3782. #ifdef HAVE_PRI
  3783. /* This means that the digit was already sent via PRI signalling */
  3784. if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) {
  3785. goto out;
  3786. }
  3787. #endif
  3788. if (pvt->begindigit) {
  3789. x = -1;
  3790. ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n",
  3791. ast_channel_name(chan), digit);
  3792. res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
  3793. pvt->dialing = 0;
  3794. pvt->begindigit = 0;
  3795. }
  3796. out:
  3797. ast_mutex_unlock(&pvt->lock);
  3798. return res;
  3799. }
  3800. static const char * const events[] = {
  3801. "No event",
  3802. "On hook",
  3803. "Ring/Answered",
  3804. "Wink/Flash",
  3805. "Alarm",
  3806. "No more alarm",
  3807. "HDLC Abort",
  3808. "HDLC Overrun",
  3809. "HDLC Bad FCS",
  3810. "Dial Complete",
  3811. "Ringer On",
  3812. "Ringer Off",
  3813. "Hook Transition Complete",
  3814. "Bits Changed",
  3815. "Pulse Start",
  3816. "Timer Expired",
  3817. "Timer Ping",
  3818. "Polarity Reversal",
  3819. "Ring Begin",
  3820. };
  3821. static struct {
  3822. int alarm;
  3823. char *name;
  3824. } alarms[] = {
  3825. { DAHDI_ALARM_RED, "Red Alarm" },
  3826. { DAHDI_ALARM_YELLOW, "Yellow Alarm" },
  3827. { DAHDI_ALARM_BLUE, "Blue Alarm" },
  3828. { DAHDI_ALARM_RECOVER, "Recovering" },
  3829. { DAHDI_ALARM_LOOPBACK, "Loopback" },
  3830. { DAHDI_ALARM_NOTOPEN, "Not Open" },
  3831. { DAHDI_ALARM_NONE, "None" },
  3832. };
  3833. static char *alarm2str(int alm)
  3834. {
  3835. int x;
  3836. for (x = 0; x < ARRAY_LEN(alarms); x++) {
  3837. if (alarms[x].alarm & alm)
  3838. return alarms[x].name;
  3839. }
  3840. return alm ? "Unknown Alarm" : "No Alarm";
  3841. }
  3842. static const char *event2str(int event)
  3843. {
  3844. static char buf[256];
  3845. if ((event < (ARRAY_LEN(events))) && (event > -1))
  3846. return events[event];
  3847. sprintf(buf, "Event %d", event); /* safe */
  3848. return buf;
  3849. }
  3850. static char *dahdi_sig2str(int sig)
  3851. {
  3852. static char buf[256];
  3853. switch (sig) {
  3854. case SIG_EM:
  3855. return "E & M Immediate";
  3856. case SIG_EMWINK:
  3857. return "E & M Wink";
  3858. case SIG_EM_E1:
  3859. return "E & M E1";
  3860. case SIG_FEATD:
  3861. return "Feature Group D (DTMF)";
  3862. case SIG_FEATDMF:
  3863. return "Feature Group D (MF)";
  3864. case SIG_FEATDMF_TA:
  3865. return "Feature Groud D (MF) Tandem Access";
  3866. case SIG_FEATB:
  3867. return "Feature Group B (MF)";
  3868. case SIG_E911:
  3869. return "E911 (MF)";
  3870. case SIG_FGC_CAMA:
  3871. return "FGC/CAMA (Dialpulse)";
  3872. case SIG_FGC_CAMAMF:
  3873. return "FGC/CAMA (MF)";
  3874. case SIG_FXSLS:
  3875. return "FXS Loopstart";
  3876. case SIG_FXSGS:
  3877. return "FXS Groundstart";
  3878. case SIG_FXSKS:
  3879. return "FXS Kewlstart";
  3880. case SIG_FXOLS:
  3881. return "FXO Loopstart";
  3882. case SIG_FXOGS:
  3883. return "FXO Groundstart";
  3884. case SIG_FXOKS:
  3885. return "FXO Kewlstart";
  3886. case SIG_PRI:
  3887. return "ISDN PRI";
  3888. case SIG_BRI:
  3889. return "ISDN BRI Point to Point";
  3890. case SIG_BRI_PTMP:
  3891. return "ISDN BRI Point to MultiPoint";
  3892. case SIG_SS7:
  3893. return "SS7";
  3894. case SIG_MFCR2:
  3895. return "MFC/R2";
  3896. case SIG_SF:
  3897. return "SF (Tone) Immediate";
  3898. case SIG_SFWINK:
  3899. return "SF (Tone) Wink";
  3900. case SIG_SF_FEATD:
  3901. return "SF (Tone) with Feature Group D (DTMF)";
  3902. case SIG_SF_FEATDMF:
  3903. return "SF (Tone) with Feature Group D (MF)";
  3904. case SIG_SF_FEATB:
  3905. return "SF (Tone) with Feature Group B (MF)";
  3906. case 0:
  3907. return "Pseudo";
  3908. default:
  3909. snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
  3910. return buf;
  3911. }
  3912. }
  3913. #define sig2str dahdi_sig2str
  3914. static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx, int slavechannel)
  3915. {
  3916. /* If the conference already exists, and we're already in it
  3917. don't bother doing anything */
  3918. struct dahdi_confinfo zi;
  3919. memset(&zi, 0, sizeof(zi));
  3920. zi.chan = 0;
  3921. if (slavechannel > 0) {
  3922. /* If we have only one slave, do a digital mon */
  3923. zi.confmode = DAHDI_CONF_DIGITALMON;
  3924. zi.confno = slavechannel;
  3925. } else {
  3926. if (!idx) {
  3927. /* Real-side and pseudo-side both participate in conference */
  3928. zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
  3929. DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
  3930. } else
  3931. zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
  3932. zi.confno = p->confno;
  3933. }
  3934. if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
  3935. return 0;
  3936. if (c->dfd < 0)
  3937. return 0;
  3938. if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
  3939. ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
  3940. return -1;
  3941. }
  3942. if (slavechannel < 1) {
  3943. p->confno = zi.confno;
  3944. }
  3945. c->curconf = zi;
  3946. ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
  3947. return 0;
  3948. }
  3949. static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
  3950. {
  3951. /* If they're listening to our channel, they're ours */
  3952. if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
  3953. return 1;
  3954. /* If they're a talker on our (allocated) conference, they're ours */
  3955. if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
  3956. return 1;
  3957. return 0;
  3958. }
  3959. static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx)
  3960. {
  3961. struct dahdi_confinfo zi;
  3962. if (/* Can't delete if there's no dfd */
  3963. (c->dfd < 0) ||
  3964. /* Don't delete from the conference if it's not our conference */
  3965. !isourconf(p, c)
  3966. /* Don't delete if we don't think it's conferenced at all (implied) */
  3967. ) return 0;
  3968. memset(&zi, 0, sizeof(zi));
  3969. if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
  3970. ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
  3971. return -1;
  3972. }
  3973. ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
  3974. memcpy(&c->curconf, &zi, sizeof(c->curconf));
  3975. return 0;
  3976. }
  3977. static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
  3978. {
  3979. int x;
  3980. int useslavenative;
  3981. struct dahdi_pvt *slave = NULL;
  3982. /* Start out optimistic */
  3983. useslavenative = 1;
  3984. /* Update conference state in a stateless fashion */
  3985. for (x = 0; x < 3; x++) {
  3986. /* Any three-way calling makes slave native mode *definitely* out
  3987. of the question */
  3988. if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
  3989. useslavenative = 0;
  3990. }
  3991. /* If we don't have any 3-way calls, check to see if we have
  3992. precisely one slave */
  3993. if (useslavenative) {
  3994. for (x = 0; x < MAX_SLAVES; x++) {
  3995. if (p->slaves[x]) {
  3996. if (slave) {
  3997. /* Whoops already have a slave! No
  3998. slave native and stop right away */
  3999. slave = NULL;
  4000. useslavenative = 0;
  4001. break;
  4002. } else {
  4003. /* We have one slave so far */
  4004. slave = p->slaves[x];
  4005. }
  4006. }
  4007. }
  4008. }
  4009. /* If no slave, slave native definitely out */
  4010. if (!slave)
  4011. useslavenative = 0;
  4012. else if (slave->law != p->law) {
  4013. useslavenative = 0;
  4014. slave = NULL;
  4015. }
  4016. if (out)
  4017. *out = slave;
  4018. return useslavenative;
  4019. }
  4020. static int reset_conf(struct dahdi_pvt *p)
  4021. {
  4022. p->confno = -1;
  4023. memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
  4024. if (p->subs[SUB_REAL].dfd > -1) {
  4025. struct dahdi_confinfo zi;
  4026. memset(&zi, 0, sizeof(zi));
  4027. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
  4028. ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
  4029. }
  4030. return 0;
  4031. }
  4032. void dahdi_conf_update(struct dahdi_pvt *p)
  4033. {
  4034. int needconf = 0;
  4035. int x;
  4036. int useslavenative;
  4037. struct dahdi_pvt *slave = NULL;
  4038. useslavenative = isslavenative(p, &slave);
  4039. /* Start with the obvious, general stuff */
  4040. for (x = 0; x < 3; x++) {
  4041. /* Look for three way calls */
  4042. if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
  4043. conf_add(p, &p->subs[x], x, 0);
  4044. needconf++;
  4045. } else {
  4046. conf_del(p, &p->subs[x], x);
  4047. }
  4048. }
  4049. /* If we have a slave, add him to our conference now. or DAX
  4050. if this is slave native */
  4051. for (x = 0; x < MAX_SLAVES; x++) {
  4052. if (p->slaves[x]) {
  4053. if (useslavenative)
  4054. conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
  4055. else {
  4056. conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
  4057. needconf++;
  4058. }
  4059. }
  4060. }
  4061. /* If we're supposed to be in there, do so now */
  4062. if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
  4063. if (useslavenative)
  4064. conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
  4065. else {
  4066. conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
  4067. needconf++;
  4068. }
  4069. }
  4070. /* If we have a master, add ourselves to his conference */
  4071. if (p->master) {
  4072. if (isslavenative(p->master, NULL)) {
  4073. conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
  4074. } else {
  4075. conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
  4076. }
  4077. }
  4078. if (!needconf) {
  4079. /* Nobody is left (or should be left) in our conference.
  4080. Kill it. */
  4081. p->confno = -1;
  4082. }
  4083. ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
  4084. }
  4085. void dahdi_ec_enable(struct dahdi_pvt *p)
  4086. {
  4087. int res;
  4088. if (!p)
  4089. return;
  4090. if (p->echocanon) {
  4091. ast_debug(1, "Echo cancellation already on\n");
  4092. return;
  4093. }
  4094. if (p->digital) {
  4095. ast_debug(1, "Echo cancellation isn't required on digital connection\n");
  4096. return;
  4097. }
  4098. if (p->echocancel.head.tap_length) {
  4099. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  4100. switch (p->sig) {
  4101. #if defined(HAVE_PRI)
  4102. case SIG_PRI_LIB_HANDLE_CASES:
  4103. if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
  4104. /*
  4105. * PRI nobch pseudo channel. Does not need ec anyway.
  4106. * Does not handle ioctl(DAHDI_AUDIOMODE)
  4107. */
  4108. return;
  4109. }
  4110. /* Fall through */
  4111. #endif /* defined(HAVE_PRI) */
  4112. #if defined(HAVE_SS7)
  4113. case SIG_SS7:
  4114. #endif /* defined(HAVE_SS7) */
  4115. {
  4116. int x = 1;
  4117. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
  4118. if (res)
  4119. ast_log(LOG_WARNING,
  4120. "Unable to enable audio mode on channel %d (%s)\n",
  4121. p->channel, strerror(errno));
  4122. }
  4123. break;
  4124. default:
  4125. break;
  4126. }
  4127. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  4128. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
  4129. if (res) {
  4130. ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
  4131. } else {
  4132. p->echocanon = 1;
  4133. ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
  4134. }
  4135. } else
  4136. ast_debug(1, "No echo cancellation requested\n");
  4137. }
  4138. static void dahdi_train_ec(struct dahdi_pvt *p)
  4139. {
  4140. int x;
  4141. int res;
  4142. if (p && p->echocanon && p->echotraining) {
  4143. x = p->echotraining;
  4144. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
  4145. if (res)
  4146. ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
  4147. else
  4148. ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
  4149. } else {
  4150. ast_debug(1, "No echo training requested\n");
  4151. }
  4152. }
  4153. void dahdi_ec_disable(struct dahdi_pvt *p)
  4154. {
  4155. int res;
  4156. if (p->echocanon) {
  4157. struct dahdi_echocanparams ecp = { .tap_length = 0 };
  4158. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
  4159. if (res)
  4160. ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
  4161. else
  4162. ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
  4163. }
  4164. p->echocanon = 0;
  4165. }
  4166. static int set_hwgain(int fd, float gain, int tx_direction)
  4167. {
  4168. struct dahdi_hwgain hwgain;
  4169. hwgain.newgain = gain * 10.0;
  4170. hwgain.tx = tx_direction;
  4171. return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
  4172. }
  4173. /* perform a dynamic range compression transform on the given sample */
  4174. static int drc_sample(int sample, float drc)
  4175. {
  4176. float neg;
  4177. float shallow, steep;
  4178. float max = SHRT_MAX;
  4179. neg = (sample < 0 ? -1 : 1);
  4180. steep = drc*sample;
  4181. shallow = neg*(max-max/drc)+(float)sample/drc;
  4182. if (abs(steep) < abs(shallow)) {
  4183. sample = steep;
  4184. }
  4185. else {
  4186. sample = shallow;
  4187. }
  4188. return sample;
  4189. }
  4190. static void fill_txgain(struct dahdi_gains *g, float gain, float drc, int law)
  4191. {
  4192. int j;
  4193. int k;
  4194. float linear_gain = pow(10.0, gain / 20.0);
  4195. switch (law) {
  4196. case DAHDI_LAW_ALAW:
  4197. for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
  4198. if (gain || drc) {
  4199. k = AST_ALAW(j);
  4200. if (drc) {
  4201. k = drc_sample(k, drc);
  4202. }
  4203. k = (float)k * linear_gain;
  4204. if (k > 32767) {
  4205. k = 32767;
  4206. } else if (k < -32768) {
  4207. k = -32768;
  4208. }
  4209. g->txgain[j] = AST_LIN2A(k);
  4210. } else {
  4211. g->txgain[j] = j;
  4212. }
  4213. }
  4214. break;
  4215. case DAHDI_LAW_MULAW:
  4216. for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
  4217. if (gain || drc) {
  4218. k = AST_MULAW(j);
  4219. if (drc) {
  4220. k = drc_sample(k, drc);
  4221. }
  4222. k = (float)k * linear_gain;
  4223. if (k > 32767) {
  4224. k = 32767;
  4225. } else if (k < -32768) {
  4226. k = -32768;
  4227. }
  4228. g->txgain[j] = AST_LIN2MU(k);
  4229. } else {
  4230. g->txgain[j] = j;
  4231. }
  4232. }
  4233. break;
  4234. }
  4235. }
  4236. static void fill_rxgain(struct dahdi_gains *g, float gain, float drc, int law)
  4237. {
  4238. int j;
  4239. int k;
  4240. float linear_gain = pow(10.0, gain / 20.0);
  4241. switch (law) {
  4242. case DAHDI_LAW_ALAW:
  4243. for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
  4244. if (gain || drc) {
  4245. k = AST_ALAW(j);
  4246. if (drc) {
  4247. k = drc_sample(k, drc);
  4248. }
  4249. k = (float)k * linear_gain;
  4250. if (k > 32767) {
  4251. k = 32767;
  4252. } else if (k < -32768) {
  4253. k = -32768;
  4254. }
  4255. g->rxgain[j] = AST_LIN2A(k);
  4256. } else {
  4257. g->rxgain[j] = j;
  4258. }
  4259. }
  4260. break;
  4261. case DAHDI_LAW_MULAW:
  4262. for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
  4263. if (gain || drc) {
  4264. k = AST_MULAW(j);
  4265. if (drc) {
  4266. k = drc_sample(k, drc);
  4267. }
  4268. k = (float)k * linear_gain;
  4269. if (k > 32767) {
  4270. k = 32767;
  4271. } else if (k < -32768) {
  4272. k = -32768;
  4273. }
  4274. g->rxgain[j] = AST_LIN2MU(k);
  4275. } else {
  4276. g->rxgain[j] = j;
  4277. }
  4278. }
  4279. break;
  4280. }
  4281. }
  4282. static int set_actual_txgain(int fd, float gain, float drc, int law)
  4283. {
  4284. struct dahdi_gains g;
  4285. int res;
  4286. memset(&g, 0, sizeof(g));
  4287. res = ioctl(fd, DAHDI_GETGAINS, &g);
  4288. if (res) {
  4289. ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
  4290. return res;
  4291. }
  4292. fill_txgain(&g, gain, drc, law);
  4293. return ioctl(fd, DAHDI_SETGAINS, &g);
  4294. }
  4295. static int set_actual_rxgain(int fd, float gain, float drc, int law)
  4296. {
  4297. struct dahdi_gains g;
  4298. int res;
  4299. memset(&g, 0, sizeof(g));
  4300. res = ioctl(fd, DAHDI_GETGAINS, &g);
  4301. if (res) {
  4302. ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
  4303. return res;
  4304. }
  4305. fill_rxgain(&g, gain, drc, law);
  4306. return ioctl(fd, DAHDI_SETGAINS, &g);
  4307. }
  4308. static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
  4309. {
  4310. return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law);
  4311. }
  4312. static int bump_gains(struct dahdi_pvt *p)
  4313. {
  4314. int res;
  4315. /* Bump receive gain by value stored in cid_rxgain */
  4316. res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
  4317. if (res) {
  4318. ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
  4319. return -1;
  4320. }
  4321. return 0;
  4322. }
  4323. static int restore_gains(struct dahdi_pvt *p)
  4324. {
  4325. int res;
  4326. res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
  4327. if (res) {
  4328. ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
  4329. return -1;
  4330. }
  4331. return 0;
  4332. }
  4333. static inline int dahdi_set_hook(int fd, int hs)
  4334. {
  4335. int x, res;
  4336. x = hs;
  4337. res = ioctl(fd, DAHDI_HOOK, &x);
  4338. if (res < 0) {
  4339. if (errno == EINPROGRESS)
  4340. return 0;
  4341. ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
  4342. /* will expectedly fail if phone is off hook during operation, such as during a restart */
  4343. }
  4344. return res;
  4345. }
  4346. static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
  4347. {
  4348. int x, res;
  4349. x = muted;
  4350. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  4351. switch (p->sig) {
  4352. #if defined(HAVE_PRI)
  4353. case SIG_PRI_LIB_HANDLE_CASES:
  4354. if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
  4355. /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
  4356. break;
  4357. }
  4358. /* Fall through */
  4359. #endif /* defined(HAVE_PRI) */
  4360. #if defined(HAVE_SS7)
  4361. case SIG_SS7:
  4362. #endif /* defined(HAVE_SS7) */
  4363. {
  4364. int y = 1;
  4365. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
  4366. if (res)
  4367. ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n",
  4368. p->channel, strerror(errno));
  4369. }
  4370. break;
  4371. default:
  4372. break;
  4373. }
  4374. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  4375. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
  4376. if (res < 0)
  4377. ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
  4378. return res;
  4379. }
  4380. static int save_conference(struct dahdi_pvt *p)
  4381. {
  4382. struct dahdi_confinfo c;
  4383. int res;
  4384. if (p->saveconf.confmode) {
  4385. ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
  4386. return -1;
  4387. }
  4388. p->saveconf.chan = 0;
  4389. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
  4390. if (res) {
  4391. ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
  4392. p->saveconf.confmode = 0;
  4393. return -1;
  4394. }
  4395. memset(&c, 0, sizeof(c));
  4396. c.confmode = DAHDI_CONF_NORMAL;
  4397. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
  4398. if (res) {
  4399. ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
  4400. return -1;
  4401. }
  4402. ast_debug(1, "Disabled conferencing\n");
  4403. return 0;
  4404. }
  4405. static int restore_conference(struct dahdi_pvt *p)
  4406. {
  4407. int res;
  4408. if (p->saveconf.confmode) {
  4409. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
  4410. p->saveconf.confmode = 0;
  4411. if (res) {
  4412. ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
  4413. return -1;
  4414. }
  4415. ast_debug(1, "Restored conferencing\n");
  4416. }
  4417. return 0;
  4418. }
  4419. static int send_cwcidspill(struct dahdi_pvt *p)
  4420. {
  4421. p->callwaitcas = 0;
  4422. p->cidcwexpire = 0;
  4423. p->cid_suppress_expire = 0;
  4424. if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
  4425. return -1;
  4426. p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
  4427. /* Make sure we account for the end */
  4428. p->cidlen += READ_SIZE * 4;
  4429. p->cidpos = 0;
  4430. send_callerid(p);
  4431. ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
  4432. return 0;
  4433. }
  4434. static int has_voicemail(struct dahdi_pvt *p)
  4435. {
  4436. int new_msgs;
  4437. RAII_VAR(struct stasis_message *, mwi_message, NULL, ao2_cleanup);
  4438. mwi_message = stasis_cache_get(ast_mwi_state_cache(), ast_mwi_state_type(), p->mailbox);
  4439. if (mwi_message) {
  4440. struct ast_mwi_state *mwi_state = stasis_message_data(mwi_message);
  4441. new_msgs = mwi_state->new_msgs;
  4442. } else {
  4443. new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
  4444. }
  4445. return new_msgs;
  4446. }
  4447. static int send_callerid(struct dahdi_pvt *p)
  4448. {
  4449. /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
  4450. int res;
  4451. /* Take out of linear mode if necessary */
  4452. if (p->subs[SUB_REAL].linear) {
  4453. p->subs[SUB_REAL].linear = 0;
  4454. dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
  4455. }
  4456. while (p->cidpos < p->cidlen) {
  4457. res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
  4458. ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res);
  4459. if (res < 0) {
  4460. if (errno == EAGAIN)
  4461. return 0;
  4462. else {
  4463. ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
  4464. return -1;
  4465. }
  4466. }
  4467. if (!res)
  4468. return 0;
  4469. p->cidpos += res;
  4470. }
  4471. p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES;
  4472. ast_free(p->cidspill);
  4473. p->cidspill = NULL;
  4474. if (p->callwaitcas) {
  4475. /* Wait for CID/CW to expire */
  4476. p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
  4477. p->cid_suppress_expire = p->cidcwexpire;
  4478. } else
  4479. restore_conference(p);
  4480. return 0;
  4481. }
  4482. static int dahdi_callwait(struct ast_channel *ast)
  4483. {
  4484. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  4485. p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
  4486. if (p->cidspill) {
  4487. ast_log(LOG_WARNING, "Spill already exists?!?\n");
  4488. ast_free(p->cidspill);
  4489. }
  4490. /*
  4491. * SAS: Subscriber Alert Signal, 440Hz for 300ms
  4492. * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
  4493. */
  4494. if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
  4495. return -1;
  4496. save_conference(p);
  4497. /* Silence */
  4498. memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
  4499. if (!p->callwaitrings && p->callwaitingcallerid) {
  4500. ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
  4501. p->callwaitcas = 1;
  4502. p->cidlen = 2400 + 680 + READ_SIZE * 4;
  4503. } else {
  4504. ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
  4505. p->callwaitcas = 0;
  4506. p->cidlen = 2400 + READ_SIZE * 4;
  4507. }
  4508. p->cidpos = 0;
  4509. send_callerid(p);
  4510. return 0;
  4511. }
  4512. static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout)
  4513. {
  4514. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  4515. int x, res, mysig;
  4516. char *dest;
  4517. AST_DECLARE_APP_ARGS(args,
  4518. AST_APP_ARG(group); /* channel/group token */
  4519. AST_APP_ARG(ext); /* extension token */
  4520. //AST_APP_ARG(opts); /* options token */
  4521. AST_APP_ARG(other); /* Any remining unused arguments */
  4522. );
  4523. ast_mutex_lock(&p->lock);
  4524. ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
  4525. /* Split the dialstring */
  4526. dest = ast_strdupa(rdest);
  4527. AST_NONSTANDARD_APP_ARGS(args, dest, '/');
  4528. if (!args.ext) {
  4529. args.ext = "";
  4530. }
  4531. #if defined(HAVE_PRI)
  4532. if (dahdi_sig_pri_lib_handles(p->sig)) {
  4533. char *subaddr;
  4534. sig_pri_extract_called_num_subaddr(p->sig_pvt, rdest, p->exten, sizeof(p->exten));
  4535. /* Remove any subaddress for uniformity with incoming calls. */
  4536. subaddr = strchr(p->exten, ':');
  4537. if (subaddr) {
  4538. *subaddr = '\0';
  4539. }
  4540. } else
  4541. #endif /* defined(HAVE_PRI) */
  4542. {
  4543. ast_copy_string(p->exten, args.ext, sizeof(p->exten));
  4544. }
  4545. if ((ast_channel_state(ast) == AST_STATE_BUSY)) {
  4546. p->subs[SUB_REAL].needbusy = 1;
  4547. ast_mutex_unlock(&p->lock);
  4548. return 0;
  4549. }
  4550. if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
  4551. ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
  4552. ast_mutex_unlock(&p->lock);
  4553. return -1;
  4554. }
  4555. p->waitingfordt.tv_sec = 0;
  4556. p->dialednone = 0;
  4557. if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
  4558. {
  4559. /* Special pseudo -- automatically up */
  4560. ast_setstate(ast, AST_STATE_UP);
  4561. ast_mutex_unlock(&p->lock);
  4562. return 0;
  4563. }
  4564. x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
  4565. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
  4566. if (res)
  4567. ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
  4568. p->outgoing = 1;
  4569. if (IS_DIGITAL(ast_channel_transfercapability(ast))){
  4570. set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law);
  4571. } else {
  4572. set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
  4573. }
  4574. #ifdef HAVE_PRI
  4575. if (dahdi_sig_pri_lib_handles(p->sig)) {
  4576. res = sig_pri_call(p->sig_pvt, ast, rdest, timeout,
  4577. (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
  4578. ast_mutex_unlock(&p->lock);
  4579. return res;
  4580. }
  4581. #endif
  4582. #if defined(HAVE_SS7)
  4583. if (p->sig == SIG_SS7) {
  4584. res = sig_ss7_call(p->sig_pvt, ast, rdest);
  4585. ast_mutex_unlock(&p->lock);
  4586. return res;
  4587. }
  4588. #endif /* defined(HAVE_SS7) */
  4589. /* If this is analog signalling we can exit here */
  4590. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  4591. p->callwaitrings = 0;
  4592. res = analog_call(p->sig_pvt, ast, rdest, timeout);
  4593. ast_mutex_unlock(&p->lock);
  4594. return res;
  4595. }
  4596. mysig = p->outsigmod > -1 ? p->outsigmod : p->sig;
  4597. switch (mysig) {
  4598. case 0:
  4599. /* Special pseudo -- automatically up*/
  4600. ast_setstate(ast, AST_STATE_UP);
  4601. break;
  4602. case SIG_MFCR2:
  4603. break;
  4604. default:
  4605. ast_debug(1, "not yet implemented\n");
  4606. ast_mutex_unlock(&p->lock);
  4607. return -1;
  4608. }
  4609. #ifdef HAVE_OPENR2
  4610. if (p->mfcr2) {
  4611. openr2_calling_party_category_t chancat;
  4612. int callres = 0;
  4613. char *c, *l;
  4614. /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
  4615. p->dialdest[0] = '\0';
  4616. c = args.ext;
  4617. if (!p->hidecallerid) {
  4618. l = ast_channel_connected(ast)->id.number.valid ? ast_channel_connected(ast)->id.number.str : NULL;
  4619. } else {
  4620. l = NULL;
  4621. }
  4622. if (strlen(c) < p->stripmsd) {
  4623. ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
  4624. ast_mutex_unlock(&p->lock);
  4625. return -1;
  4626. }
  4627. p->dialing = 1;
  4628. chancat = dahdi_r2_get_channel_category(ast);
  4629. callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
  4630. if (-1 == callres) {
  4631. ast_mutex_unlock(&p->lock);
  4632. ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
  4633. return -1;
  4634. }
  4635. p->mfcr2_call_accepted = 0;
  4636. p->mfcr2_progress_sent = 0;
  4637. ast_setstate(ast, AST_STATE_DIALING);
  4638. }
  4639. #endif /* HAVE_OPENR2 */
  4640. ast_mutex_unlock(&p->lock);
  4641. return 0;
  4642. }
  4643. /*!
  4644. * \internal
  4645. * \brief Insert the given chan_dahdi interface structure into the interface list.
  4646. * \since 1.8
  4647. *
  4648. * \param pvt chan_dahdi private interface structure to insert.
  4649. *
  4650. * \details
  4651. * The interface list is a doubly linked list sorted by the chan_dahdi channel number.
  4652. * Any duplicates are inserted after the existing entries.
  4653. *
  4654. * \note The new interface must not already be in the list.
  4655. *
  4656. * \return Nothing
  4657. */
  4658. static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
  4659. {
  4660. struct dahdi_pvt *cur;
  4661. pvt->which_iflist = DAHDI_IFLIST_MAIN;
  4662. /* Find place in middle of list for the new interface. */
  4663. for (cur = iflist; cur; cur = cur->next) {
  4664. if (pvt->channel < cur->channel) {
  4665. /* New interface goes before the current interface. */
  4666. pvt->prev = cur->prev;
  4667. pvt->next = cur;
  4668. if (cur->prev) {
  4669. /* Insert into the middle of the list. */
  4670. cur->prev->next = pvt;
  4671. } else {
  4672. /* Insert at head of list. */
  4673. iflist = pvt;
  4674. }
  4675. cur->prev = pvt;
  4676. return;
  4677. }
  4678. }
  4679. /* New interface goes onto the end of the list */
  4680. pvt->prev = ifend;
  4681. pvt->next = NULL;
  4682. if (ifend) {
  4683. ifend->next = pvt;
  4684. }
  4685. ifend = pvt;
  4686. if (!iflist) {
  4687. /* List was empty */
  4688. iflist = pvt;
  4689. }
  4690. }
  4691. /*!
  4692. * \internal
  4693. * \brief Extract the given chan_dahdi interface structure from the interface list.
  4694. * \since 1.8
  4695. *
  4696. * \param pvt chan_dahdi private interface structure to extract.
  4697. *
  4698. * \note
  4699. * The given interface structure can be either in the interface list or a stand alone
  4700. * structure that has not been put in the list if the next and prev pointers are NULL.
  4701. *
  4702. * \return Nothing
  4703. */
  4704. static void dahdi_iflist_extract(struct dahdi_pvt *pvt)
  4705. {
  4706. /* Extract from the forward chain. */
  4707. if (pvt->prev) {
  4708. pvt->prev->next = pvt->next;
  4709. } else if (iflist == pvt) {
  4710. /* Node is at the head of the list. */
  4711. iflist = pvt->next;
  4712. }
  4713. /* Extract from the reverse chain. */
  4714. if (pvt->next) {
  4715. pvt->next->prev = pvt->prev;
  4716. } else if (ifend == pvt) {
  4717. /* Node is at the end of the list. */
  4718. ifend = pvt->prev;
  4719. }
  4720. /* Node is no longer in the list. */
  4721. pvt->which_iflist = DAHDI_IFLIST_NONE;
  4722. pvt->prev = NULL;
  4723. pvt->next = NULL;
  4724. }
  4725. #if defined(HAVE_PRI)
  4726. /*!
  4727. * \internal
  4728. * \brief Insert the given chan_dahdi interface structure into the no B channel list.
  4729. * \since 1.8
  4730. *
  4731. * \param pri sig_pri span control structure holding no B channel list.
  4732. * \param pvt chan_dahdi private interface structure to insert.
  4733. *
  4734. * \details
  4735. * The interface list is a doubly linked list sorted by the chan_dahdi channel number.
  4736. * Any duplicates are inserted after the existing entries.
  4737. *
  4738. * \note The new interface must not already be in the list.
  4739. *
  4740. * \return Nothing
  4741. */
  4742. static void dahdi_nobch_insert(struct sig_pri_span *pri, struct dahdi_pvt *pvt)
  4743. {
  4744. struct dahdi_pvt *cur;
  4745. pvt->which_iflist = DAHDI_IFLIST_NO_B_CHAN;
  4746. /* Find place in middle of list for the new interface. */
  4747. for (cur = pri->no_b_chan_iflist; cur; cur = cur->next) {
  4748. if (pvt->channel < cur->channel) {
  4749. /* New interface goes before the current interface. */
  4750. pvt->prev = cur->prev;
  4751. pvt->next = cur;
  4752. if (cur->prev) {
  4753. /* Insert into the middle of the list. */
  4754. cur->prev->next = pvt;
  4755. } else {
  4756. /* Insert at head of list. */
  4757. pri->no_b_chan_iflist = pvt;
  4758. }
  4759. cur->prev = pvt;
  4760. return;
  4761. }
  4762. }
  4763. /* New interface goes onto the end of the list */
  4764. pvt->prev = pri->no_b_chan_end;
  4765. pvt->next = NULL;
  4766. if (pri->no_b_chan_end) {
  4767. ((struct dahdi_pvt *) pri->no_b_chan_end)->next = pvt;
  4768. }
  4769. pri->no_b_chan_end = pvt;
  4770. if (!pri->no_b_chan_iflist) {
  4771. /* List was empty */
  4772. pri->no_b_chan_iflist = pvt;
  4773. }
  4774. }
  4775. #endif /* defined(HAVE_PRI) */
  4776. #if defined(HAVE_PRI)
  4777. /*!
  4778. * \internal
  4779. * \brief Extract the given chan_dahdi interface structure from the no B channel list.
  4780. * \since 1.8
  4781. *
  4782. * \param pri sig_pri span control structure holding no B channel list.
  4783. * \param pvt chan_dahdi private interface structure to extract.
  4784. *
  4785. * \note
  4786. * The given interface structure can be either in the interface list or a stand alone
  4787. * structure that has not been put in the list if the next and prev pointers are NULL.
  4788. *
  4789. * \return Nothing
  4790. */
  4791. static void dahdi_nobch_extract(struct sig_pri_span *pri, struct dahdi_pvt *pvt)
  4792. {
  4793. /* Extract from the forward chain. */
  4794. if (pvt->prev) {
  4795. pvt->prev->next = pvt->next;
  4796. } else if (pri->no_b_chan_iflist == pvt) {
  4797. /* Node is at the head of the list. */
  4798. pri->no_b_chan_iflist = pvt->next;
  4799. }
  4800. /* Extract from the reverse chain. */
  4801. if (pvt->next) {
  4802. pvt->next->prev = pvt->prev;
  4803. } else if (pri->no_b_chan_end == pvt) {
  4804. /* Node is at the end of the list. */
  4805. pri->no_b_chan_end = pvt->prev;
  4806. }
  4807. /* Node is no longer in the list. */
  4808. pvt->which_iflist = DAHDI_IFLIST_NONE;
  4809. pvt->prev = NULL;
  4810. pvt->next = NULL;
  4811. }
  4812. #endif /* defined(HAVE_PRI) */
  4813. #if defined(HAVE_PRI)
  4814. /*!
  4815. * \internal
  4816. * \brief Unlink the channel interface from the PRI private pointer array.
  4817. * \since 1.8
  4818. *
  4819. * \param pvt chan_dahdi private interface structure to unlink.
  4820. *
  4821. * \return Nothing
  4822. */
  4823. static void dahdi_unlink_pri_pvt(struct dahdi_pvt *pvt)
  4824. {
  4825. unsigned idx;
  4826. struct sig_pri_span *pri;
  4827. pri = pvt->pri;
  4828. if (!pri) {
  4829. /* Not PRI signaling so cannot be in a PRI private pointer array. */
  4830. return;
  4831. }
  4832. ast_mutex_lock(&pri->lock);
  4833. for (idx = 0; idx < pri->numchans; ++idx) {
  4834. if (pri->pvts[idx] == pvt->sig_pvt) {
  4835. pri->pvts[idx] = NULL;
  4836. ast_mutex_unlock(&pri->lock);
  4837. return;
  4838. }
  4839. }
  4840. ast_mutex_unlock(&pri->lock);
  4841. }
  4842. #endif /* defined(HAVE_PRI) */
  4843. #if defined(HAVE_SS7)
  4844. /*!
  4845. * \internal
  4846. * \brief Unlink the channel interface from the SS7 private pointer array.
  4847. * \since 1.8
  4848. *
  4849. * \param pvt chan_dahdi private interface structure to unlink.
  4850. *
  4851. * \return Nothing
  4852. */
  4853. static void dahdi_unlink_ss7_pvt(struct dahdi_pvt *pvt)
  4854. {
  4855. unsigned idx;
  4856. struct sig_ss7_linkset *ss7;
  4857. ss7 = pvt->ss7;
  4858. if (!ss7) {
  4859. /* Not SS7 signaling so cannot be in a SS7 private pointer array. */
  4860. return;
  4861. }
  4862. ast_mutex_lock(&ss7->lock);
  4863. for (idx = 0; idx < ss7->numchans; ++idx) {
  4864. if (ss7->pvts[idx] == pvt->sig_pvt) {
  4865. ss7->pvts[idx] = NULL;
  4866. ast_mutex_unlock(&ss7->lock);
  4867. return;
  4868. }
  4869. }
  4870. ast_mutex_unlock(&ss7->lock);
  4871. }
  4872. #endif /* defined(HAVE_SS7) */
  4873. static struct dahdi_pvt *find_next_iface_in_span(struct dahdi_pvt *cur)
  4874. {
  4875. if (cur->next && cur->next->span == cur->span) {
  4876. return cur->next;
  4877. } else if (cur->prev && cur->prev->span == cur->span) {
  4878. return cur->prev;
  4879. }
  4880. return NULL;
  4881. }
  4882. static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
  4883. {
  4884. struct dahdi_pvt *p = pvt;
  4885. if (p->manages_span_alarms) {
  4886. struct dahdi_pvt *next = find_next_iface_in_span(p);
  4887. if (next) {
  4888. next->manages_span_alarms = 1;
  4889. }
  4890. }
  4891. /* Remove channel from the list */
  4892. #if defined(HAVE_PRI)
  4893. dahdi_unlink_pri_pvt(p);
  4894. #endif /* defined(HAVE_PRI) */
  4895. #if defined(HAVE_SS7)
  4896. dahdi_unlink_ss7_pvt(p);
  4897. #endif /* defined(HAVE_SS7) */
  4898. switch (pvt->which_iflist) {
  4899. case DAHDI_IFLIST_NONE:
  4900. break;
  4901. case DAHDI_IFLIST_MAIN:
  4902. dahdi_iflist_extract(p);
  4903. break;
  4904. #if defined(HAVE_PRI)
  4905. case DAHDI_IFLIST_NO_B_CHAN:
  4906. if (p->pri) {
  4907. dahdi_nobch_extract(p->pri, p);
  4908. }
  4909. break;
  4910. #endif /* defined(HAVE_PRI) */
  4911. }
  4912. if (p->sig_pvt) {
  4913. if (dahdi_analog_lib_handles(p->sig, 0, 0)) {
  4914. analog_delete(p->sig_pvt);
  4915. }
  4916. switch (p->sig) {
  4917. #if defined(HAVE_PRI)
  4918. case SIG_PRI_LIB_HANDLE_CASES:
  4919. sig_pri_chan_delete(p->sig_pvt);
  4920. break;
  4921. #endif /* defined(HAVE_PRI) */
  4922. #if defined(HAVE_SS7)
  4923. case SIG_SS7:
  4924. sig_ss7_chan_delete(p->sig_pvt);
  4925. break;
  4926. #endif /* defined(HAVE_SS7) */
  4927. default:
  4928. break;
  4929. }
  4930. }
  4931. ast_free(p->cidspill);
  4932. if (p->use_smdi) {
  4933. ao2_cleanup(p->smdi_iface);
  4934. }
  4935. if (p->mwi_event_sub) {
  4936. p->mwi_event_sub = stasis_unsubscribe(p->mwi_event_sub);
  4937. }
  4938. if (p->vars) {
  4939. ast_variables_destroy(p->vars);
  4940. }
  4941. if (p->cc_params) {
  4942. ast_cc_config_params_destroy(p->cc_params);
  4943. }
  4944. p->named_callgroups = ast_unref_namedgroups(p->named_callgroups);
  4945. p->named_pickupgroups = ast_unref_namedgroups(p->named_pickupgroups);
  4946. ast_mutex_destroy(&p->lock);
  4947. dahdi_close_sub(p, SUB_REAL);
  4948. if (p->owner) {
  4949. ast_channel_tech_pvt_set(p->owner, NULL);
  4950. }
  4951. ast_free(p);
  4952. }
  4953. static void destroy_channel(struct dahdi_pvt *cur, int now)
  4954. {
  4955. int i;
  4956. if (!now) {
  4957. /* Do not destroy the channel now if it is owned by someone. */
  4958. if (cur->owner) {
  4959. return;
  4960. }
  4961. for (i = 0; i < 3; i++) {
  4962. if (cur->subs[i].owner) {
  4963. return;
  4964. }
  4965. }
  4966. }
  4967. destroy_dahdi_pvt(cur);
  4968. }
  4969. static void destroy_all_channels(void)
  4970. {
  4971. int chan;
  4972. #if defined(HAVE_PRI)
  4973. unsigned span;
  4974. struct sig_pri_span *pri;
  4975. #endif /* defined(HAVE_PRI) */
  4976. struct dahdi_pvt *p;
  4977. while (num_restart_pending) {
  4978. usleep(1);
  4979. }
  4980. ast_mutex_lock(&iflock);
  4981. /* Destroy all the interfaces and free their memory */
  4982. while (iflist) {
  4983. p = iflist;
  4984. chan = p->channel;
  4985. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  4986. {
  4987. char db_chan_name[20];
  4988. char db_answer[5];
  4989. char state;
  4990. int why = -1;
  4991. snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan);
  4992. if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
  4993. sscanf(db_answer, "%1c:%30d", &state, &why);
  4994. }
  4995. if (!why) {
  4996. /* SRVST persistence is not required */
  4997. ast_db_del(db_chan_name, SRVST_DBKEY);
  4998. }
  4999. }
  5000. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  5001. /* Free associated memory */
  5002. destroy_dahdi_pvt(p);
  5003. ast_verb(3, "Unregistered channel %d\n", chan);
  5004. }
  5005. ifcount = 0;
  5006. ast_mutex_unlock(&iflock);
  5007. #if defined(HAVE_PRI)
  5008. /* Destroy all of the no B channel interface lists */
  5009. for (span = 0; span < NUM_SPANS; ++span) {
  5010. if (!pris[span].dchannels[0]) {
  5011. break;
  5012. }
  5013. pri = &pris[span].pri;
  5014. ast_mutex_lock(&pri->lock);
  5015. while (pri->no_b_chan_iflist) {
  5016. p = pri->no_b_chan_iflist;
  5017. /* Free associated memory */
  5018. destroy_dahdi_pvt(p);
  5019. }
  5020. ast_mutex_unlock(&pri->lock);
  5021. }
  5022. #endif /* defined(HAVE_PRI) */
  5023. }
  5024. #if defined(HAVE_PRI)
  5025. static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
  5026. static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, const char *digits)
  5027. {
  5028. /* Data will be our digit string */
  5029. struct dahdi_pvt *p;
  5030. if (ast_strlen_zero(digits)) {
  5031. ast_debug(1, "No digit string sent to application!\n");
  5032. return -1;
  5033. }
  5034. p = (struct dahdi_pvt *)ast_channel_tech_pvt(chan);
  5035. if (!p) {
  5036. ast_debug(1, "Unable to find technology private\n");
  5037. return -1;
  5038. }
  5039. pri_send_keypad_facility_exec(p->sig_pvt, digits);
  5040. return 0;
  5041. }
  5042. #endif /* defined(HAVE_PRI) */
  5043. #if defined(HAVE_PRI)
  5044. #if defined(HAVE_PRI_PROG_W_CAUSE)
  5045. static char *dahdi_send_callrerouting_facility_app = "DAHDISendCallreroutingFacility";
  5046. static int dahdi_send_callrerouting_facility_exec(struct ast_channel *chan, const char *data)
  5047. {
  5048. /* Data will be our digit string */
  5049. struct dahdi_pvt *pvt;
  5050. char *parse;
  5051. int res;
  5052. AST_DECLARE_APP_ARGS(args,
  5053. AST_APP_ARG(destination);
  5054. AST_APP_ARG(original);
  5055. AST_APP_ARG(reason);
  5056. );
  5057. if (ast_strlen_zero(data)) {
  5058. ast_debug(1, "No data sent to application!\n");
  5059. return -1;
  5060. }
  5061. if (ast_channel_tech(chan) != &dahdi_tech) {
  5062. ast_debug(1, "Only DAHDI technology accepted!\n");
  5063. return -1;
  5064. }
  5065. pvt = (struct dahdi_pvt *) ast_channel_tech_pvt(chan);
  5066. if (!pvt) {
  5067. ast_debug(1, "Unable to find technology private\n");
  5068. return -1;
  5069. }
  5070. switch (pvt->sig) {
  5071. case SIG_PRI_LIB_HANDLE_CASES:
  5072. break;
  5073. default:
  5074. ast_debug(1, "callrerouting attempted on non-ISDN channel %s\n",
  5075. ast_channel_name(chan));
  5076. return -1;
  5077. }
  5078. parse = ast_strdupa(data);
  5079. AST_STANDARD_APP_ARGS(args, parse);
  5080. if (ast_strlen_zero(args.destination)) {
  5081. ast_log(LOG_WARNING, "callrerouting facility requires at least destination number argument\n");
  5082. return -1;
  5083. }
  5084. if (ast_strlen_zero(args.original)) {
  5085. ast_log(LOG_WARNING, "Callrerouting Facility without original called number argument\n");
  5086. args.original = NULL;
  5087. }
  5088. if (ast_strlen_zero(args.reason)) {
  5089. ast_log(LOG_NOTICE, "Callrerouting Facility without diversion reason argument, defaulting to unknown\n");
  5090. args.reason = NULL;
  5091. }
  5092. res = pri_send_callrerouting_facility_exec(pvt->sig_pvt, ast_channel_state(chan),
  5093. args.destination, args.original, args.reason);
  5094. if (!res) {
  5095. /*
  5096. * Wait up to 5 seconds for a reply before hanging up this call
  5097. * leg if the peer does not disconnect first.
  5098. */
  5099. ast_safe_sleep(chan, 5000);
  5100. }
  5101. return -1;
  5102. }
  5103. #endif /* defined(HAVE_PRI_PROG_W_CAUSE) */
  5104. #endif /* defined(HAVE_PRI) */
  5105. #if defined(HAVE_OPENR2)
  5106. static const char * const dahdi_accept_r2_call_app = "DAHDIAcceptR2Call";
  5107. static int dahdi_accept_r2_call_exec(struct ast_channel *chan, const char *data)
  5108. {
  5109. /* data is whether to accept with charge or no charge */
  5110. openr2_call_mode_t accept_mode;
  5111. int res, timeout, maxloops;
  5112. struct ast_frame *f;
  5113. struct dahdi_pvt *p;
  5114. char *parse;
  5115. AST_DECLARE_APP_ARGS(args,
  5116. AST_APP_ARG(charge);
  5117. );
  5118. if (ast_strlen_zero(data)) {
  5119. ast_debug(1, "No data sent to application!\n");
  5120. return -1;
  5121. }
  5122. if (ast_channel_tech(chan) != &dahdi_tech) {
  5123. ast_debug(1, "Only DAHDI technology accepted!\n");
  5124. return -1;
  5125. }
  5126. p = (struct dahdi_pvt *)ast_channel_tech_pvt(chan);
  5127. if (!p) {
  5128. ast_debug(1, "Unable to find technology private!\n");
  5129. return -1;
  5130. }
  5131. parse = ast_strdupa(data);
  5132. AST_STANDARD_APP_ARGS(args, parse);
  5133. if (ast_strlen_zero(args.charge)) {
  5134. ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
  5135. return -1;
  5136. }
  5137. ast_mutex_lock(&p->lock);
  5138. if (!p->mfcr2 || !p->mfcr2call) {
  5139. ast_mutex_unlock(&p->lock);
  5140. ast_debug(1, "Channel %s does not seems to be an R2 active channel!\n", ast_channel_name(chan));
  5141. return -1;
  5142. }
  5143. if (p->mfcr2_call_accepted) {
  5144. ast_mutex_unlock(&p->lock);
  5145. ast_debug(1, "MFC/R2 call already accepted on channel %s!\n", ast_channel_name(chan));
  5146. return 0;
  5147. }
  5148. accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
  5149. if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
  5150. ast_mutex_unlock(&p->lock);
  5151. ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
  5152. return -1;
  5153. }
  5154. ast_mutex_unlock(&p->lock);
  5155. res = 0;
  5156. timeout = 100;
  5157. maxloops = 50; /* wait up to 5 seconds */
  5158. /* we need to read() until the call is accepted */
  5159. while (maxloops > 0) {
  5160. maxloops--;
  5161. if (ast_check_hangup(chan)) {
  5162. break;
  5163. }
  5164. res = ast_waitfor(chan, timeout);
  5165. if (res < 0) {
  5166. ast_debug(1, "ast_waitfor failed on channel %s, going out ...\n", ast_channel_name(chan));
  5167. res = -1;
  5168. break;
  5169. }
  5170. if (res == 0) {
  5171. continue;
  5172. }
  5173. res = 0;
  5174. f = ast_read(chan);
  5175. if (!f) {
  5176. ast_debug(1, "No frame read on channel %s, going out ...\n", ast_channel_name(chan));
  5177. res = -1;
  5178. break;
  5179. }
  5180. if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) {
  5181. ast_debug(1, "Got HANGUP frame on channel %s, going out ...\n", ast_channel_name(chan));
  5182. ast_frfree(f);
  5183. res = -1;
  5184. break;
  5185. }
  5186. ast_frfree(f);
  5187. ast_mutex_lock(&p->lock);
  5188. if (p->mfcr2_call_accepted) {
  5189. ast_mutex_unlock(&p->lock);
  5190. ast_debug(1, "Accepted MFC/R2 call!\n");
  5191. break;
  5192. }
  5193. ast_mutex_unlock(&p->lock);
  5194. }
  5195. if (res == -1) {
  5196. ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
  5197. }
  5198. return res;
  5199. }
  5200. static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(int cause)
  5201. {
  5202. openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
  5203. switch (cause) {
  5204. case AST_CAUSE_USER_BUSY:
  5205. case AST_CAUSE_CALL_REJECTED:
  5206. case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */
  5207. r2cause = OR2_CAUSE_BUSY_NUMBER;
  5208. break;
  5209. case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION:
  5210. case AST_CAUSE_SWITCH_CONGESTION:
  5211. r2cause = OR2_CAUSE_NETWORK_CONGESTION;
  5212. break;
  5213. case AST_CAUSE_UNALLOCATED:
  5214. r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
  5215. break;
  5216. case AST_CAUSE_NETWORK_OUT_OF_ORDER:
  5217. case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
  5218. r2cause = OR2_CAUSE_OUT_OF_ORDER;
  5219. break;
  5220. case AST_CAUSE_NO_ANSWER:
  5221. case AST_CAUSE_NO_USER_RESPONSE:
  5222. r2cause = OR2_CAUSE_NO_ANSWER;
  5223. break;
  5224. default:
  5225. r2cause = OR2_CAUSE_NORMAL_CLEARING;
  5226. break;
  5227. }
  5228. ast_debug(1, "ast cause %d resulted in openr2 cause %d/%s\n",
  5229. cause, r2cause, openr2_proto_get_disconnect_string(r2cause));
  5230. return r2cause;
  5231. }
  5232. #endif
  5233. static int revert_fax_buffers(struct dahdi_pvt *p, struct ast_channel *ast)
  5234. {
  5235. if (p->bufferoverrideinuse) {
  5236. /* faxbuffers are in use, revert them */
  5237. struct dahdi_bufferinfo bi = {
  5238. .txbufpolicy = p->buf_policy,
  5239. .rxbufpolicy = p->buf_policy,
  5240. .bufsize = p->bufsize,
  5241. .numbufs = p->buf_no
  5242. };
  5243. int bpres;
  5244. if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
  5245. ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast_channel_name(ast), strerror(errno));
  5246. }
  5247. p->bufferoverrideinuse = 0;
  5248. return bpres;
  5249. }
  5250. return -1;
  5251. }
  5252. static int dahdi_hangup(struct ast_channel *ast)
  5253. {
  5254. int res = 0;
  5255. int idx,x;
  5256. int law;
  5257. /*static int restore_gains(struct dahdi_pvt *p);*/
  5258. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  5259. struct dahdi_params par;
  5260. ast_debug(1, "dahdi_hangup(%s)\n", ast_channel_name(ast));
  5261. if (!ast_channel_tech_pvt(ast)) {
  5262. ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
  5263. return 0;
  5264. }
  5265. ast_mutex_lock(&p->lock);
  5266. p->exten[0] = '\0';
  5267. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  5268. dahdi_confmute(p, 0);
  5269. restore_gains(p);
  5270. p->ignoredtmf = 0;
  5271. p->waitingfordt.tv_sec = 0;
  5272. res = analog_hangup(p->sig_pvt, ast);
  5273. revert_fax_buffers(p, ast);
  5274. goto hangup_out;
  5275. } else {
  5276. p->cid_num[0] = '\0';
  5277. p->cid_name[0] = '\0';
  5278. p->cid_subaddr[0] = '\0';
  5279. }
  5280. #if defined(HAVE_PRI)
  5281. if (dahdi_sig_pri_lib_handles(p->sig)) {
  5282. x = 1;
  5283. ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
  5284. dahdi_confmute(p, 0);
  5285. p->muting = 0;
  5286. restore_gains(p);
  5287. if (p->dsp) {
  5288. ast_dsp_free(p->dsp);
  5289. p->dsp = NULL;
  5290. }
  5291. p->ignoredtmf = 0;
  5292. /* Real channel, do some fixup */
  5293. p->subs[SUB_REAL].owner = NULL;
  5294. p->subs[SUB_REAL].needbusy = 0;
  5295. dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
  5296. p->owner = NULL;
  5297. p->cid_tag[0] = '\0';
  5298. p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
  5299. p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
  5300. p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
  5301. p->outgoing = 0;
  5302. p->digital = 0;
  5303. p->faxhandled = 0;
  5304. p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
  5305. revert_fax_buffers(p, ast);
  5306. p->law = p->law_default;
  5307. law = p->law_default;
  5308. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
  5309. if (res < 0) {
  5310. ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
  5311. p->channel, strerror(errno));
  5312. }
  5313. sig_pri_hangup(p->sig_pvt, ast);
  5314. tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
  5315. dahdi_ec_disable(p);
  5316. x = 0;
  5317. ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
  5318. p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
  5319. p->rdnis[0] = '\0';
  5320. dahdi_conf_update(p);
  5321. reset_conf(p);
  5322. /* Restore data mode */
  5323. x = 0;
  5324. ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
  5325. if (num_restart_pending == 0) {
  5326. restart_monitor();
  5327. }
  5328. goto hangup_out;
  5329. }
  5330. #endif /* defined(HAVE_PRI) */
  5331. #if defined(HAVE_SS7)
  5332. if (p->sig == SIG_SS7) {
  5333. x = 1;
  5334. ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
  5335. dahdi_confmute(p, 0);
  5336. p->muting = 0;
  5337. restore_gains(p);
  5338. if (p->dsp) {
  5339. ast_dsp_free(p->dsp);
  5340. p->dsp = NULL;
  5341. }
  5342. p->ignoredtmf = 0;
  5343. /* Real channel, do some fixup */
  5344. p->subs[SUB_REAL].owner = NULL;
  5345. p->subs[SUB_REAL].needbusy = 0;
  5346. dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
  5347. p->owner = NULL;
  5348. p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
  5349. p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
  5350. p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
  5351. p->outgoing = 0;
  5352. p->digital = 0;
  5353. p->faxhandled = 0;
  5354. p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
  5355. revert_fax_buffers(p, ast);
  5356. p->law = p->law_default;
  5357. law = p->law_default;
  5358. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
  5359. if (res < 0) {
  5360. ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
  5361. p->channel, strerror(errno));
  5362. }
  5363. sig_ss7_hangup(p->sig_pvt, ast);
  5364. tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
  5365. dahdi_ec_disable(p);
  5366. x = 0;
  5367. ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
  5368. p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
  5369. dahdi_conf_update(p);
  5370. reset_conf(p);
  5371. /* Restore data mode */
  5372. x = 0;
  5373. ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
  5374. if (num_restart_pending == 0) {
  5375. restart_monitor();
  5376. }
  5377. goto hangup_out;
  5378. }
  5379. #endif /* defined(HAVE_SS7) */
  5380. idx = dahdi_get_index(ast, p, 1);
  5381. dahdi_confmute(p, 0);
  5382. p->muting = 0;
  5383. restore_gains(p);
  5384. if (p->origcid_num) {
  5385. ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
  5386. ast_free(p->origcid_num);
  5387. p->origcid_num = NULL;
  5388. }
  5389. if (p->origcid_name) {
  5390. ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
  5391. ast_free(p->origcid_name);
  5392. p->origcid_name = NULL;
  5393. }
  5394. if (p->dsp)
  5395. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
  5396. ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
  5397. p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
  5398. p->ignoredtmf = 0;
  5399. if (idx > -1) {
  5400. /* Real channel, do some fixup */
  5401. p->subs[idx].owner = NULL;
  5402. p->subs[idx].needanswer = 0;
  5403. p->subs[idx].needflash = 0;
  5404. p->subs[idx].needringing = 0;
  5405. p->subs[idx].needbusy = 0;
  5406. p->subs[idx].needcongestion = 0;
  5407. p->subs[idx].linear = 0;
  5408. p->polarity = POLARITY_IDLE;
  5409. dahdi_setlinear(p->subs[idx].dfd, 0);
  5410. if (idx == SUB_REAL) {
  5411. if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
  5412. ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
  5413. if (p->subs[SUB_CALLWAIT].inthreeway) {
  5414. /* We had flipped over to answer a callwait and now it's gone */
  5415. ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
  5416. /* Move to the call-wait, but un-own us until they flip back. */
  5417. swap_subs(p, SUB_CALLWAIT, SUB_REAL);
  5418. unalloc_sub(p, SUB_CALLWAIT);
  5419. p->owner = NULL;
  5420. } else {
  5421. /* The three way hung up, but we still have a call wait */
  5422. ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
  5423. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  5424. unalloc_sub(p, SUB_THREEWAY);
  5425. if (p->subs[SUB_REAL].inthreeway) {
  5426. /* This was part of a three way call. Immediately make way for
  5427. another call */
  5428. ast_debug(1, "Call was complete, setting owner to former third call\n");
  5429. p->owner = p->subs[SUB_REAL].owner;
  5430. } else {
  5431. /* This call hasn't been completed yet... Set owner to NULL */
  5432. ast_debug(1, "Call was incomplete, setting owner to NULL\n");
  5433. p->owner = NULL;
  5434. }
  5435. p->subs[SUB_REAL].inthreeway = 0;
  5436. }
  5437. } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
  5438. /* Move to the call-wait and switch back to them. */
  5439. swap_subs(p, SUB_CALLWAIT, SUB_REAL);
  5440. unalloc_sub(p, SUB_CALLWAIT);
  5441. p->owner = p->subs[SUB_REAL].owner;
  5442. if (ast_channel_state(p->owner) != AST_STATE_UP)
  5443. p->subs[SUB_REAL].needanswer = 1;
  5444. ast_queue_unhold(p->subs[SUB_REAL].owner);
  5445. } else if (p->subs[SUB_THREEWAY].dfd > -1) {
  5446. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  5447. unalloc_sub(p, SUB_THREEWAY);
  5448. if (p->subs[SUB_REAL].inthreeway) {
  5449. /* This was part of a three way call. Immediately make way for
  5450. another call */
  5451. ast_debug(1, "Call was complete, setting owner to former third call\n");
  5452. p->owner = p->subs[SUB_REAL].owner;
  5453. } else {
  5454. /* This call hasn't been completed yet... Set owner to NULL */
  5455. ast_debug(1, "Call was incomplete, setting owner to NULL\n");
  5456. p->owner = NULL;
  5457. }
  5458. p->subs[SUB_REAL].inthreeway = 0;
  5459. }
  5460. } else if (idx == SUB_CALLWAIT) {
  5461. /* Ditch the holding callwait call, and immediately make it availabe */
  5462. if (p->subs[SUB_CALLWAIT].inthreeway) {
  5463. /* This is actually part of a three way, placed on hold. Place the third part
  5464. on music on hold now */
  5465. if (p->subs[SUB_THREEWAY].owner) {
  5466. ast_queue_hold(p->subs[SUB_THREEWAY].owner, p->mohsuggest);
  5467. }
  5468. p->subs[SUB_THREEWAY].inthreeway = 0;
  5469. /* Make it the call wait now */
  5470. swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
  5471. unalloc_sub(p, SUB_THREEWAY);
  5472. } else
  5473. unalloc_sub(p, SUB_CALLWAIT);
  5474. } else if (idx == SUB_THREEWAY) {
  5475. if (p->subs[SUB_CALLWAIT].inthreeway) {
  5476. /* The other party of the three way call is currently in a call-wait state.
  5477. Start music on hold for them, and take the main guy out of the third call */
  5478. if (p->subs[SUB_CALLWAIT].owner) {
  5479. ast_queue_hold(p->subs[SUB_CALLWAIT].owner, p->mohsuggest);
  5480. }
  5481. p->subs[SUB_CALLWAIT].inthreeway = 0;
  5482. }
  5483. p->subs[SUB_REAL].inthreeway = 0;
  5484. /* If this was part of a three way call index, let us make
  5485. another three way call */
  5486. unalloc_sub(p, SUB_THREEWAY);
  5487. } else {
  5488. /* This wasn't any sort of call, but how are we an index? */
  5489. ast_log(LOG_WARNING, "Index found but not any type of call?\n");
  5490. }
  5491. }
  5492. if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
  5493. p->owner = NULL;
  5494. p->ringt = 0;
  5495. p->distinctivering = 0;
  5496. p->confirmanswer = 0;
  5497. p->outgoing = 0;
  5498. p->digital = 0;
  5499. p->faxhandled = 0;
  5500. p->pulsedial = 0;
  5501. if (p->dsp) {
  5502. ast_dsp_free(p->dsp);
  5503. p->dsp = NULL;
  5504. }
  5505. revert_fax_buffers(p, ast);
  5506. p->law = p->law_default;
  5507. law = p->law_default;
  5508. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
  5509. if (res < 0)
  5510. ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
  5511. /* Perform low level hangup if no owner left */
  5512. #ifdef HAVE_OPENR2
  5513. if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
  5514. ast_debug(1, "disconnecting MFC/R2 call on chan %d\n", p->channel);
  5515. /* If it's an incoming call, check the mfcr2_forced_release setting */
  5516. if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
  5517. dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
  5518. } else {
  5519. const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE");
  5520. int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
  5521. openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
  5522. : dahdi_ast_cause_to_r2_cause(ast_channel_hangupcause(ast));
  5523. dahdi_r2_disconnect_call(p, r2cause);
  5524. }
  5525. } else if (p->mfcr2call) {
  5526. ast_debug(1, "Clearing call request on channel %d\n", p->channel);
  5527. /* since ast_request() was called but not ast_call() we have not yet dialed
  5528. and the openr2 stack will not call on_call_end callback, we need to unset
  5529. the mfcr2call flag and bump the monitor count so the monitor thread can take
  5530. care of this channel events from now on */
  5531. p->mfcr2call = 0;
  5532. }
  5533. #endif
  5534. switch (p->sig) {
  5535. case SIG_SS7:
  5536. case SIG_MFCR2:
  5537. case SIG_PRI_LIB_HANDLE_CASES:
  5538. case 0:
  5539. break;
  5540. default:
  5541. res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
  5542. break;
  5543. }
  5544. if (res < 0) {
  5545. ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast_channel_name(ast));
  5546. }
  5547. switch (p->sig) {
  5548. case SIG_FXOGS:
  5549. case SIG_FXOLS:
  5550. case SIG_FXOKS:
  5551. memset(&par, 0, sizeof(par));
  5552. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
  5553. if (!res) {
  5554. struct analog_pvt *analog_p = p->sig_pvt;
  5555. #if 0
  5556. ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
  5557. #endif
  5558. /* If they're off hook, try playing congestion */
  5559. if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
  5560. tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  5561. else
  5562. tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
  5563. analog_p->fxsoffhookstate = par.rxisoffhook;
  5564. }
  5565. break;
  5566. case SIG_FXSGS:
  5567. case SIG_FXSLS:
  5568. case SIG_FXSKS:
  5569. /* Make sure we're not made available for at least two seconds assuming
  5570. we were actually used for an inbound or outbound call. */
  5571. if (ast_channel_state(ast) != AST_STATE_RESERVED) {
  5572. time(&p->guardtime);
  5573. p->guardtime += 2;
  5574. }
  5575. break;
  5576. default:
  5577. tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
  5578. break;
  5579. }
  5580. if (p->sig)
  5581. dahdi_ec_disable(p);
  5582. x = 0;
  5583. ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
  5584. ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
  5585. p->didtdd = 0;
  5586. p->callwaitcas = 0;
  5587. p->callwaiting = p->permcallwaiting;
  5588. p->hidecallerid = p->permhidecallerid;
  5589. p->waitingfordt.tv_sec = 0;
  5590. p->dialing = 0;
  5591. p->rdnis[0] = '\0';
  5592. dahdi_conf_update(p);
  5593. reset_conf(p);
  5594. /* Restore data mode */
  5595. switch (p->sig) {
  5596. case SIG_PRI_LIB_HANDLE_CASES:
  5597. case SIG_SS7:
  5598. x = 0;
  5599. ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
  5600. break;
  5601. default:
  5602. break;
  5603. }
  5604. if (num_restart_pending == 0)
  5605. restart_monitor();
  5606. }
  5607. p->callwaitingrepeat = 0;
  5608. p->cidcwexpire = 0;
  5609. p->cid_suppress_expire = 0;
  5610. p->oprmode = 0;
  5611. hangup_out:
  5612. ast_channel_tech_pvt_set(ast, NULL);
  5613. ast_free(p->cidspill);
  5614. p->cidspill = NULL;
  5615. ast_mutex_unlock(&p->lock);
  5616. ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
  5617. ast_mutex_lock(&iflock);
  5618. if (p->restartpending) {
  5619. num_restart_pending--;
  5620. }
  5621. if (p->destroy) {
  5622. destroy_channel(p, 0);
  5623. }
  5624. ast_mutex_unlock(&iflock);
  5625. ast_module_unref(ast_module_info->self);
  5626. return 0;
  5627. }
  5628. static int dahdi_answer(struct ast_channel *ast)
  5629. {
  5630. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  5631. int res = 0;
  5632. int idx;
  5633. ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */
  5634. ast_mutex_lock(&p->lock);
  5635. idx = dahdi_get_index(ast, p, 0);
  5636. if (idx < 0)
  5637. idx = SUB_REAL;
  5638. /* nothing to do if a radio channel */
  5639. if ((p->radio || (p->oprmode < 0))) {
  5640. ast_mutex_unlock(&p->lock);
  5641. return 0;
  5642. }
  5643. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  5644. res = analog_answer(p->sig_pvt, ast);
  5645. ast_mutex_unlock(&p->lock);
  5646. return res;
  5647. }
  5648. switch (p->sig) {
  5649. #if defined(HAVE_PRI)
  5650. case SIG_PRI_LIB_HANDLE_CASES:
  5651. res = sig_pri_answer(p->sig_pvt, ast);
  5652. break;
  5653. #endif /* defined(HAVE_PRI) */
  5654. #if defined(HAVE_SS7)
  5655. case SIG_SS7:
  5656. res = sig_ss7_answer(p->sig_pvt, ast);
  5657. break;
  5658. #endif /* defined(HAVE_SS7) */
  5659. #ifdef HAVE_OPENR2
  5660. case SIG_MFCR2:
  5661. if (!p->mfcr2_call_accepted) {
  5662. /* The call was not accepted on offer nor the user, so it must be accepted now before answering,
  5663. openr2_chan_answer_call will be called when the callback on_call_accepted is executed */
  5664. p->mfcr2_answer_pending = 1;
  5665. if (p->mfcr2_charge_calls) {
  5666. ast_debug(1, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel);
  5667. openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
  5668. } else {
  5669. ast_debug(1, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel);
  5670. openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
  5671. }
  5672. } else {
  5673. ast_debug(1, "Answering MFC/R2 call on chan %d\n", p->channel);
  5674. dahdi_r2_answer(p);
  5675. }
  5676. break;
  5677. #endif
  5678. case 0:
  5679. ast_mutex_unlock(&p->lock);
  5680. return 0;
  5681. default:
  5682. ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
  5683. res = -1;
  5684. break;
  5685. }
  5686. ast_mutex_unlock(&p->lock);
  5687. return res;
  5688. }
  5689. void dahdi_dtmf_detect_disable(struct dahdi_pvt *p)
  5690. {
  5691. int val = 0;
  5692. p->ignoredtmf = 1;
  5693. ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
  5694. if (!p->hardwaredtmf && p->dsp) {
  5695. p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
  5696. ast_dsp_set_features(p->dsp, p->dsp_features);
  5697. }
  5698. }
  5699. void dahdi_dtmf_detect_enable(struct dahdi_pvt *p)
  5700. {
  5701. int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
  5702. if (p->channel == CHAN_PSEUDO)
  5703. return;
  5704. p->ignoredtmf = 0;
  5705. ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
  5706. if (!p->hardwaredtmf && p->dsp) {
  5707. p->dsp_features |= DSP_FEATURE_DIGIT_DETECT;
  5708. ast_dsp_set_features(p->dsp, p->dsp_features);
  5709. }
  5710. }
  5711. static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen)
  5712. {
  5713. char *cp;
  5714. struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
  5715. /* all supported options require data */
  5716. if (!p || !data || (*datalen < 1)) {
  5717. errno = EINVAL;
  5718. return -1;
  5719. }
  5720. switch (option) {
  5721. case AST_OPTION_DIGIT_DETECT:
  5722. cp = (char *) data;
  5723. *cp = p->ignoredtmf ? 0 : 1;
  5724. ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
  5725. break;
  5726. case AST_OPTION_FAX_DETECT:
  5727. cp = (char *) data;
  5728. *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1;
  5729. ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
  5730. break;
  5731. case AST_OPTION_CC_AGENT_TYPE:
  5732. #if defined(HAVE_PRI)
  5733. #if defined(HAVE_PRI_CCSS)
  5734. if (dahdi_sig_pri_lib_handles(p->sig)) {
  5735. ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen);
  5736. break;
  5737. }
  5738. #endif /* defined(HAVE_PRI_CCSS) */
  5739. #endif /* defined(HAVE_PRI) */
  5740. return -1;
  5741. default:
  5742. return -1;
  5743. }
  5744. errno = 0;
  5745. return 0;
  5746. }
  5747. static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
  5748. {
  5749. char *cp;
  5750. signed char *scp;
  5751. int x;
  5752. int idx;
  5753. struct dahdi_pvt *p = ast_channel_tech_pvt(chan), *pp;
  5754. struct oprmode *oprmode;
  5755. /* all supported options require data */
  5756. if (!p || !data || (datalen < 1)) {
  5757. errno = EINVAL;
  5758. return -1;
  5759. }
  5760. switch (option) {
  5761. case AST_OPTION_TXGAIN:
  5762. scp = (signed char *) data;
  5763. idx = dahdi_get_index(chan, p, 0);
  5764. if (idx < 0) {
  5765. ast_log(LOG_WARNING, "No index in TXGAIN?\n");
  5766. return -1;
  5767. }
  5768. ast_debug(1, "Setting actual tx gain on %s to %f\n", ast_channel_name(chan), p->txgain + (float) *scp);
  5769. return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law);
  5770. case AST_OPTION_RXGAIN:
  5771. scp = (signed char *) data;
  5772. idx = dahdi_get_index(chan, p, 0);
  5773. if (idx < 0) {
  5774. ast_log(LOG_WARNING, "No index in RXGAIN?\n");
  5775. return -1;
  5776. }
  5777. ast_debug(1, "Setting actual rx gain on %s to %f\n", ast_channel_name(chan), p->rxgain + (float) *scp);
  5778. return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law);
  5779. case AST_OPTION_TONE_VERIFY:
  5780. if (!p->dsp)
  5781. break;
  5782. cp = (char *) data;
  5783. switch (*cp) {
  5784. case 1:
  5785. ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",ast_channel_name(chan));
  5786. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */
  5787. break;
  5788. case 2:
  5789. ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",ast_channel_name(chan));
  5790. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */
  5791. break;
  5792. default:
  5793. ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",ast_channel_name(chan));
  5794. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */
  5795. break;
  5796. }
  5797. break;
  5798. case AST_OPTION_TDD:
  5799. /* turn on or off TDD */
  5800. cp = (char *) data;
  5801. p->mate = 0;
  5802. if (!*cp) { /* turn it off */
  5803. ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",ast_channel_name(chan));
  5804. if (p->tdd)
  5805. tdd_free(p->tdd);
  5806. p->tdd = 0;
  5807. break;
  5808. }
  5809. ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n",
  5810. (*cp == 2) ? "MATE" : "ON", (int) *cp, ast_channel_name(chan));
  5811. dahdi_ec_disable(p);
  5812. /* otherwise, turn it on */
  5813. if (!p->didtdd) { /* if havent done it yet */
  5814. unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
  5815. unsigned char *buf;
  5816. int size, res, fd, len;
  5817. struct pollfd fds[1];
  5818. buf = mybuf;
  5819. memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
  5820. ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */
  5821. len = 40000;
  5822. idx = dahdi_get_index(chan, p, 0);
  5823. if (idx < 0) {
  5824. ast_log(LOG_WARNING, "No index in TDD?\n");
  5825. return -1;
  5826. }
  5827. fd = p->subs[idx].dfd;
  5828. while (len) {
  5829. if (ast_check_hangup(chan))
  5830. return -1;
  5831. size = len;
  5832. if (size > READ_SIZE)
  5833. size = READ_SIZE;
  5834. fds[0].fd = fd;
  5835. fds[0].events = POLLPRI | POLLOUT;
  5836. fds[0].revents = 0;
  5837. res = poll(fds, 1, -1);
  5838. if (!res) {
  5839. ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
  5840. continue;
  5841. }
  5842. /* if got exception */
  5843. if (fds[0].revents & POLLPRI)
  5844. return -1;
  5845. if (!(fds[0].revents & POLLOUT)) {
  5846. ast_debug(1, "write fd not ready on channel %d\n", p->channel);
  5847. continue;
  5848. }
  5849. res = write(fd, buf, size);
  5850. if (res != size) {
  5851. if (res == -1) return -1;
  5852. ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
  5853. break;
  5854. }
  5855. len -= size;
  5856. buf += size;
  5857. }
  5858. p->didtdd = 1; /* set to have done it now */
  5859. }
  5860. if (*cp == 2) { /* Mate mode */
  5861. if (p->tdd)
  5862. tdd_free(p->tdd);
  5863. p->tdd = 0;
  5864. p->mate = 1;
  5865. break;
  5866. }
  5867. if (!p->tdd) { /* if we don't have one yet */
  5868. p->tdd = tdd_new(); /* allocate one */
  5869. }
  5870. break;
  5871. case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */
  5872. if (!p->dsp)
  5873. break;
  5874. cp = (char *) data;
  5875. ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n",
  5876. *cp ? "ON" : "OFF", (int) *cp, ast_channel_name(chan));
  5877. ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
  5878. break;
  5879. case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */
  5880. #if defined(HAVE_PRI)
  5881. if (dahdi_sig_pri_lib_handles(p->sig)
  5882. && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
  5883. /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
  5884. break;
  5885. }
  5886. #endif /* defined(HAVE_PRI) */
  5887. cp = (char *) data;
  5888. if (!*cp) {
  5889. ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", ast_channel_name(chan));
  5890. x = 0;
  5891. dahdi_ec_disable(p);
  5892. } else {
  5893. ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", ast_channel_name(chan));
  5894. x = 1;
  5895. }
  5896. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
  5897. ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
  5898. break;
  5899. case AST_OPTION_OPRMODE: /* Operator services mode */
  5900. oprmode = (struct oprmode *) data;
  5901. /* We don't support operator mode across technologies */
  5902. if (strcasecmp(ast_channel_tech(chan)->type, ast_channel_tech(oprmode->peer)->type)) {
  5903. ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n",
  5904. ast_channel_tech(chan)->type, ast_channel_tech(oprmode->peer)->type);
  5905. errno = EINVAL;
  5906. return -1;
  5907. }
  5908. pp = ast_channel_tech_pvt(oprmode->peer);
  5909. p->oprmode = pp->oprmode = 0;
  5910. /* setup peers */
  5911. p->oprpeer = pp;
  5912. pp->oprpeer = p;
  5913. /* setup modes, if any */
  5914. if (oprmode->mode)
  5915. {
  5916. pp->oprmode = oprmode->mode;
  5917. p->oprmode = -oprmode->mode;
  5918. }
  5919. ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n",
  5920. oprmode->mode, ast_channel_name(chan),ast_channel_name(oprmode->peer));
  5921. break;
  5922. case AST_OPTION_ECHOCAN:
  5923. cp = (char *) data;
  5924. if (*cp) {
  5925. ast_debug(1, "Enabling echo cancellation on %s\n", ast_channel_name(chan));
  5926. dahdi_ec_enable(p);
  5927. } else {
  5928. ast_debug(1, "Disabling echo cancellation on %s\n", ast_channel_name(chan));
  5929. dahdi_ec_disable(p);
  5930. }
  5931. break;
  5932. case AST_OPTION_DIGIT_DETECT:
  5933. cp = (char *) data;
  5934. ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
  5935. if (*cp) {
  5936. dahdi_dtmf_detect_enable(p);
  5937. } else {
  5938. dahdi_dtmf_detect_disable(p);
  5939. }
  5940. break;
  5941. case AST_OPTION_FAX_DETECT:
  5942. cp = (char *) data;
  5943. if (p->dsp) {
  5944. ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
  5945. if (*cp) {
  5946. p->dsp_features |= DSP_FEATURE_FAX_DETECT;
  5947. } else {
  5948. p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
  5949. }
  5950. ast_dsp_set_features(p->dsp, p->dsp_features);
  5951. }
  5952. break;
  5953. default:
  5954. return -1;
  5955. }
  5956. errno = 0;
  5957. return 0;
  5958. }
  5959. static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
  5960. {
  5961. struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
  5962. int res = 0;
  5963. if (!p) {
  5964. /* No private structure! */
  5965. *buf = '\0';
  5966. return -1;
  5967. }
  5968. if (!strcasecmp(data, "rxgain")) {
  5969. ast_mutex_lock(&p->lock);
  5970. snprintf(buf, len, "%f", p->rxgain);
  5971. ast_mutex_unlock(&p->lock);
  5972. } else if (!strcasecmp(data, "txgain")) {
  5973. ast_mutex_lock(&p->lock);
  5974. snprintf(buf, len, "%f", p->txgain);
  5975. ast_mutex_unlock(&p->lock);
  5976. } else if (!strcasecmp(data, "dahdi_channel")) {
  5977. ast_mutex_lock(&p->lock);
  5978. snprintf(buf, len, "%d", p->channel);
  5979. ast_mutex_unlock(&p->lock);
  5980. } else if (!strcasecmp(data, "dahdi_span")) {
  5981. ast_mutex_lock(&p->lock);
  5982. snprintf(buf, len, "%d", p->span);
  5983. ast_mutex_unlock(&p->lock);
  5984. } else if (!strcasecmp(data, "dahdi_type")) {
  5985. ast_mutex_lock(&p->lock);
  5986. switch (p->sig) {
  5987. #if defined(HAVE_OPENR2)
  5988. case SIG_MFCR2:
  5989. ast_copy_string(buf, "mfc/r2", len);
  5990. break;
  5991. #endif /* defined(HAVE_OPENR2) */
  5992. #if defined(HAVE_PRI)
  5993. case SIG_PRI_LIB_HANDLE_CASES:
  5994. ast_copy_string(buf, "pri", len);
  5995. break;
  5996. #endif /* defined(HAVE_PRI) */
  5997. case 0:
  5998. ast_copy_string(buf, "pseudo", len);
  5999. break;
  6000. #if defined(HAVE_SS7)
  6001. case SIG_SS7:
  6002. ast_copy_string(buf, "ss7", len);
  6003. break;
  6004. #endif /* defined(HAVE_SS7) */
  6005. default:
  6006. /* The only thing left is analog ports. */
  6007. ast_copy_string(buf, "analog", len);
  6008. break;
  6009. }
  6010. ast_mutex_unlock(&p->lock);
  6011. #if defined(HAVE_PRI)
  6012. #if defined(HAVE_PRI_REVERSE_CHARGE)
  6013. } else if (!strcasecmp(data, "reversecharge")) {
  6014. ast_mutex_lock(&p->lock);
  6015. switch (p->sig) {
  6016. case SIG_PRI_LIB_HANDLE_CASES:
  6017. snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication);
  6018. break;
  6019. default:
  6020. *buf = '\0';
  6021. res = -1;
  6022. break;
  6023. }
  6024. ast_mutex_unlock(&p->lock);
  6025. #endif
  6026. #if defined(HAVE_PRI_SETUP_KEYPAD)
  6027. } else if (!strcasecmp(data, "keypad_digits")) {
  6028. ast_mutex_lock(&p->lock);
  6029. switch (p->sig) {
  6030. case SIG_PRI_LIB_HANDLE_CASES:
  6031. ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits,
  6032. len);
  6033. break;
  6034. default:
  6035. *buf = '\0';
  6036. res = -1;
  6037. break;
  6038. }
  6039. ast_mutex_unlock(&p->lock);
  6040. #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
  6041. } else if (!strcasecmp(data, "no_media_path")) {
  6042. ast_mutex_lock(&p->lock);
  6043. switch (p->sig) {
  6044. case SIG_PRI_LIB_HANDLE_CASES:
  6045. /*
  6046. * TRUE if the call is on hold or is call waiting because
  6047. * there is no media path available.
  6048. */
  6049. snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel);
  6050. break;
  6051. default:
  6052. *buf = '\0';
  6053. res = -1;
  6054. break;
  6055. }
  6056. ast_mutex_unlock(&p->lock);
  6057. #endif /* defined(HAVE_PRI) */
  6058. } else {
  6059. *buf = '\0';
  6060. res = -1;
  6061. }
  6062. return res;
  6063. }
  6064. static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
  6065. {
  6066. int res;
  6067. char policy_str[21] = "";
  6068. if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) {
  6069. ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
  6070. return 1;
  6071. }
  6072. if (*num_buffers < 0) {
  6073. ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
  6074. return -1;
  6075. }
  6076. if (!strcasecmp(policy_str, "full")) {
  6077. *policy = DAHDI_POLICY_WHEN_FULL;
  6078. } else if (!strcasecmp(policy_str, "immediate")) {
  6079. *policy = DAHDI_POLICY_IMMEDIATE;
  6080. #if defined(HAVE_DAHDI_HALF_FULL)
  6081. } else if (!strcasecmp(policy_str, "half")) {
  6082. *policy = DAHDI_POLICY_HALF_FULL;
  6083. #endif
  6084. } else {
  6085. ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
  6086. return -1;
  6087. }
  6088. return 0;
  6089. }
  6090. static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
  6091. {
  6092. struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
  6093. int res = 0;
  6094. if (!p) {
  6095. /* No private structure! */
  6096. return -1;
  6097. }
  6098. if (!strcasecmp(data, "buffers")) {
  6099. int num_bufs, policy;
  6100. if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
  6101. struct dahdi_bufferinfo bi = {
  6102. .txbufpolicy = policy,
  6103. .rxbufpolicy = policy,
  6104. .bufsize = p->bufsize,
  6105. .numbufs = num_bufs,
  6106. };
  6107. int bpres;
  6108. if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
  6109. ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
  6110. } else {
  6111. p->bufferoverrideinuse = 1;
  6112. }
  6113. } else {
  6114. res = -1;
  6115. }
  6116. } else if (!strcasecmp(data, "echocan_mode")) {
  6117. if (!strcasecmp(value, "on")) {
  6118. ast_mutex_lock(&p->lock);
  6119. dahdi_ec_enable(p);
  6120. ast_mutex_unlock(&p->lock);
  6121. } else if (!strcasecmp(value, "off")) {
  6122. ast_mutex_lock(&p->lock);
  6123. dahdi_ec_disable(p);
  6124. ast_mutex_unlock(&p->lock);
  6125. #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
  6126. } else if (!strcasecmp(value, "fax")) {
  6127. int blah = 1;
  6128. ast_mutex_lock(&p->lock);
  6129. if (!p->echocanon) {
  6130. dahdi_ec_enable(p);
  6131. }
  6132. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
  6133. ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno));
  6134. }
  6135. ast_mutex_unlock(&p->lock);
  6136. } else if (!strcasecmp(value, "voice")) {
  6137. int blah = 0;
  6138. ast_mutex_lock(&p->lock);
  6139. if (!p->echocanon) {
  6140. dahdi_ec_enable(p);
  6141. }
  6142. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
  6143. ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno));
  6144. }
  6145. ast_mutex_unlock(&p->lock);
  6146. #endif
  6147. } else {
  6148. ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data);
  6149. res = -1;
  6150. }
  6151. } else {
  6152. res = -1;
  6153. }
  6154. return res;
  6155. }
  6156. void dahdi_master_slave_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
  6157. {
  6158. /* Unlink a specific slave or all slaves/masters from a given master */
  6159. int x;
  6160. int hasslaves;
  6161. if (!master)
  6162. return;
  6163. if (needlock) {
  6164. ast_mutex_lock(&master->lock);
  6165. if (slave) {
  6166. while (ast_mutex_trylock(&slave->lock)) {
  6167. DEADLOCK_AVOIDANCE(&master->lock);
  6168. }
  6169. }
  6170. }
  6171. hasslaves = 0;
  6172. for (x = 0; x < MAX_SLAVES; x++) {
  6173. if (master->slaves[x]) {
  6174. if (!slave || (master->slaves[x] == slave)) {
  6175. /* Take slave out of the conference */
  6176. ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
  6177. conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
  6178. conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
  6179. master->slaves[x]->master = NULL;
  6180. master->slaves[x] = NULL;
  6181. } else
  6182. hasslaves = 1;
  6183. }
  6184. if (!hasslaves)
  6185. master->inconference = 0;
  6186. }
  6187. if (!slave) {
  6188. if (master->master) {
  6189. /* Take master out of the conference */
  6190. conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
  6191. conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
  6192. hasslaves = 0;
  6193. for (x = 0; x < MAX_SLAVES; x++) {
  6194. if (master->master->slaves[x] == master)
  6195. master->master->slaves[x] = NULL;
  6196. else if (master->master->slaves[x])
  6197. hasslaves = 1;
  6198. }
  6199. if (!hasslaves)
  6200. master->master->inconference = 0;
  6201. }
  6202. master->master = NULL;
  6203. }
  6204. dahdi_conf_update(master);
  6205. if (needlock) {
  6206. if (slave)
  6207. ast_mutex_unlock(&slave->lock);
  6208. ast_mutex_unlock(&master->lock);
  6209. }
  6210. }
  6211. void dahdi_master_slave_link(struct dahdi_pvt *slave, struct dahdi_pvt *master)
  6212. {
  6213. int x;
  6214. if (!slave || !master) {
  6215. ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
  6216. return;
  6217. }
  6218. for (x = 0; x < MAX_SLAVES; x++) {
  6219. if (!master->slaves[x]) {
  6220. master->slaves[x] = slave;
  6221. break;
  6222. }
  6223. }
  6224. if (x >= MAX_SLAVES) {
  6225. ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
  6226. master->slaves[MAX_SLAVES - 1] = slave;
  6227. }
  6228. if (slave->master)
  6229. ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
  6230. slave->master = master;
  6231. ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
  6232. }
  6233. static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  6234. {
  6235. struct dahdi_pvt *p = ast_channel_tech_pvt(newchan);
  6236. int x;
  6237. ast_mutex_lock(&p->lock);
  6238. ast_debug(1, "New owner for channel %d is %s\n", p->channel, ast_channel_name(newchan));
  6239. if (p->owner == oldchan) {
  6240. p->owner = newchan;
  6241. }
  6242. for (x = 0; x < 3; x++) {
  6243. if (p->subs[x].owner == oldchan) {
  6244. if (!x) {
  6245. dahdi_master_slave_unlink(NULL, p, 0);
  6246. }
  6247. p->subs[x].owner = newchan;
  6248. }
  6249. }
  6250. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  6251. analog_fixup(oldchan, newchan, p->sig_pvt);
  6252. #if defined(HAVE_PRI)
  6253. } else if (dahdi_sig_pri_lib_handles(p->sig)) {
  6254. sig_pri_fixup(oldchan, newchan, p->sig_pvt);
  6255. #endif /* defined(HAVE_PRI) */
  6256. #if defined(HAVE_SS7)
  6257. } else if (p->sig == SIG_SS7) {
  6258. sig_ss7_fixup(oldchan, newchan, p->sig_pvt);
  6259. #endif /* defined(HAVE_SS7) */
  6260. }
  6261. dahdi_conf_update(p);
  6262. ast_mutex_unlock(&p->lock);
  6263. if (ast_channel_state(newchan) == AST_STATE_RINGING) {
  6264. dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
  6265. }
  6266. return 0;
  6267. }
  6268. static int dahdi_ring_phone(struct dahdi_pvt *p)
  6269. {
  6270. int x;
  6271. int res;
  6272. /* Make sure our transmit state is on hook */
  6273. x = 0;
  6274. x = DAHDI_ONHOOK;
  6275. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  6276. do {
  6277. x = DAHDI_RING;
  6278. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  6279. if (res) {
  6280. switch (errno) {
  6281. case EBUSY:
  6282. case EINTR:
  6283. /* Wait just in case */
  6284. usleep(10000);
  6285. continue;
  6286. case EINPROGRESS:
  6287. res = 0;
  6288. break;
  6289. default:
  6290. ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
  6291. res = 0;
  6292. }
  6293. }
  6294. } while (res);
  6295. return res;
  6296. }
  6297. static void *analog_ss_thread(void *data);
  6298. /*!
  6299. * \internal
  6300. * \brief Attempt to transfer 3-way call.
  6301. *
  6302. * \param p DAHDI private structure.
  6303. *
  6304. * \note On entry these locks are held: real-call, private, 3-way call.
  6305. * \note On exit these locks are held: real-call, private.
  6306. *
  6307. * \retval 0 on success.
  6308. * \retval -1 on error.
  6309. */
  6310. static int attempt_transfer(struct dahdi_pvt *p)
  6311. {
  6312. struct ast_channel *owner_real;
  6313. struct ast_channel *owner_3way;
  6314. enum ast_transfer_result xfer_res;
  6315. int res = 0;
  6316. owner_real = ast_channel_ref(p->subs[SUB_REAL].owner);
  6317. owner_3way = ast_channel_ref(p->subs[SUB_THREEWAY].owner);
  6318. ast_verb(3, "TRANSFERRING %s to %s\n",
  6319. ast_channel_name(owner_3way), ast_channel_name(owner_real));
  6320. ast_channel_unlock(owner_real);
  6321. ast_channel_unlock(owner_3way);
  6322. ast_mutex_unlock(&p->lock);
  6323. xfer_res = ast_bridge_transfer_attended(owner_3way, owner_real);
  6324. if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
  6325. ast_softhangup(owner_3way, AST_SOFTHANGUP_DEV);
  6326. res = -1;
  6327. }
  6328. /* Must leave with these locked. */
  6329. ast_channel_lock(owner_real);
  6330. ast_mutex_lock(&p->lock);
  6331. ast_channel_unref(owner_real);
  6332. ast_channel_unref(owner_3way);
  6333. return res;
  6334. }
  6335. static int check_for_conference(struct dahdi_pvt *p)
  6336. {
  6337. struct dahdi_confinfo ci;
  6338. /* Fine if we already have a master, etc */
  6339. if (p->master || (p->confno > -1))
  6340. return 0;
  6341. memset(&ci, 0, sizeof(ci));
  6342. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
  6343. ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
  6344. return 0;
  6345. }
  6346. /* If we have no master and don't have a confno, then
  6347. if we're in a conference, it's probably a MeetMe room or
  6348. some such, so don't let us 3-way out! */
  6349. if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
  6350. ast_verb(3, "Avoiding 3-way call when in an external conference\n");
  6351. return 1;
  6352. }
  6353. return 0;
  6354. }
  6355. /*! Checks channel for alarms
  6356. * \param p a channel to check for alarms.
  6357. * \returns the alarms on the span to which the channel belongs, or alarms on
  6358. * the channel if no span alarms.
  6359. */
  6360. static int get_alarms(struct dahdi_pvt *p)
  6361. {
  6362. int res;
  6363. struct dahdi_spaninfo zi;
  6364. struct dahdi_params params;
  6365. memset(&zi, 0, sizeof(zi));
  6366. zi.spanno = p->span;
  6367. if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) {
  6368. if (zi.alarms != DAHDI_ALARM_NONE)
  6369. return zi.alarms;
  6370. } else {
  6371. ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
  6372. return 0;
  6373. }
  6374. /* No alarms on the span. Check for channel alarms. */
  6375. memset(&params, 0, sizeof(params));
  6376. if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &params)) >= 0)
  6377. return params.chan_alarms;
  6378. ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
  6379. return DAHDI_ALARM_NONE;
  6380. }
  6381. static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame **dest)
  6382. {
  6383. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  6384. struct ast_frame *f = *dest;
  6385. ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
  6386. f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
  6387. (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
  6388. if (p->confirmanswer) {
  6389. if (f->frametype == AST_FRAME_DTMF_END) {
  6390. ast_debug(1, "Confirm answer on %s!\n", ast_channel_name(ast));
  6391. /* Upon receiving a DTMF digit, consider this an answer confirmation instead
  6392. of a DTMF digit */
  6393. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6394. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  6395. /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
  6396. p->confirmanswer = 0;
  6397. } else {
  6398. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6399. p->subs[idx].f.subclass.integer = 0;
  6400. }
  6401. *dest = &p->subs[idx].f;
  6402. } else if (p->callwaitcas) {
  6403. if (f->frametype == AST_FRAME_DTMF_END) {
  6404. if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
  6405. ast_debug(1, "Got some DTMF, but it's for the CAS\n");
  6406. ast_free(p->cidspill);
  6407. p->cidspill = NULL;
  6408. send_cwcidspill(p);
  6409. }
  6410. p->callwaitcas = 0;
  6411. }
  6412. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6413. p->subs[idx].f.subclass.integer = 0;
  6414. *dest = &p->subs[idx].f;
  6415. } else if (f->subclass.integer == 'f') {
  6416. if (f->frametype == AST_FRAME_DTMF_END) {
  6417. /* Fax tone -- Handle and return NULL */
  6418. if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
  6419. /* If faxbuffers are configured, use them for the fax transmission */
  6420. if (p->usefaxbuffers && !p->bufferoverrideinuse) {
  6421. struct dahdi_bufferinfo bi = {
  6422. .txbufpolicy = p->faxbuf_policy,
  6423. .bufsize = p->bufsize,
  6424. .numbufs = p->faxbuf_no
  6425. };
  6426. int res;
  6427. if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
  6428. ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
  6429. } else {
  6430. p->bufferoverrideinuse = 1;
  6431. }
  6432. }
  6433. p->faxhandled = 1;
  6434. if (p->dsp) {
  6435. p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
  6436. ast_dsp_set_features(p->dsp, p->dsp_features);
  6437. ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
  6438. }
  6439. if (strcmp(ast_channel_exten(ast), "fax")) {
  6440. const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
  6441. /* We need to unlock 'ast' here because ast_exists_extension has the
  6442. * potential to start autoservice on the channel. Such action is prone
  6443. * to deadlock.
  6444. */
  6445. ast_mutex_unlock(&p->lock);
  6446. ast_channel_unlock(ast);
  6447. if (ast_exists_extension(ast, target_context, "fax", 1,
  6448. S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
  6449. ast_channel_lock(ast);
  6450. ast_mutex_lock(&p->lock);
  6451. ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
  6452. /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
  6453. pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
  6454. if (ast_async_goto(ast, target_context, "fax", 1))
  6455. ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
  6456. } else {
  6457. ast_channel_lock(ast);
  6458. ast_mutex_lock(&p->lock);
  6459. ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
  6460. }
  6461. } else {
  6462. ast_debug(1, "Already in a fax extension, not redirecting\n");
  6463. }
  6464. } else {
  6465. ast_debug(1, "Fax already handled\n");
  6466. }
  6467. dahdi_confmute(p, 0);
  6468. }
  6469. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6470. p->subs[idx].f.subclass.integer = 0;
  6471. *dest = &p->subs[idx].f;
  6472. }
  6473. }
  6474. static void publish_span_alarm(int span, const char *alarm_txt)
  6475. {
  6476. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  6477. body = ast_json_pack("{s: i, s: s}",
  6478. "Span", span,
  6479. "Alarm", alarm_txt);
  6480. if (!body) {
  6481. return;
  6482. }
  6483. ast_manager_publish_event("SpanAlarm", EVENT_FLAG_SYSTEM, body);
  6484. }
  6485. static void publish_channel_alarm(int channel, const char *alarm_txt)
  6486. {
  6487. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  6488. RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
  6489. if (!dahdi_chan) {
  6490. return;
  6491. }
  6492. ast_str_set(&dahdi_chan, 0, "%d", channel);
  6493. body = ast_json_pack("{s: s, s: s}",
  6494. "DAHDIChannel", ast_str_buffer(dahdi_chan),
  6495. "Alarm", alarm_txt);
  6496. if (!body) {
  6497. return;
  6498. }
  6499. ast_manager_publish_event("Alarm", EVENT_FLAG_SYSTEM, body);
  6500. }
  6501. static void handle_alarms(struct dahdi_pvt *p, int alms)
  6502. {
  6503. const char *alarm_str;
  6504. #if defined(HAVE_PRI)
  6505. if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) {
  6506. return;
  6507. }
  6508. #endif /* defined(HAVE_PRI) */
  6509. alarm_str = alarm2str(alms);
  6510. if (report_alarms & REPORT_CHANNEL_ALARMS) {
  6511. ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
  6512. publish_channel_alarm(p->channel, alarm_str);
  6513. }
  6514. if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
  6515. ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str);
  6516. publish_span_alarm(p->span, alarm_str);
  6517. }
  6518. }
  6519. static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
  6520. {
  6521. int res, x;
  6522. int idx, mysig;
  6523. char *c;
  6524. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  6525. pthread_t threadid;
  6526. struct ast_channel *chan;
  6527. struct ast_frame *f;
  6528. idx = dahdi_get_index(ast, p, 0);
  6529. if (idx < 0) {
  6530. return &ast_null_frame;
  6531. }
  6532. mysig = p->sig;
  6533. if (p->outsigmod > -1)
  6534. mysig = p->outsigmod;
  6535. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6536. p->subs[idx].f.subclass.integer = 0;
  6537. p->subs[idx].f.datalen = 0;
  6538. p->subs[idx].f.samples = 0;
  6539. p->subs[idx].f.mallocd = 0;
  6540. p->subs[idx].f.offset = 0;
  6541. p->subs[idx].f.src = "dahdi_handle_event";
  6542. p->subs[idx].f.data.ptr = NULL;
  6543. f = &p->subs[idx].f;
  6544. if (p->fake_event) {
  6545. res = p->fake_event;
  6546. p->fake_event = 0;
  6547. } else
  6548. res = dahdi_get_event(p->subs[idx].dfd);
  6549. ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx);
  6550. if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
  6551. p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
  6552. ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
  6553. #if defined(HAVE_PRI)
  6554. if (dahdi_sig_pri_lib_handles(p->sig)
  6555. && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
  6556. && p->pri
  6557. && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
  6558. /* absorb event */
  6559. } else
  6560. #endif /* defined(HAVE_PRI) */
  6561. {
  6562. /* Unmute conference */
  6563. dahdi_confmute(p, 0);
  6564. p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
  6565. p->subs[idx].f.subclass.integer = res & 0xff;
  6566. dahdi_handle_dtmf(ast, idx, &f);
  6567. }
  6568. return f;
  6569. }
  6570. if (res & DAHDI_EVENT_DTMFDOWN) {
  6571. ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
  6572. #if defined(HAVE_PRI)
  6573. if (dahdi_sig_pri_lib_handles(p->sig)
  6574. && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
  6575. && p->pri
  6576. && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
  6577. /* absorb event */
  6578. } else
  6579. #endif /* defined(HAVE_PRI) */
  6580. {
  6581. /* Mute conference */
  6582. dahdi_confmute(p, 1);
  6583. p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN;
  6584. p->subs[idx].f.subclass.integer = res & 0xff;
  6585. dahdi_handle_dtmf(ast, idx, &f);
  6586. }
  6587. return &p->subs[idx].f;
  6588. }
  6589. switch (res) {
  6590. case DAHDI_EVENT_EC_DISABLED:
  6591. ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel);
  6592. p->echocanon = 0;
  6593. break;
  6594. #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
  6595. case DAHDI_EVENT_TX_CED_DETECTED:
  6596. ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
  6597. break;
  6598. case DAHDI_EVENT_RX_CED_DETECTED:
  6599. ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
  6600. break;
  6601. case DAHDI_EVENT_EC_NLP_DISABLED:
  6602. ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel);
  6603. break;
  6604. case DAHDI_EVENT_EC_NLP_ENABLED:
  6605. ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel);
  6606. break;
  6607. #endif
  6608. case DAHDI_EVENT_BITSCHANGED:
  6609. #ifdef HAVE_OPENR2
  6610. if (p->sig != SIG_MFCR2) {
  6611. ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
  6612. } else {
  6613. ast_debug(1, "bits changed in chan %d\n", p->channel);
  6614. openr2_chan_handle_cas(p->r2chan);
  6615. }
  6616. #else
  6617. ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
  6618. #endif
  6619. break;
  6620. case DAHDI_EVENT_PULSE_START:
  6621. /* Stop tone if there's a pulse start and the PBX isn't started */
  6622. if (!ast_channel_pbx(ast))
  6623. tone_zone_play_tone(p->subs[idx].dfd, -1);
  6624. break;
  6625. case DAHDI_EVENT_DIALCOMPLETE:
  6626. /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */
  6627. #if defined(HAVE_PRI)
  6628. if (dahdi_sig_pri_lib_handles(p->sig)) {
  6629. if (p->inalarm) {
  6630. break;
  6631. }
  6632. if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) {
  6633. ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",
  6634. ast_channel_name(ast), strerror(errno));
  6635. return NULL;
  6636. }
  6637. if (x) {
  6638. /* Still dialing in DAHDI driver */
  6639. break;
  6640. }
  6641. /*
  6642. * The ast channel is locked and the private may be locked more
  6643. * than once.
  6644. */
  6645. sig_pri_dial_complete(p->sig_pvt, ast);
  6646. break;
  6647. }
  6648. #endif /* defined(HAVE_PRI) */
  6649. #ifdef HAVE_OPENR2
  6650. if ((p->sig & SIG_MFCR2) && p->r2chan && ast_channel_state(ast) != AST_STATE_UP) {
  6651. /* we don't need to do anything for this event for R2 signaling
  6652. if the call is being setup */
  6653. break;
  6654. }
  6655. #endif
  6656. if (p->inalarm) break;
  6657. if ((p->radio || (p->oprmode < 0))) break;
  6658. if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) {
  6659. ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",ast_channel_name(ast), strerror(errno));
  6660. return NULL;
  6661. }
  6662. if (!x) { /* if not still dialing in driver */
  6663. dahdi_ec_enable(p);
  6664. if (p->echobreak) {
  6665. dahdi_train_ec(p);
  6666. ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
  6667. p->dop.op = DAHDI_DIAL_OP_REPLACE;
  6668. res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
  6669. p->echobreak = 0;
  6670. } else {
  6671. p->dialing = 0;
  6672. if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
  6673. /* if thru with dialing after offhook */
  6674. if (ast_channel_state(ast) == AST_STATE_DIALING_OFFHOOK) {
  6675. ast_setstate(ast, AST_STATE_UP);
  6676. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6677. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  6678. break;
  6679. } else { /* if to state wait for offhook to dial rest */
  6680. /* we now wait for off hook */
  6681. ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
  6682. }
  6683. }
  6684. if (ast_channel_state(ast) == AST_STATE_DIALING) {
  6685. if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
  6686. ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
  6687. } else if (p->confirmanswer || (!p->dialednone
  6688. && ((mysig == SIG_EM) || (mysig == SIG_EM_E1)
  6689. || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD)
  6690. || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF)
  6691. || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA)
  6692. || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB)
  6693. || (mysig == SIG_SF) || (mysig == SIG_SFWINK)
  6694. || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF)
  6695. || (mysig == SIG_SF_FEATB)))) {
  6696. ast_setstate(ast, AST_STATE_RINGING);
  6697. } else if (!p->answeronpolarityswitch) {
  6698. ast_setstate(ast, AST_STATE_UP);
  6699. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6700. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  6701. /* If aops=0 and hops=1, this is necessary */
  6702. p->polarity = POLARITY_REV;
  6703. } else {
  6704. /* Start clean, so we can catch the change to REV polarity when party answers */
  6705. p->polarity = POLARITY_IDLE;
  6706. }
  6707. }
  6708. }
  6709. }
  6710. break;
  6711. case DAHDI_EVENT_ALARM:
  6712. switch (p->sig) {
  6713. #if defined(HAVE_PRI)
  6714. case SIG_PRI_LIB_HANDLE_CASES:
  6715. sig_pri_chan_alarm_notify(p->sig_pvt, 0);
  6716. break;
  6717. #endif /* defined(HAVE_PRI) */
  6718. #if defined(HAVE_SS7)
  6719. case SIG_SS7:
  6720. sig_ss7_set_alarm(p->sig_pvt, 1);
  6721. break;
  6722. #endif /* defined(HAVE_SS7) */
  6723. default:
  6724. p->inalarm = 1;
  6725. break;
  6726. }
  6727. res = get_alarms(p);
  6728. handle_alarms(p, res);
  6729. #ifdef HAVE_PRI
  6730. if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
  6731. /* fall through intentionally */
  6732. } else {
  6733. break;
  6734. }
  6735. #endif
  6736. #if defined(HAVE_SS7)
  6737. if (p->sig == SIG_SS7)
  6738. break;
  6739. #endif /* defined(HAVE_SS7) */
  6740. #ifdef HAVE_OPENR2
  6741. if (p->sig == SIG_MFCR2)
  6742. break;
  6743. #endif
  6744. case DAHDI_EVENT_ONHOOK:
  6745. if (p->radio) {
  6746. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6747. p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY;
  6748. break;
  6749. }
  6750. if (p->oprmode < 0)
  6751. {
  6752. if (p->oprmode != -1) break;
  6753. if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
  6754. {
  6755. /* Make sure it starts ringing */
  6756. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
  6757. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
  6758. save_conference(p->oprpeer);
  6759. tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
  6760. }
  6761. break;
  6762. }
  6763. switch (p->sig) {
  6764. case SIG_FXOLS:
  6765. case SIG_FXOGS:
  6766. case SIG_FXOKS:
  6767. /* Check for some special conditions regarding call waiting */
  6768. if (idx == SUB_REAL) {
  6769. /* The normal line was hung up */
  6770. if (p->subs[SUB_CALLWAIT].owner) {
  6771. /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
  6772. swap_subs(p, SUB_CALLWAIT, SUB_REAL);
  6773. ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
  6774. unalloc_sub(p, SUB_CALLWAIT);
  6775. #if 0
  6776. p->subs[idx].needanswer = 0;
  6777. p->subs[idx].needringing = 0;
  6778. #endif
  6779. p->callwaitingrepeat = 0;
  6780. p->cidcwexpire = 0;
  6781. p->cid_suppress_expire = 0;
  6782. p->owner = NULL;
  6783. /* Don't start streaming audio yet if the incoming call isn't up yet */
  6784. if (ast_channel_state(p->subs[SUB_REAL].owner) != AST_STATE_UP)
  6785. p->dialing = 1;
  6786. dahdi_ring_phone(p);
  6787. } else if (p->subs[SUB_THREEWAY].owner) {
  6788. unsigned int mssinceflash;
  6789. /* Here we have to retain the lock on both the main channel, the 3-way channel, and
  6790. the private structure -- not especially easy or clean */
  6791. while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
  6792. /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
  6793. DLA_UNLOCK(&p->lock);
  6794. CHANNEL_DEADLOCK_AVOIDANCE(ast);
  6795. /* We can grab ast and p in that order, without worry. We should make sure
  6796. nothing seriously bad has happened though like some sort of bizarre double
  6797. masquerade! */
  6798. DLA_LOCK(&p->lock);
  6799. if (p->owner != ast) {
  6800. ast_log(LOG_WARNING, "This isn't good...\n");
  6801. return NULL;
  6802. }
  6803. }
  6804. if (!p->subs[SUB_THREEWAY].owner) {
  6805. ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
  6806. return NULL;
  6807. }
  6808. mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
  6809. ast_debug(1, "Last flash was %u ms ago\n", mssinceflash);
  6810. if (mssinceflash < MIN_MS_SINCE_FLASH) {
  6811. /* It hasn't been long enough since the last flashook. This is probably a bounce on
  6812. hanging up. Hangup both channels now */
  6813. if (p->subs[SUB_THREEWAY].owner)
  6814. ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER);
  6815. ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
  6816. ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
  6817. ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
  6818. } else if ((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) {
  6819. if (p->transfer) {
  6820. /* In any case this isn't a threeway call anymore */
  6821. p->subs[SUB_REAL].inthreeway = 0;
  6822. p->subs[SUB_THREEWAY].inthreeway = 0;
  6823. /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
  6824. if (!p->transfertobusy && ast_channel_state(ast) == AST_STATE_BUSY) {
  6825. ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
  6826. /* Swap subs and dis-own channel */
  6827. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  6828. p->owner = NULL;
  6829. /* Ring the phone */
  6830. dahdi_ring_phone(p);
  6831. } else if (!attempt_transfer(p)) {
  6832. /*
  6833. * Transfer successful. Don't actually hang up at this point.
  6834. * Let our channel legs of the calls die off as the transfer
  6835. * percolates through the core.
  6836. */
  6837. break;
  6838. }
  6839. } else {
  6840. ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
  6841. if (p->subs[SUB_THREEWAY].owner)
  6842. ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
  6843. }
  6844. } else {
  6845. ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
  6846. /* Swap subs and dis-own channel */
  6847. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  6848. p->owner = NULL;
  6849. /* Ring the phone */
  6850. dahdi_ring_phone(p);
  6851. }
  6852. }
  6853. } else {
  6854. ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
  6855. }
  6856. /* Fall through */
  6857. default:
  6858. dahdi_ec_disable(p);
  6859. return NULL;
  6860. }
  6861. break;
  6862. case DAHDI_EVENT_RINGOFFHOOK:
  6863. if (p->inalarm) break;
  6864. if (p->oprmode < 0)
  6865. {
  6866. if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
  6867. {
  6868. /* Make sure it stops ringing */
  6869. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
  6870. tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
  6871. restore_conference(p->oprpeer);
  6872. }
  6873. break;
  6874. }
  6875. if (p->radio)
  6876. {
  6877. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6878. p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY;
  6879. break;
  6880. }
  6881. /* for E911, its supposed to wait for offhook then dial
  6882. the second half of the dial string */
  6883. if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast_channel_state(ast) == AST_STATE_DIALING_OFFHOOK)) {
  6884. c = strchr(p->dialdest, '/');
  6885. if (c)
  6886. c++;
  6887. else
  6888. c = p->dialdest;
  6889. if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
  6890. else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
  6891. if (strlen(p->dop.dialstr) > 4) {
  6892. memset(p->echorest, 'w', sizeof(p->echorest) - 1);
  6893. strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
  6894. p->echorest[sizeof(p->echorest) - 1] = '\0';
  6895. p->echobreak = 1;
  6896. p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
  6897. } else
  6898. p->echobreak = 0;
  6899. if (dahdi_dial_str(p, p->dop.op, p->dop.dialstr)) {
  6900. x = DAHDI_ONHOOK;
  6901. ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  6902. return NULL;
  6903. }
  6904. p->dialing = 1;
  6905. return &p->subs[idx].f;
  6906. }
  6907. switch (p->sig) {
  6908. case SIG_FXOLS:
  6909. case SIG_FXOGS:
  6910. case SIG_FXOKS:
  6911. switch (ast_channel_state(ast)) {
  6912. case AST_STATE_RINGING:
  6913. dahdi_ec_enable(p);
  6914. dahdi_train_ec(p);
  6915. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6916. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  6917. /* Make sure it stops ringing */
  6918. p->subs[SUB_REAL].needringing = 0;
  6919. dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
  6920. ast_debug(1, "channel %d answered\n", p->channel);
  6921. /* Cancel any running CallerID spill */
  6922. ast_free(p->cidspill);
  6923. p->cidspill = NULL;
  6924. restore_conference(p);
  6925. p->dialing = 0;
  6926. p->callwaitcas = 0;
  6927. if (p->confirmanswer) {
  6928. /* Ignore answer if "confirm answer" is enabled */
  6929. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6930. p->subs[idx].f.subclass.integer = 0;
  6931. } else if (!ast_strlen_zero(p->dop.dialstr)) {
  6932. /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
  6933. res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
  6934. if (res) {
  6935. p->dop.dialstr[0] = '\0';
  6936. return NULL;
  6937. } else {
  6938. ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
  6939. p->subs[idx].f.frametype = AST_FRAME_NULL;
  6940. p->subs[idx].f.subclass.integer = 0;
  6941. p->dialing = 1;
  6942. }
  6943. p->dop.dialstr[0] = '\0';
  6944. ast_setstate(ast, AST_STATE_DIALING);
  6945. } else
  6946. ast_setstate(ast, AST_STATE_UP);
  6947. return &p->subs[idx].f;
  6948. case AST_STATE_DOWN:
  6949. ast_setstate(ast, AST_STATE_RING);
  6950. ast_channel_rings_set(ast, 1);
  6951. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  6952. p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK;
  6953. ast_debug(1, "channel %d picked up\n", p->channel);
  6954. return &p->subs[idx].f;
  6955. case AST_STATE_UP:
  6956. /* Make sure it stops ringing */
  6957. dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
  6958. /* Okay -- probably call waiting*/
  6959. ast_queue_unhold(p->owner);
  6960. p->subs[idx].needunhold = 1;
  6961. break;
  6962. case AST_STATE_RESERVED:
  6963. /* Start up dialtone */
  6964. if (has_voicemail(p))
  6965. res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
  6966. else
  6967. res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
  6968. break;
  6969. default:
  6970. ast_log(LOG_WARNING, "FXO phone off hook in weird state %u??\n", ast_channel_state(ast));
  6971. }
  6972. break;
  6973. case SIG_FXSLS:
  6974. case SIG_FXSGS:
  6975. case SIG_FXSKS:
  6976. if (ast_channel_state(ast) == AST_STATE_RING) {
  6977. p->ringt = p->ringt_base;
  6978. }
  6979. /* If we get a ring then we cannot be in
  6980. * reversed polarity. So we reset to idle */
  6981. ast_debug(1, "Setting IDLE polarity due "
  6982. "to ring. Old polarity was %d\n",
  6983. p->polarity);
  6984. p->polarity = POLARITY_IDLE;
  6985. /* Fall through */
  6986. case SIG_EM:
  6987. case SIG_EM_E1:
  6988. case SIG_EMWINK:
  6989. case SIG_FEATD:
  6990. case SIG_FEATDMF:
  6991. case SIG_FEATDMF_TA:
  6992. case SIG_E911:
  6993. case SIG_FGC_CAMA:
  6994. case SIG_FGC_CAMAMF:
  6995. case SIG_FEATB:
  6996. case SIG_SF:
  6997. case SIG_SFWINK:
  6998. case SIG_SF_FEATD:
  6999. case SIG_SF_FEATDMF:
  7000. case SIG_SF_FEATB:
  7001. if (ast_channel_state(ast) == AST_STATE_PRERING)
  7002. ast_setstate(ast, AST_STATE_RING);
  7003. if ((ast_channel_state(ast) == AST_STATE_DOWN) || (ast_channel_state(ast) == AST_STATE_RING)) {
  7004. ast_debug(1, "Ring detected\n");
  7005. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7006. p->subs[idx].f.subclass.integer = AST_CONTROL_RING;
  7007. } else if (p->outgoing && ((ast_channel_state(ast) == AST_STATE_RINGING) || (ast_channel_state(ast) == AST_STATE_DIALING))) {
  7008. ast_debug(1, "Line answered\n");
  7009. if (p->confirmanswer) {
  7010. p->subs[idx].f.frametype = AST_FRAME_NULL;
  7011. p->subs[idx].f.subclass.integer = 0;
  7012. } else {
  7013. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7014. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  7015. ast_setstate(ast, AST_STATE_UP);
  7016. }
  7017. } else if (ast_channel_state(ast) != AST_STATE_RING)
  7018. ast_log(LOG_WARNING, "Ring/Off-hook in strange state %u on channel %d\n", ast_channel_state(ast), p->channel);
  7019. break;
  7020. default:
  7021. ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
  7022. }
  7023. break;
  7024. case DAHDI_EVENT_RINGBEGIN:
  7025. switch (p->sig) {
  7026. case SIG_FXSLS:
  7027. case SIG_FXSGS:
  7028. case SIG_FXSKS:
  7029. if (ast_channel_state(ast) == AST_STATE_RING) {
  7030. p->ringt = p->ringt_base;
  7031. }
  7032. break;
  7033. }
  7034. break;
  7035. case DAHDI_EVENT_RINGERON:
  7036. break;
  7037. case DAHDI_EVENT_NOALARM:
  7038. switch (p->sig) {
  7039. #if defined(HAVE_PRI)
  7040. case SIG_PRI_LIB_HANDLE_CASES:
  7041. sig_pri_chan_alarm_notify(p->sig_pvt, 1);
  7042. break;
  7043. #endif /* defined(HAVE_PRI) */
  7044. #if defined(HAVE_SS7)
  7045. case SIG_SS7:
  7046. sig_ss7_set_alarm(p->sig_pvt, 0);
  7047. break;
  7048. #endif /* defined(HAVE_SS7) */
  7049. default:
  7050. p->inalarm = 0;
  7051. break;
  7052. }
  7053. handle_clear_alarms(p);
  7054. break;
  7055. case DAHDI_EVENT_WINKFLASH:
  7056. if (p->inalarm) break;
  7057. if (p->radio) break;
  7058. if (p->oprmode < 0) break;
  7059. if (p->oprmode > 1)
  7060. {
  7061. struct dahdi_params par;
  7062. memset(&par, 0, sizeof(par));
  7063. if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
  7064. {
  7065. if (!par.rxisoffhook)
  7066. {
  7067. /* Make sure it stops ringing */
  7068. dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
  7069. dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
  7070. save_conference(p);
  7071. tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
  7072. }
  7073. }
  7074. break;
  7075. }
  7076. /* Remember last time we got a flash-hook */
  7077. p->flashtime = ast_tvnow();
  7078. switch (mysig) {
  7079. case SIG_FXOLS:
  7080. case SIG_FXOGS:
  7081. case SIG_FXOKS:
  7082. ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
  7083. idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
  7084. /* Cancel any running CallerID spill */
  7085. ast_free(p->cidspill);
  7086. p->cidspill = NULL;
  7087. restore_conference(p);
  7088. p->callwaitcas = 0;
  7089. if (idx != SUB_REAL) {
  7090. ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
  7091. goto winkflashdone;
  7092. }
  7093. if (p->subs[SUB_CALLWAIT].owner) {
  7094. /* Swap to call-wait */
  7095. swap_subs(p, SUB_REAL, SUB_CALLWAIT);
  7096. tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
  7097. p->owner = p->subs[SUB_REAL].owner;
  7098. ast_debug(1, "Making %s the new owner\n", ast_channel_name(p->owner));
  7099. if (ast_channel_state(p->owner) == AST_STATE_RINGING) {
  7100. ast_setstate(p->owner, AST_STATE_UP);
  7101. p->subs[SUB_REAL].needanswer = 1;
  7102. }
  7103. p->callwaitingrepeat = 0;
  7104. p->cidcwexpire = 0;
  7105. p->cid_suppress_expire = 0;
  7106. /* Start music on hold if appropriate */
  7107. if (!p->subs[SUB_CALLWAIT].inthreeway) {
  7108. ast_queue_hold(p->subs[SUB_CALLWAIT].owner, p->mohsuggest);
  7109. }
  7110. p->subs[SUB_CALLWAIT].needhold = 1;
  7111. ast_queue_hold(p->subs[SUB_REAL].owner, p->mohsuggest);
  7112. p->subs[SUB_REAL].needunhold = 1;
  7113. } else if (!p->subs[SUB_THREEWAY].owner) {
  7114. if (!p->threewaycalling) {
  7115. /* Just send a flash if no 3-way calling */
  7116. p->subs[SUB_REAL].needflash = 1;
  7117. goto winkflashdone;
  7118. } else if (!check_for_conference(p)) {
  7119. struct ast_callid *callid = NULL;
  7120. int callid_created;
  7121. char cid_num[256];
  7122. char cid_name[256];
  7123. cid_num[0] = 0;
  7124. cid_name[0] = 0;
  7125. if (p->dahditrcallerid && p->owner) {
  7126. if (ast_channel_caller(p->owner)->id.number.valid
  7127. && ast_channel_caller(p->owner)->id.number.str) {
  7128. ast_copy_string(cid_num, ast_channel_caller(p->owner)->id.number.str,
  7129. sizeof(cid_num));
  7130. }
  7131. if (ast_channel_caller(p->owner)->id.name.valid
  7132. && ast_channel_caller(p->owner)->id.name.str) {
  7133. ast_copy_string(cid_name, ast_channel_caller(p->owner)->id.name.str,
  7134. sizeof(cid_name));
  7135. }
  7136. }
  7137. /* XXX This section needs much more error checking!!! XXX */
  7138. /* Start a 3-way call if feasible */
  7139. if (!((ast_channel_pbx(ast)) ||
  7140. (ast_channel_state(ast) == AST_STATE_UP) ||
  7141. (ast_channel_state(ast) == AST_STATE_RING))) {
  7142. ast_debug(1, "Flash when call not up or ringing\n");
  7143. goto winkflashdone;
  7144. }
  7145. if (alloc_sub(p, SUB_THREEWAY)) {
  7146. ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
  7147. goto winkflashdone;
  7148. }
  7149. callid_created = ast_callid_threadstorage_auto(&callid);
  7150. /*
  7151. * Make new channel
  7152. *
  7153. * We cannot hold the p or ast locks while creating a new
  7154. * channel.
  7155. */
  7156. ast_mutex_unlock(&p->lock);
  7157. ast_channel_unlock(ast);
  7158. chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, NULL, callid);
  7159. ast_channel_lock(ast);
  7160. ast_mutex_lock(&p->lock);
  7161. if (p->dahditrcallerid) {
  7162. if (!p->origcid_num)
  7163. p->origcid_num = ast_strdup(p->cid_num);
  7164. if (!p->origcid_name)
  7165. p->origcid_name = ast_strdup(p->cid_name);
  7166. ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
  7167. ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
  7168. }
  7169. /* Swap things around between the three-way and real call */
  7170. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  7171. /* Disable echo canceller for better dialing */
  7172. dahdi_ec_disable(p);
  7173. res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
  7174. if (res)
  7175. ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
  7176. p->owner = chan;
  7177. if (!chan) {
  7178. ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
  7179. } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
  7180. ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
  7181. res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  7182. dahdi_ec_enable(p);
  7183. ast_hangup(chan);
  7184. } else {
  7185. ast_verb(3, "Started three way call on channel %d\n", p->channel);
  7186. /* Start music on hold */
  7187. ast_queue_hold(p->subs[SUB_THREEWAY].owner, p->mohsuggest);
  7188. p->subs[SUB_THREEWAY].needhold = 1;
  7189. }
  7190. ast_callid_threadstorage_auto_clean(callid, callid_created);
  7191. }
  7192. } else {
  7193. /* Already have a 3 way call */
  7194. if (p->subs[SUB_THREEWAY].inthreeway) {
  7195. /* Call is already up, drop the last person */
  7196. ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
  7197. /* If the primary call isn't answered yet, use it */
  7198. if ((ast_channel_state(p->subs[SUB_REAL].owner) != AST_STATE_UP) && (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_UP)) {
  7199. /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
  7200. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  7201. p->owner = p->subs[SUB_REAL].owner;
  7202. }
  7203. /* Drop the last call and stop the conference */
  7204. ast_verb(3, "Dropping three-way call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
  7205. ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
  7206. p->subs[SUB_REAL].inthreeway = 0;
  7207. p->subs[SUB_THREEWAY].inthreeway = 0;
  7208. } else {
  7209. /* Lets see what we're up to */
  7210. if (((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) &&
  7211. (p->transfertobusy || (ast_channel_state(ast) != AST_STATE_BUSY))) {
  7212. int otherindex = SUB_THREEWAY;
  7213. ast_verb(3, "Building conference call with %s and %s\n",
  7214. ast_channel_name(p->subs[SUB_THREEWAY].owner),
  7215. ast_channel_name(p->subs[SUB_REAL].owner));
  7216. /* Put them in the threeway, and flip */
  7217. p->subs[SUB_THREEWAY].inthreeway = 1;
  7218. p->subs[SUB_REAL].inthreeway = 1;
  7219. if (ast_channel_state(ast) == AST_STATE_UP) {
  7220. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  7221. otherindex = SUB_REAL;
  7222. }
  7223. if (p->subs[otherindex].owner) {
  7224. ast_queue_unhold(p->subs[otherindex].owner);
  7225. }
  7226. p->subs[otherindex].needunhold = 1;
  7227. p->owner = p->subs[SUB_REAL].owner;
  7228. } else {
  7229. ast_verb(3, "Dumping incomplete call on on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
  7230. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  7231. ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
  7232. p->owner = p->subs[SUB_REAL].owner;
  7233. if (p->subs[SUB_REAL].owner) {
  7234. ast_queue_unhold(p->subs[SUB_REAL].owner);
  7235. }
  7236. p->subs[SUB_REAL].needunhold = 1;
  7237. dahdi_ec_enable(p);
  7238. }
  7239. }
  7240. }
  7241. winkflashdone:
  7242. dahdi_conf_update(p);
  7243. break;
  7244. case SIG_EM:
  7245. case SIG_EM_E1:
  7246. case SIG_FEATD:
  7247. case SIG_SF:
  7248. case SIG_SFWINK:
  7249. case SIG_SF_FEATD:
  7250. case SIG_FXSLS:
  7251. case SIG_FXSGS:
  7252. if (p->dialing)
  7253. ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
  7254. else
  7255. ast_debug(1, "Got wink in weird state %u on channel %d\n", ast_channel_state(ast), p->channel);
  7256. break;
  7257. case SIG_FEATDMF_TA:
  7258. switch (p->whichwink) {
  7259. case 0:
  7260. ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", ast_channel_caller(p->owner)->ani2,
  7261. S_COR(ast_channel_caller(p->owner)->ani.number.valid,
  7262. ast_channel_caller(p->owner)->ani.number.str, ""));
  7263. snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
  7264. ast_channel_caller(p->owner)->ani2,
  7265. S_COR(ast_channel_caller(p->owner)->ani.number.valid,
  7266. ast_channel_caller(p->owner)->ani.number.str, ""));
  7267. break;
  7268. case 1:
  7269. ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
  7270. break;
  7271. case 2:
  7272. ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
  7273. return NULL;
  7274. }
  7275. p->whichwink++;
  7276. /* Fall through */
  7277. case SIG_FEATDMF:
  7278. case SIG_E911:
  7279. case SIG_FGC_CAMAMF:
  7280. case SIG_FGC_CAMA:
  7281. case SIG_FEATB:
  7282. case SIG_SF_FEATDMF:
  7283. case SIG_SF_FEATB:
  7284. case SIG_EMWINK:
  7285. /* FGD MF and EMWINK *Must* wait for wink */
  7286. if (!ast_strlen_zero(p->dop.dialstr)) {
  7287. res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
  7288. if (res) {
  7289. p->dop.dialstr[0] = '\0';
  7290. return NULL;
  7291. } else
  7292. ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
  7293. }
  7294. p->dop.dialstr[0] = '\0';
  7295. break;
  7296. default:
  7297. ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
  7298. }
  7299. break;
  7300. case DAHDI_EVENT_HOOKCOMPLETE:
  7301. if (p->inalarm) break;
  7302. if ((p->radio || (p->oprmode < 0))) break;
  7303. if (p->waitingfordt.tv_sec) break;
  7304. switch (mysig) {
  7305. case SIG_FXSLS: /* only interesting for FXS */
  7306. case SIG_FXSGS:
  7307. case SIG_FXSKS:
  7308. case SIG_EM:
  7309. case SIG_EM_E1:
  7310. case SIG_EMWINK:
  7311. case SIG_FEATD:
  7312. case SIG_SF:
  7313. case SIG_SFWINK:
  7314. case SIG_SF_FEATD:
  7315. if (!ast_strlen_zero(p->dop.dialstr)) {
  7316. res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
  7317. if (res) {
  7318. p->dop.dialstr[0] = '\0';
  7319. return NULL;
  7320. } else
  7321. ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
  7322. }
  7323. p->dop.dialstr[0] = '\0';
  7324. p->dop.op = DAHDI_DIAL_OP_REPLACE;
  7325. break;
  7326. case SIG_FEATDMF:
  7327. case SIG_FEATDMF_TA:
  7328. case SIG_E911:
  7329. case SIG_FGC_CAMA:
  7330. case SIG_FGC_CAMAMF:
  7331. case SIG_FEATB:
  7332. case SIG_SF_FEATDMF:
  7333. case SIG_SF_FEATB:
  7334. ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
  7335. break;
  7336. default:
  7337. break;
  7338. }
  7339. break;
  7340. case DAHDI_EVENT_POLARITY:
  7341. /*
  7342. * If we get a Polarity Switch event, check to see
  7343. * if we should change the polarity state and
  7344. * mark the channel as UP or if this is an indication
  7345. * of remote end disconnect.
  7346. */
  7347. if (p->polarity == POLARITY_IDLE) {
  7348. p->polarity = POLARITY_REV;
  7349. if (p->answeronpolarityswitch &&
  7350. ((ast_channel_state(ast) == AST_STATE_DIALING) ||
  7351. (ast_channel_state(ast) == AST_STATE_RINGING))) {
  7352. ast_debug(1, "Answering on polarity switch!\n");
  7353. ast_setstate(p->owner, AST_STATE_UP);
  7354. if (p->hanguponpolarityswitch) {
  7355. p->polaritydelaytv = ast_tvnow();
  7356. }
  7357. } else
  7358. ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %u\n", p->channel, ast_channel_state(ast));
  7359. }
  7360. /* Removed else statement from here as it was preventing hangups from ever happening*/
  7361. /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
  7362. if (p->hanguponpolarityswitch &&
  7363. (p->polarityonanswerdelay > 0) &&
  7364. (p->polarity == POLARITY_REV) &&
  7365. ((ast_channel_state(ast) == AST_STATE_UP) || (ast_channel_state(ast) == AST_STATE_RING)) ) {
  7366. /* Added log_debug information below to provide a better indication of what is going on */
  7367. ast_debug(1, "Polarity Reversal event occured - DEBUG 1: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast_channel_state(ast), p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
  7368. if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
  7369. ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
  7370. ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
  7371. p->polarity = POLARITY_IDLE;
  7372. } else
  7373. ast_debug(1, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %u\n", p->channel, ast_channel_state(ast));
  7374. } else {
  7375. p->polarity = POLARITY_IDLE;
  7376. ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %u\n", p->channel, ast_channel_state(ast));
  7377. }
  7378. /* Added more log_debug information below to provide a better indication of what is going on */
  7379. ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast_channel_state(ast), p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
  7380. break;
  7381. default:
  7382. ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
  7383. }
  7384. return &p->subs[idx].f;
  7385. }
  7386. static struct ast_frame *__dahdi_exception(struct ast_channel *ast)
  7387. {
  7388. int res;
  7389. int idx;
  7390. struct ast_frame *f;
  7391. int usedindex = -1;
  7392. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  7393. if ((idx = dahdi_get_index(ast, p, 0)) < 0) {
  7394. idx = SUB_REAL;
  7395. }
  7396. p->subs[idx].f.frametype = AST_FRAME_NULL;
  7397. p->subs[idx].f.datalen = 0;
  7398. p->subs[idx].f.samples = 0;
  7399. p->subs[idx].f.mallocd = 0;
  7400. p->subs[idx].f.offset = 0;
  7401. p->subs[idx].f.subclass.integer = 0;
  7402. p->subs[idx].f.delivery = ast_tv(0,0);
  7403. p->subs[idx].f.src = "dahdi_exception";
  7404. p->subs[idx].f.data.ptr = NULL;
  7405. if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
  7406. /* If nobody owns us, absorb the event appropriately, otherwise
  7407. we loop indefinitely. This occurs when, during call waiting, the
  7408. other end hangs up our channel so that it no longer exists, but we
  7409. have neither FLASH'd nor ONHOOK'd to signify our desire to
  7410. change to the other channel. */
  7411. if (p->fake_event) {
  7412. res = p->fake_event;
  7413. p->fake_event = 0;
  7414. } else
  7415. res = dahdi_get_event(p->subs[SUB_REAL].dfd);
  7416. /* Switch to real if there is one and this isn't something really silly... */
  7417. if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
  7418. (res != DAHDI_EVENT_HOOKCOMPLETE)) {
  7419. ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
  7420. p->owner = p->subs[SUB_REAL].owner;
  7421. if (p->owner) {
  7422. ast_queue_unhold(p->owner);
  7423. }
  7424. p->subs[SUB_REAL].needunhold = 1;
  7425. }
  7426. switch (res) {
  7427. case DAHDI_EVENT_ONHOOK:
  7428. dahdi_ec_disable(p);
  7429. if (p->owner) {
  7430. ast_verb(3, "Channel %s still has call, ringing phone\n", ast_channel_name(p->owner));
  7431. dahdi_ring_phone(p);
  7432. p->callwaitingrepeat = 0;
  7433. p->cidcwexpire = 0;
  7434. p->cid_suppress_expire = 0;
  7435. } else
  7436. ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
  7437. dahdi_conf_update(p);
  7438. break;
  7439. case DAHDI_EVENT_RINGOFFHOOK:
  7440. dahdi_ec_enable(p);
  7441. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  7442. if (p->owner && (ast_channel_state(p->owner) == AST_STATE_RINGING)) {
  7443. p->subs[SUB_REAL].needanswer = 1;
  7444. p->dialing = 0;
  7445. }
  7446. break;
  7447. case DAHDI_EVENT_HOOKCOMPLETE:
  7448. case DAHDI_EVENT_RINGERON:
  7449. case DAHDI_EVENT_RINGEROFF:
  7450. /* Do nothing */
  7451. break;
  7452. case DAHDI_EVENT_WINKFLASH:
  7453. p->flashtime = ast_tvnow();
  7454. if (p->owner) {
  7455. ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, ast_channel_name(p->owner));
  7456. if (ast_channel_state(p->owner) != AST_STATE_UP) {
  7457. /* Answer if necessary */
  7458. usedindex = dahdi_get_index(p->owner, p, 0);
  7459. if (usedindex > -1) {
  7460. p->subs[usedindex].needanswer = 1;
  7461. }
  7462. ast_setstate(p->owner, AST_STATE_UP);
  7463. }
  7464. p->callwaitingrepeat = 0;
  7465. p->cidcwexpire = 0;
  7466. p->cid_suppress_expire = 0;
  7467. ast_queue_unhold(p->owner);
  7468. p->subs[SUB_REAL].needunhold = 1;
  7469. } else
  7470. ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
  7471. dahdi_conf_update(p);
  7472. break;
  7473. default:
  7474. ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
  7475. }
  7476. f = &p->subs[idx].f;
  7477. return f;
  7478. }
  7479. if (!(p->radio || (p->oprmode < 0)))
  7480. ast_debug(1, "Exception on %d, channel %d\n", ast_channel_fd(ast, 0), p->channel);
  7481. /* If it's not us, return NULL immediately */
  7482. if (ast != p->owner) {
  7483. if (p->owner) {
  7484. ast_log(LOG_WARNING, "We're %s, not %s\n", ast_channel_name(ast), ast_channel_name(p->owner));
  7485. }
  7486. f = &p->subs[idx].f;
  7487. return f;
  7488. }
  7489. f = dahdi_handle_event(ast);
  7490. if (!f) {
  7491. const char *name = ast_strdupa(ast_channel_name(ast));
  7492. /* Tell the CDR this DAHDI device hung up */
  7493. ast_mutex_unlock(&p->lock);
  7494. ast_channel_unlock(ast);
  7495. ast_set_hangupsource(ast, name, 0);
  7496. ast_channel_lock(ast);
  7497. ast_mutex_lock(&p->lock);
  7498. }
  7499. return f;
  7500. }
  7501. static struct ast_frame *dahdi_exception(struct ast_channel *ast)
  7502. {
  7503. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  7504. struct ast_frame *f;
  7505. ast_mutex_lock(&p->lock);
  7506. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  7507. struct analog_pvt *analog_p = p->sig_pvt;
  7508. f = analog_exception(analog_p, ast);
  7509. } else {
  7510. f = __dahdi_exception(ast);
  7511. }
  7512. ast_mutex_unlock(&p->lock);
  7513. return f;
  7514. }
  7515. static struct ast_frame *dahdi_read(struct ast_channel *ast)
  7516. {
  7517. struct dahdi_pvt *p;
  7518. int res;
  7519. int idx;
  7520. void *readbuf;
  7521. struct ast_frame *f;
  7522. /*
  7523. * For analog channels, we must do deadlock avoidance because
  7524. * analog ports can have more than one Asterisk channel using
  7525. * the same private structure.
  7526. */
  7527. p = ast_channel_tech_pvt(ast);
  7528. while (ast_mutex_trylock(&p->lock)) {
  7529. CHANNEL_DEADLOCK_AVOIDANCE(ast);
  7530. /*
  7531. * Check to see if the channel is still associated with the same
  7532. * private structure. While the Asterisk channel was unlocked
  7533. * the following events may have occured:
  7534. *
  7535. * 1) A masquerade may have associated the channel with another
  7536. * technology or private structure.
  7537. *
  7538. * 2) For PRI calls, call signaling could change the channel
  7539. * association to another B channel (private structure).
  7540. */
  7541. if (ast_channel_tech_pvt(ast) != p) {
  7542. /* The channel is no longer associated. Quit gracefully. */
  7543. return &ast_null_frame;
  7544. }
  7545. }
  7546. idx = dahdi_get_index(ast, p, 0);
  7547. /* Hang up if we don't really exist */
  7548. if (idx < 0) {
  7549. ast_log(LOG_WARNING, "We don't exist?\n");
  7550. ast_mutex_unlock(&p->lock);
  7551. return NULL;
  7552. }
  7553. if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
  7554. ast_mutex_unlock(&p->lock);
  7555. return NULL;
  7556. }
  7557. p->subs[idx].f.frametype = AST_FRAME_NULL;
  7558. p->subs[idx].f.datalen = 0;
  7559. p->subs[idx].f.samples = 0;
  7560. p->subs[idx].f.mallocd = 0;
  7561. p->subs[idx].f.offset = 0;
  7562. p->subs[idx].f.subclass.integer = 0;
  7563. p->subs[idx].f.delivery = ast_tv(0,0);
  7564. p->subs[idx].f.src = "dahdi_read";
  7565. p->subs[idx].f.data.ptr = NULL;
  7566. /* make sure it sends initial key state as first frame */
  7567. if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
  7568. {
  7569. struct dahdi_params ps;
  7570. memset(&ps, 0, sizeof(ps));
  7571. if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
  7572. ast_mutex_unlock(&p->lock);
  7573. return NULL;
  7574. }
  7575. p->firstradio = 1;
  7576. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7577. if (ps.rxisoffhook)
  7578. {
  7579. p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY;
  7580. }
  7581. else
  7582. {
  7583. p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY;
  7584. }
  7585. ast_mutex_unlock(&p->lock);
  7586. return &p->subs[idx].f;
  7587. }
  7588. if (p->ringt > 0) {
  7589. if (!(--p->ringt)) {
  7590. ast_mutex_unlock(&p->lock);
  7591. return NULL;
  7592. }
  7593. }
  7594. #ifdef HAVE_OPENR2
  7595. if (p->mfcr2) {
  7596. openr2_chan_process_event(p->r2chan);
  7597. if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
  7598. struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS } };
  7599. /* if the call is already accepted and we already delivered AST_CONTROL_RINGING
  7600. * now enqueue a progress frame to bridge the media up */
  7601. if (p->mfcr2_call_accepted &&
  7602. !p->mfcr2_progress_sent &&
  7603. ast_channel_state(ast) == AST_STATE_RINGING) {
  7604. ast_debug(1, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel);
  7605. ast_queue_frame(p->owner, &fr);
  7606. p->mfcr2_progress_sent = 1;
  7607. }
  7608. }
  7609. }
  7610. #endif
  7611. if (p->subs[idx].needringing) {
  7612. /* Send ringing frame if requested */
  7613. p->subs[idx].needringing = 0;
  7614. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7615. p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING;
  7616. ast_setstate(ast, AST_STATE_RINGING);
  7617. ast_mutex_unlock(&p->lock);
  7618. return &p->subs[idx].f;
  7619. }
  7620. if (p->subs[idx].needbusy) {
  7621. /* Send busy frame if requested */
  7622. p->subs[idx].needbusy = 0;
  7623. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7624. p->subs[idx].f.subclass.integer = AST_CONTROL_BUSY;
  7625. ast_mutex_unlock(&p->lock);
  7626. return &p->subs[idx].f;
  7627. }
  7628. if (p->subs[idx].needcongestion) {
  7629. /* Send congestion frame if requested */
  7630. p->subs[idx].needcongestion = 0;
  7631. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7632. p->subs[idx].f.subclass.integer = AST_CONTROL_CONGESTION;
  7633. ast_mutex_unlock(&p->lock);
  7634. return &p->subs[idx].f;
  7635. }
  7636. if (p->subs[idx].needanswer) {
  7637. /* Send answer frame if requested */
  7638. p->subs[idx].needanswer = 0;
  7639. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7640. p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER;
  7641. ast_mutex_unlock(&p->lock);
  7642. return &p->subs[idx].f;
  7643. }
  7644. #ifdef HAVE_OPENR2
  7645. if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
  7646. /* openr2 took care of reading and handling any event
  7647. (needanswer, needbusy etc), if we continue we will read()
  7648. twice, lets just return a null frame. This should only
  7649. happen when openr2 is dialing out */
  7650. ast_mutex_unlock(&p->lock);
  7651. return &ast_null_frame;
  7652. }
  7653. #endif
  7654. if (p->subs[idx].needflash) {
  7655. /* Send answer frame if requested */
  7656. p->subs[idx].needflash = 0;
  7657. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7658. p->subs[idx].f.subclass.integer = AST_CONTROL_FLASH;
  7659. ast_mutex_unlock(&p->lock);
  7660. return &p->subs[idx].f;
  7661. }
  7662. if (p->subs[idx].needhold) {
  7663. /* Send answer frame if requested */
  7664. p->subs[idx].needhold = 0;
  7665. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7666. p->subs[idx].f.subclass.integer = AST_CONTROL_HOLD;
  7667. ast_mutex_unlock(&p->lock);
  7668. ast_debug(1, "Sending hold on '%s'\n", ast_channel_name(ast));
  7669. return &p->subs[idx].f;
  7670. }
  7671. if (p->subs[idx].needunhold) {
  7672. /* Send answer frame if requested */
  7673. p->subs[idx].needunhold = 0;
  7674. p->subs[idx].f.frametype = AST_FRAME_CONTROL;
  7675. p->subs[idx].f.subclass.integer = AST_CONTROL_UNHOLD;
  7676. ast_mutex_unlock(&p->lock);
  7677. ast_debug(1, "Sending unhold on '%s'\n", ast_channel_name(ast));
  7678. return &p->subs[idx].f;
  7679. }
  7680. /*
  7681. * If we have a fake_event, fake an exception to handle it only
  7682. * if this channel owns the private.
  7683. */
  7684. if (p->fake_event && p->owner == ast) {
  7685. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  7686. struct analog_pvt *analog_p = p->sig_pvt;
  7687. f = analog_exception(analog_p, ast);
  7688. } else {
  7689. f = __dahdi_exception(ast);
  7690. }
  7691. ast_mutex_unlock(&p->lock);
  7692. return f;
  7693. }
  7694. if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
  7695. if (!p->subs[idx].linear) {
  7696. p->subs[idx].linear = 1;
  7697. res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  7698. if (res)
  7699. ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
  7700. }
  7701. } else {
  7702. if (p->subs[idx].linear) {
  7703. p->subs[idx].linear = 0;
  7704. res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  7705. if (res)
  7706. ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
  7707. }
  7708. }
  7709. readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
  7710. CHECK_BLOCKING(ast);
  7711. res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
  7712. ast_clear_flag(ast_channel_flags(ast), AST_FLAG_BLOCKING);
  7713. /* Check for hangup */
  7714. if (res < 0) {
  7715. f = NULL;
  7716. if (res == -1) {
  7717. if (errno == EAGAIN) {
  7718. /* Return "NULL" frame if there is nobody there */
  7719. ast_mutex_unlock(&p->lock);
  7720. return &p->subs[idx].f;
  7721. } else if (errno == ELAST) {
  7722. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  7723. struct analog_pvt *analog_p = p->sig_pvt;
  7724. f = analog_exception(analog_p, ast);
  7725. } else {
  7726. f = __dahdi_exception(ast);
  7727. }
  7728. } else
  7729. ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
  7730. }
  7731. ast_mutex_unlock(&p->lock);
  7732. return f;
  7733. }
  7734. if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
  7735. ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
  7736. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  7737. struct analog_pvt *analog_p = p->sig_pvt;
  7738. f = analog_exception(analog_p, ast);
  7739. } else {
  7740. f = __dahdi_exception(ast);
  7741. }
  7742. ast_mutex_unlock(&p->lock);
  7743. return f;
  7744. }
  7745. if (p->tdd) { /* if in TDD mode, see if we receive that */
  7746. int c;
  7747. c = tdd_feed(p->tdd,readbuf,READ_SIZE);
  7748. if (c < 0) {
  7749. ast_debug(1,"tdd_feed failed\n");
  7750. ast_mutex_unlock(&p->lock);
  7751. return NULL;
  7752. }
  7753. if (c) { /* if a char to return */
  7754. p->subs[idx].f.subclass.integer = 0;
  7755. p->subs[idx].f.frametype = AST_FRAME_TEXT;
  7756. p->subs[idx].f.mallocd = 0;
  7757. p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
  7758. p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET;
  7759. p->subs[idx].f.datalen = 1;
  7760. *((char *) p->subs[idx].f.data.ptr) = c;
  7761. ast_mutex_unlock(&p->lock);
  7762. return &p->subs[idx].f;
  7763. }
  7764. }
  7765. if (idx == SUB_REAL) {
  7766. /* Ensure the CW timers decrement only on a single subchannel */
  7767. if (p->cidcwexpire) {
  7768. if (!--p->cidcwexpire) {
  7769. /* Expired CID/CW */
  7770. ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n");
  7771. restore_conference(p);
  7772. }
  7773. }
  7774. if (p->cid_suppress_expire) {
  7775. --p->cid_suppress_expire;
  7776. }
  7777. if (p->callwaitingrepeat) {
  7778. if (!--p->callwaitingrepeat) {
  7779. /* Expired, Repeat callwaiting tone */
  7780. ++p->callwaitrings;
  7781. dahdi_callwait(ast);
  7782. }
  7783. }
  7784. }
  7785. if (p->subs[idx].linear) {
  7786. p->subs[idx].f.datalen = READ_SIZE * 2;
  7787. } else
  7788. p->subs[idx].f.datalen = READ_SIZE;
  7789. /* Handle CallerID Transmission */
  7790. if ((p->owner == ast) && p->cidspill) {
  7791. send_callerid(p);
  7792. }
  7793. p->subs[idx].f.frametype = AST_FRAME_VOICE;
  7794. p->subs[idx].f.subclass.format = ast_channel_rawreadformat(ast);
  7795. p->subs[idx].f.samples = READ_SIZE;
  7796. p->subs[idx].f.mallocd = 0;
  7797. p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
  7798. p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]);
  7799. #if 0
  7800. ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name);
  7801. #endif
  7802. if ((p->dialing && !p->waitingfordt.tv_sec) || p->radio || /* Transmitting something */
  7803. (idx && (ast_channel_state(ast) != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
  7804. ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
  7805. ) {
  7806. /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
  7807. don't send anything */
  7808. p->subs[idx].f.frametype = AST_FRAME_NULL;
  7809. p->subs[idx].f.subclass.integer = 0;
  7810. p->subs[idx].f.samples = 0;
  7811. p->subs[idx].f.mallocd = 0;
  7812. p->subs[idx].f.offset = 0;
  7813. p->subs[idx].f.data.ptr = NULL;
  7814. p->subs[idx].f.datalen= 0;
  7815. }
  7816. if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec || p->dialtone_detect) && !idx) {
  7817. /* Perform busy detection etc on the dahdi line */
  7818. int mute;
  7819. f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f);
  7820. /* Check if DSP code thinks we should be muting this frame and mute the conference if so */
  7821. mute = ast_dsp_was_muted(p->dsp);
  7822. if (p->muting != mute) {
  7823. p->muting = mute;
  7824. dahdi_confmute(p, mute);
  7825. }
  7826. if (f) {
  7827. if ((p->dsp_features & DSP_FEATURE_WAITDIALTONE) && (p->dialtone_detect > 0)
  7828. && !p->outgoing && ast_channel_state(ast) == AST_STATE_UP) {
  7829. if (++p->dialtone_scanning_time_elapsed >= p->dialtone_detect) {
  7830. p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
  7831. ast_dsp_set_features(p->dsp, p->dsp_features);
  7832. }
  7833. }
  7834. if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) {
  7835. if ((ast_channel_state(ast) == AST_STATE_UP) && !p->outgoing) {
  7836. /*
  7837. * Treat this as a "hangup" instead of a "busy" on the
  7838. * assumption that a busy means the incoming call went away.
  7839. */
  7840. ast_frfree(f);
  7841. f = NULL;
  7842. }
  7843. } else if (p->dialtone_detect && !p->outgoing && f->frametype == AST_FRAME_VOICE) {
  7844. if ((ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_DIALTONE) && (ast_dsp_get_tcount(p->dsp) > 9)) {
  7845. /* Dialtone detected on inbound call; hangup the channel */
  7846. ast_frfree(f);
  7847. f = NULL;
  7848. }
  7849. } else if (f->frametype == AST_FRAME_DTMF_BEGIN
  7850. || f->frametype == AST_FRAME_DTMF_END) {
  7851. #ifdef HAVE_PRI
  7852. if (dahdi_sig_pri_lib_handles(p->sig)
  7853. && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
  7854. && p->pri
  7855. && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING))
  7856. || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
  7857. /* Don't accept in-band DTMF when in overlap dial mode */
  7858. ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
  7859. f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end",
  7860. (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
  7861. f->frametype = AST_FRAME_NULL;
  7862. f->subclass.integer = 0;
  7863. }
  7864. #endif
  7865. /* DSP clears us of being pulse */
  7866. p->pulsedial = 0;
  7867. } else if (p->waitingfordt.tv_sec) {
  7868. if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) {
  7869. p->waitingfordt.tv_sec = 0;
  7870. ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel);
  7871. ast_frfree(f);
  7872. f = NULL;
  7873. } else if (f->frametype == AST_FRAME_VOICE) {
  7874. f->frametype = AST_FRAME_NULL;
  7875. f->subclass.integer = 0;
  7876. if ((ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_DIALTONE || ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_RINGING) && ast_dsp_get_tcount(p->dsp) > 9) {
  7877. p->waitingfordt.tv_sec = 0;
  7878. p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
  7879. ast_dsp_set_features(p->dsp, p->dsp_features);
  7880. ast_debug(1, "Got 10 samples of dialtone!\n");
  7881. if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */
  7882. res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
  7883. if (res) {
  7884. p->dop.dialstr[0] = '\0';
  7885. ast_mutex_unlock(&p->lock);
  7886. ast_frfree(f);
  7887. return NULL;
  7888. } else {
  7889. ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
  7890. p->dialing = 1;
  7891. p->dop.dialstr[0] = '\0';
  7892. p->dop.op = DAHDI_DIAL_OP_REPLACE;
  7893. ast_setstate(ast, AST_STATE_DIALING);
  7894. }
  7895. }
  7896. }
  7897. }
  7898. }
  7899. }
  7900. } else
  7901. f = &p->subs[idx].f;
  7902. if (f) {
  7903. switch (f->frametype) {
  7904. case AST_FRAME_DTMF_BEGIN:
  7905. case AST_FRAME_DTMF_END:
  7906. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  7907. analog_handle_dtmf(p->sig_pvt, ast, idx, &f);
  7908. } else {
  7909. dahdi_handle_dtmf(ast, idx, &f);
  7910. }
  7911. break;
  7912. case AST_FRAME_VOICE:
  7913. if (p->cidspill || p->cid_suppress_expire) {
  7914. /* We are/were sending a caller id spill. Suppress any echo. */
  7915. p->subs[idx].f.frametype = AST_FRAME_NULL;
  7916. p->subs[idx].f.subclass.integer = 0;
  7917. p->subs[idx].f.samples = 0;
  7918. p->subs[idx].f.mallocd = 0;
  7919. p->subs[idx].f.offset = 0;
  7920. p->subs[idx].f.data.ptr = NULL;
  7921. p->subs[idx].f.datalen= 0;
  7922. }
  7923. break;
  7924. default:
  7925. break;
  7926. }
  7927. }
  7928. ast_mutex_unlock(&p->lock);
  7929. return f;
  7930. }
  7931. static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
  7932. {
  7933. int sent=0;
  7934. int size;
  7935. int res;
  7936. int fd;
  7937. fd = p->subs[idx].dfd;
  7938. while (len) {
  7939. size = len;
  7940. if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
  7941. size = (linear ? READ_SIZE * 2 : READ_SIZE);
  7942. res = write(fd, buf, size);
  7943. if (res != size) {
  7944. ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
  7945. return sent;
  7946. }
  7947. len -= size;
  7948. buf += size;
  7949. }
  7950. return sent;
  7951. }
  7952. static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
  7953. {
  7954. struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
  7955. int res;
  7956. int idx;
  7957. idx = dahdi_get_index(ast, p, 0);
  7958. if (idx < 0) {
  7959. ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast));
  7960. return -1;
  7961. }
  7962. /* Write a frame of (presumably voice) data */
  7963. if (frame->frametype != AST_FRAME_VOICE) {
  7964. if (frame->frametype != AST_FRAME_IMAGE)
  7965. ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);
  7966. return 0;
  7967. }
  7968. if (p->dialing) {
  7969. ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",ast_channel_name(ast));
  7970. return 0;
  7971. }
  7972. if (!p->owner) {
  7973. ast_debug(5, "Dropping frame since there is no active owner on %s...\n",ast_channel_name(ast));
  7974. return 0;
  7975. }
  7976. if (p->cidspill) {
  7977. ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
  7978. ast_channel_name(ast));
  7979. return 0;
  7980. }
  7981. /* Return if it's not valid data */
  7982. if (!frame->data.ptr || !frame->datalen)
  7983. return 0;
  7984. if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
  7985. if (!p->subs[idx].linear) {
  7986. p->subs[idx].linear = 1;
  7987. res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  7988. if (res)
  7989. ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
  7990. }
  7991. res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1);
  7992. } else if (ast_format_cmp(frame->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL
  7993. || ast_format_cmp(frame->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
  7994. /* x-law already */
  7995. if (p->subs[idx].linear) {
  7996. p->subs[idx].linear = 0;
  7997. res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  7998. if (res)
  7999. ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
  8000. }
  8001. res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
  8002. } else {
  8003. ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
  8004. ast_format_get_name(frame->subclass.format));
  8005. return -1;
  8006. }
  8007. if (res < 0) {
  8008. ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
  8009. return -1;
  8010. }
  8011. return 0;
  8012. }
  8013. static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
  8014. {
  8015. struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
  8016. int res=-1;
  8017. int idx;
  8018. int func = DAHDI_FLASH;
  8019. ast_mutex_lock(&p->lock);
  8020. ast_debug(1, "Requested indication %d on channel %s\n", condition, ast_channel_name(chan));
  8021. switch (p->sig) {
  8022. #if defined(HAVE_PRI)
  8023. case SIG_PRI_LIB_HANDLE_CASES:
  8024. res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen);
  8025. ast_mutex_unlock(&p->lock);
  8026. return res;
  8027. #endif /* defined(HAVE_PRI) */
  8028. #if defined(HAVE_SS7)
  8029. case SIG_SS7:
  8030. res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen);
  8031. ast_mutex_unlock(&p->lock);
  8032. return res;
  8033. #endif /* defined(HAVE_SS7) */
  8034. default:
  8035. break;
  8036. }
  8037. #ifdef HAVE_OPENR2
  8038. if (p->mfcr2 && !p->mfcr2_call_accepted) {
  8039. ast_mutex_unlock(&p->lock);
  8040. /* if this is an R2 call and the call is not yet accepted, we don't want the
  8041. tone indications to mess up with the MF tones */
  8042. return 0;
  8043. }
  8044. #endif
  8045. idx = dahdi_get_index(chan, p, 0);
  8046. if (idx == SUB_REAL) {
  8047. switch (condition) {
  8048. case AST_CONTROL_BUSY:
  8049. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY);
  8050. break;
  8051. case AST_CONTROL_RINGING:
  8052. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE);
  8053. if (ast_channel_state(chan) != AST_STATE_UP) {
  8054. if ((ast_channel_state(chan) != AST_STATE_RING) ||
  8055. ((p->sig != SIG_FXSKS) &&
  8056. (p->sig != SIG_FXSLS) &&
  8057. (p->sig != SIG_FXSGS)))
  8058. ast_setstate(chan, AST_STATE_RINGING);
  8059. }
  8060. break;
  8061. case AST_CONTROL_INCOMPLETE:
  8062. ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", ast_channel_name(chan));
  8063. /* act as a progress or proceeding, allowing the caller to enter additional numbers */
  8064. res = 0;
  8065. break;
  8066. case AST_CONTROL_PROCEEDING:
  8067. ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", ast_channel_name(chan));
  8068. /* don't continue in ast_indicate */
  8069. res = 0;
  8070. break;
  8071. case AST_CONTROL_PROGRESS:
  8072. ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", ast_channel_name(chan));
  8073. /* don't continue in ast_indicate */
  8074. res = 0;
  8075. break;
  8076. case AST_CONTROL_CONGESTION:
  8077. /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
  8078. switch (ast_channel_hangupcause(chan)) {
  8079. case AST_CAUSE_USER_BUSY:
  8080. case AST_CAUSE_NORMAL_CLEARING:
  8081. case 0:/* Cause has not been set. */
  8082. /* Supply a more appropriate cause. */
  8083. ast_channel_hangupcause_set(chan, AST_CAUSE_CONGESTION);
  8084. break;
  8085. default:
  8086. break;
  8087. }
  8088. break;
  8089. case AST_CONTROL_HOLD:
  8090. ast_moh_start(chan, data, p->mohinterpret);
  8091. break;
  8092. case AST_CONTROL_UNHOLD:
  8093. ast_moh_stop(chan);
  8094. break;
  8095. case AST_CONTROL_RADIO_KEY:
  8096. if (p->radio)
  8097. res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
  8098. res = 0;
  8099. break;
  8100. case AST_CONTROL_RADIO_UNKEY:
  8101. if (p->radio)
  8102. res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF);
  8103. res = 0;
  8104. break;
  8105. case AST_CONTROL_FLASH:
  8106. /* flash hookswitch */
  8107. if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
  8108. /* Clear out the dial buffer */
  8109. p->dop.dialstr[0] = '\0';
  8110. if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
  8111. ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
  8112. ast_channel_name(chan), strerror(errno));
  8113. } else
  8114. res = 0;
  8115. } else
  8116. res = 0;
  8117. break;
  8118. case AST_CONTROL_SRCUPDATE:
  8119. res = 0;
  8120. break;
  8121. case -1:
  8122. res = tone_zone_play_tone(p->subs[idx].dfd, -1);
  8123. break;
  8124. }
  8125. } else {
  8126. res = 0;
  8127. }
  8128. ast_mutex_unlock(&p->lock);
  8129. return res;
  8130. }
  8131. #if defined(HAVE_PRI)
  8132. static struct ast_str *create_channel_name(struct dahdi_pvt *i, int is_outgoing, char *address)
  8133. #else
  8134. static struct ast_str *create_channel_name(struct dahdi_pvt *i)
  8135. #endif /* defined(HAVE_PRI) */
  8136. {
  8137. struct ast_str *chan_name;
  8138. int x, y;
  8139. /* Create the new channel name tail. */
  8140. if (!(chan_name = ast_str_create(32))) {
  8141. return NULL;
  8142. }
  8143. if (i->channel == CHAN_PSEUDO) {
  8144. ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
  8145. #if defined(HAVE_PRI)
  8146. } else if (i->pri) {
  8147. ast_mutex_lock(&i->pri->lock);
  8148. y = ++i->pri->new_chan_seq;
  8149. if (is_outgoing) {
  8150. ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, (unsigned)y);
  8151. address[0] = '\0';
  8152. } else if (ast_strlen_zero(i->cid_subaddr)) {
  8153. /* Put in caller-id number only since there is no subaddress. */
  8154. ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, (unsigned)y);
  8155. } else {
  8156. /* Put in caller-id number and subaddress. */
  8157. ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num,
  8158. i->cid_subaddr, (unsigned)y);
  8159. }
  8160. ast_mutex_unlock(&i->pri->lock);
  8161. #endif /* defined(HAVE_PRI) */
  8162. } else {
  8163. y = 1;
  8164. do {
  8165. ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
  8166. for (x = 0; x < 3; ++x) {
  8167. if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name),
  8168. ast_channel_name(i->subs[x].owner) + 6)) {
  8169. break;
  8170. }
  8171. }
  8172. ++y;
  8173. } while (x < 3);
  8174. }
  8175. return chan_name;
  8176. }
  8177. static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid, int callid_created)
  8178. {
  8179. struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, assignedids, requestor, callid);
  8180. ast_callid_threadstorage_auto_clean(callid, callid_created);
  8181. return new_channel;
  8182. }
  8183. static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid)
  8184. {
  8185. struct ast_channel *tmp;
  8186. struct ast_format_cap *caps;
  8187. struct ast_format *deflaw;
  8188. int x;
  8189. int features;
  8190. struct ast_str *chan_name;
  8191. struct ast_variable *v;
  8192. char *dashptr;
  8193. char device_name[AST_CHANNEL_NAME];
  8194. if (i->subs[idx].owner) {
  8195. ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
  8196. return NULL;
  8197. }
  8198. #if defined(HAVE_PRI)
  8199. /*
  8200. * The dnid has been stuffed with the called-number[:subaddress]
  8201. * by dahdi_request() for outgoing calls.
  8202. */
  8203. chan_name = create_channel_name(i, i->outgoing, i->dnid);
  8204. #else
  8205. chan_name = create_channel_name(i);
  8206. #endif /* defined(HAVE_PRI) */
  8207. if (!chan_name) {
  8208. return NULL;
  8209. }
  8210. caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
  8211. if (!caps) {
  8212. ast_free(chan_name);
  8213. return NULL;
  8214. }
  8215. tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
  8216. ast_free(chan_name);
  8217. if (!tmp) {
  8218. ao2_ref(caps, -1);
  8219. return NULL;
  8220. }
  8221. ast_channel_stage_snapshot(tmp);
  8222. if (callid) {
  8223. ast_channel_callid_set(tmp, callid);
  8224. }
  8225. ast_channel_tech_set(tmp, &dahdi_tech);
  8226. #if defined(HAVE_PRI)
  8227. if (i->pri) {
  8228. ast_cc_copy_config_params(i->cc_params, i->pri->cc_params);
  8229. }
  8230. #endif /* defined(HAVE_PRI) */
  8231. ast_channel_cc_params_init(tmp, i->cc_params);
  8232. if (law) {
  8233. i->law = law;
  8234. if (law == DAHDI_LAW_ALAW) {
  8235. deflaw = ast_format_alaw;
  8236. } else {
  8237. deflaw = ast_format_ulaw;
  8238. }
  8239. } else {
  8240. switch (i->sig) {
  8241. case SIG_PRI_LIB_HANDLE_CASES:
  8242. /* Make sure companding law is known. */
  8243. i->law = (i->law_default == DAHDI_LAW_ALAW)
  8244. ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
  8245. break;
  8246. default:
  8247. i->law = i->law_default;
  8248. break;
  8249. }
  8250. if (i->law_default == DAHDI_LAW_ALAW) {
  8251. deflaw = ast_format_alaw;
  8252. } else {
  8253. deflaw = ast_format_ulaw;
  8254. }
  8255. }
  8256. ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
  8257. ast_format_cap_append(caps, deflaw, 0);
  8258. ast_channel_nativeformats_set(tmp, caps);
  8259. ao2_ref(caps, -1);
  8260. /* Start out assuming ulaw since it's smaller :) */
  8261. ast_channel_set_rawreadformat(tmp, deflaw);
  8262. ast_channel_set_readformat(tmp, deflaw);
  8263. ast_channel_set_rawwriteformat(tmp, deflaw);
  8264. ast_channel_set_writeformat(tmp, deflaw);
  8265. i->subs[idx].linear = 0;
  8266. dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
  8267. features = 0;
  8268. if (idx == SUB_REAL) {
  8269. if (i->busydetect && CANBUSYDETECT(i))
  8270. features |= DSP_FEATURE_BUSY_DETECT;
  8271. if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i))
  8272. features |= DSP_FEATURE_CALL_PROGRESS;
  8273. if ((i->waitfordialtone || i->dialtone_detect) && CANPROGRESSDETECT(i))
  8274. features |= DSP_FEATURE_WAITDIALTONE;
  8275. if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) ||
  8276. (i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) {
  8277. features |= DSP_FEATURE_FAX_DETECT;
  8278. }
  8279. x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
  8280. if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) {
  8281. i->hardwaredtmf = 0;
  8282. features |= DSP_FEATURE_DIGIT_DETECT;
  8283. } else if (NEED_MFDETECT(i)) {
  8284. i->hardwaredtmf = 1;
  8285. features |= DSP_FEATURE_DIGIT_DETECT;
  8286. }
  8287. }
  8288. if (features) {
  8289. if (i->dsp) {
  8290. ast_debug(1, "Already have a dsp on %s?\n", ast_channel_name(tmp));
  8291. } else {
  8292. if (i->channel != CHAN_PSEUDO)
  8293. i->dsp = ast_dsp_new();
  8294. else
  8295. i->dsp = NULL;
  8296. if (i->dsp) {
  8297. i->dsp_features = features;
  8298. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  8299. /* We cannot do progress detection until receive PROGRESS message */
  8300. if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) {
  8301. /* Remember requested DSP features, don't treat
  8302. talking as ANSWER */
  8303. i->dsp_features = features & ~DSP_PROGRESS_TALK;
  8304. features = 0;
  8305. }
  8306. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  8307. ast_dsp_set_features(i->dsp, features);
  8308. ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
  8309. if (!ast_strlen_zero(progzone))
  8310. ast_dsp_set_call_progress_zone(i->dsp, progzone);
  8311. if (i->busydetect && CANBUSYDETECT(i)) {
  8312. ast_dsp_set_busy_count(i->dsp, i->busycount);
  8313. ast_dsp_set_busy_pattern(i->dsp, &i->busy_cadence);
  8314. }
  8315. }
  8316. }
  8317. }
  8318. i->dialtone_scanning_time_elapsed = 0;
  8319. if (state == AST_STATE_RING)
  8320. ast_channel_rings_set(tmp, 1);
  8321. ast_channel_tech_pvt_set(tmp, i);
  8322. if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
  8323. /* Only FXO signalled stuff can be picked up */
  8324. ast_channel_callgroup_set(tmp, i->callgroup);
  8325. ast_channel_pickupgroup_set(tmp, i->pickupgroup);
  8326. ast_channel_named_callgroups_set(tmp, i->named_callgroups);
  8327. ast_channel_named_pickupgroups_set(tmp, i->named_pickupgroups);
  8328. }
  8329. if (!ast_strlen_zero(i->parkinglot))
  8330. ast_channel_parkinglot_set(tmp, i->parkinglot);
  8331. if (!ast_strlen_zero(i->language))
  8332. ast_channel_language_set(tmp, i->language);
  8333. if (!i->owner)
  8334. i->owner = tmp;
  8335. if (!ast_strlen_zero(i->accountcode))
  8336. ast_channel_accountcode_set(tmp, i->accountcode);
  8337. if (i->amaflags)
  8338. ast_channel_amaflags_set(tmp, i->amaflags);
  8339. i->subs[idx].owner = tmp;
  8340. ast_channel_context_set(tmp, i->context);
  8341. if (!dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
  8342. ast_channel_call_forward_set(tmp, i->call_forward);
  8343. }
  8344. /* If we've been told "no ADSI" then enforce it */
  8345. if (!i->adsi)
  8346. ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
  8347. if (!ast_strlen_zero(i->exten))
  8348. ast_channel_exten_set(tmp, i->exten);
  8349. if (!ast_strlen_zero(i->rdnis)) {
  8350. ast_channel_redirecting(tmp)->from.number.valid = 1;
  8351. ast_channel_redirecting(tmp)->from.number.str = ast_strdup(i->rdnis);
  8352. }
  8353. if (!ast_strlen_zero(i->dnid)) {
  8354. ast_channel_dialed(tmp)->number.str = ast_strdup(i->dnid);
  8355. }
  8356. /* Don't use ast_set_callerid() here because it will
  8357. * generate a needless NewCallerID event */
  8358. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  8359. if (!ast_strlen_zero(i->cid_ani)) {
  8360. ast_channel_caller(tmp)->ani.number.valid = 1;
  8361. ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_ani);
  8362. } else if (!ast_strlen_zero(i->cid_num)) {
  8363. ast_channel_caller(tmp)->ani.number.valid = 1;
  8364. ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
  8365. }
  8366. #else
  8367. if (!ast_strlen_zero(i->cid_num)) {
  8368. ast_channel_caller(tmp)->ani.number.valid = 1;
  8369. ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);
  8370. }
  8371. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  8372. ast_channel_caller(tmp)->id.name.presentation = i->callingpres;
  8373. ast_channel_caller(tmp)->id.number.presentation = i->callingpres;
  8374. ast_channel_caller(tmp)->id.number.plan = i->cid_ton;
  8375. ast_channel_caller(tmp)->ani2 = i->cid_ani2;
  8376. ast_channel_caller(tmp)->id.tag = ast_strdup(i->cid_tag);
  8377. /* clear the fake event in case we posted one before we had ast_channel */
  8378. i->fake_event = 0;
  8379. /* Assure there is no confmute on this channel */
  8380. dahdi_confmute(i, 0);
  8381. i->muting = 0;
  8382. /* Configure the new channel jb */
  8383. ast_jb_configure(tmp, &global_jbconf);
  8384. /* Set initial device state */
  8385. ast_copy_string(device_name, ast_channel_name(tmp), sizeof(device_name));
  8386. dashptr = strrchr(device_name, '-');
  8387. if (dashptr) {
  8388. *dashptr = '\0';
  8389. }
  8390. ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
  8391. ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name);
  8392. for (v = i->vars ; v ; v = v->next)
  8393. pbx_builtin_setvar_helper(tmp, v->name, v->value);
  8394. ast_channel_stage_snapshot_done(tmp);
  8395. ast_channel_unlock(tmp);
  8396. ast_module_ref(ast_module_info->self);
  8397. dahdi_ami_channel_event(i, tmp);
  8398. if (startpbx) {
  8399. #ifdef HAVE_OPENR2
  8400. if (i->mfcr2call) {
  8401. pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category));
  8402. }
  8403. #endif
  8404. if (ast_pbx_start(tmp)) {
  8405. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
  8406. ast_hangup(tmp);
  8407. return NULL;
  8408. }
  8409. }
  8410. return tmp;
  8411. }
  8412. static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
  8413. {
  8414. char c;
  8415. *str = 0; /* start with empty output buffer */
  8416. for (;;)
  8417. {
  8418. /* Wait for the first digit (up to specified ms). */
  8419. c = ast_waitfordigit(chan, ms);
  8420. /* if timeout, hangup or error, return as such */
  8421. if (c < 1)
  8422. return c;
  8423. *str++ = c;
  8424. *str = 0;
  8425. if (strchr(term, c))
  8426. return 1;
  8427. }
  8428. }
  8429. static int dahdi_wink(struct dahdi_pvt *p, int idx)
  8430. {
  8431. int j;
  8432. dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK);
  8433. for (;;)
  8434. {
  8435. /* set bits of interest */
  8436. j = DAHDI_IOMUX_SIGEVENT;
  8437. /* wait for some happening */
  8438. if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1);
  8439. /* exit loop if we have it */
  8440. if (j & DAHDI_IOMUX_SIGEVENT) break;
  8441. }
  8442. /* get the event info */
  8443. if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1);
  8444. return 0;
  8445. }
  8446. static void publish_dnd_state(int channel, const char *status)
  8447. {
  8448. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  8449. RAII_VAR(struct ast_str *, dahdichan, ast_str_create(32), ast_free);
  8450. if (!dahdichan) {
  8451. return;
  8452. }
  8453. ast_str_set(&dahdichan, 0, "%d", channel);
  8454. body = ast_json_pack("{s: s, s: s}",
  8455. "DAHDIChannel", ast_str_buffer(dahdichan),
  8456. "Status", status);
  8457. if (!body) {
  8458. return;
  8459. }
  8460. ast_manager_publish_event("DNDState", EVENT_FLAG_SYSTEM, body);
  8461. }
  8462. /*! \brief enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
  8463. * \param dahdichan "Physical" DAHDI channel (e.g: DAHDI/5)
  8464. * \param flag on 1 to enable, 0 to disable, -1 return dnd value
  8465. *
  8466. * chan_dahdi has a DND (Do Not Disturb) mode for each dahdichan (physical
  8467. * DAHDI channel). Use this to enable or disable it.
  8468. *
  8469. * \bug the use of the word "channel" for those dahdichans is really confusing.
  8470. */
  8471. static int dahdi_dnd(struct dahdi_pvt *dahdichan, int flag)
  8472. {
  8473. if (dahdi_analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) {
  8474. return analog_dnd(dahdichan->sig_pvt, flag);
  8475. }
  8476. if (flag == -1) {
  8477. return dahdichan->dnd;
  8478. }
  8479. /* Do not disturb */
  8480. dahdichan->dnd = flag;
  8481. ast_verb(3, "%s DND on channel %d\n",
  8482. flag? "Enabled" : "Disabled",
  8483. dahdichan->channel);
  8484. publish_dnd_state(dahdichan->channel, flag ? "enabled" : "disabled");
  8485. return 0;
  8486. }
  8487. static int canmatch_featurecode(const char *pickupexten, const char *exten)
  8488. {
  8489. int extlen = strlen(exten);
  8490. if (!extlen) {
  8491. return 1;
  8492. }
  8493. if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
  8494. return 1;
  8495. }
  8496. /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
  8497. if (exten[0] == '*' && extlen < 3) {
  8498. if (extlen == 1) {
  8499. return 1;
  8500. }
  8501. /* "*0" should be processed before it gets here */
  8502. switch (exten[1]) {
  8503. case '6':
  8504. case '7':
  8505. case '8':
  8506. return 1;
  8507. }
  8508. }
  8509. return 0;
  8510. }
  8511. static void *analog_ss_thread(void *data)
  8512. {
  8513. struct ast_channel *chan = data;
  8514. struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
  8515. char exten[AST_MAX_EXTENSION] = "";
  8516. char exten2[AST_MAX_EXTENSION] = "";
  8517. unsigned char buf[256];
  8518. char dtmfcid[300];
  8519. char dtmfbuf[300];
  8520. struct callerid_state *cs = NULL;
  8521. char *name = NULL, *number = NULL;
  8522. int distMatches;
  8523. int curRingData[3];
  8524. int receivedRingT;
  8525. int counter1;
  8526. int counter;
  8527. int samples = 0;
  8528. struct ast_smdi_md_message *smdi_msg = NULL;
  8529. int flags = 0;
  8530. int i;
  8531. int timeout;
  8532. int getforward = 0;
  8533. char *s1, *s2;
  8534. int len = 0;
  8535. int res;
  8536. int idx;
  8537. RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
  8538. const char *pickupexten;
  8539. ast_mutex_lock(&ss_thread_lock);
  8540. ss_thread_count++;
  8541. ast_mutex_unlock(&ss_thread_lock);
  8542. /* in the bizarre case where the channel has become a zombie before we
  8543. even get started here, abort safely
  8544. */
  8545. if (!p) {
  8546. ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan));
  8547. ast_hangup(chan);
  8548. goto quit;
  8549. }
  8550. ast_verb(3, "Starting simple switch on '%s'\n", ast_channel_name(chan));
  8551. idx = dahdi_get_index(chan, p, 1);
  8552. if (idx < 0) {
  8553. ast_log(LOG_WARNING, "Huh?\n");
  8554. ast_hangup(chan);
  8555. goto quit;
  8556. }
  8557. ast_channel_lock(chan);
  8558. pickup_cfg = ast_get_chan_features_pickup_config(chan);
  8559. if (!pickup_cfg) {
  8560. ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
  8561. pickupexten = "";
  8562. } else {
  8563. pickupexten = ast_strdupa(pickup_cfg->pickupexten);
  8564. }
  8565. ast_channel_unlock(chan);
  8566. if (p->dsp)
  8567. ast_dsp_digitreset(p->dsp);
  8568. switch (p->sig) {
  8569. case SIG_FEATD:
  8570. case SIG_FEATDMF:
  8571. case SIG_FEATDMF_TA:
  8572. case SIG_E911:
  8573. case SIG_FGC_CAMAMF:
  8574. case SIG_FEATB:
  8575. case SIG_EMWINK:
  8576. case SIG_SF_FEATD:
  8577. case SIG_SF_FEATDMF:
  8578. case SIG_SF_FEATB:
  8579. case SIG_SFWINK:
  8580. if (dahdi_wink(p, idx))
  8581. goto quit;
  8582. /* Fall through */
  8583. case SIG_EM:
  8584. case SIG_EM_E1:
  8585. case SIG_SF:
  8586. case SIG_FGC_CAMA:
  8587. res = tone_zone_play_tone(p->subs[idx].dfd, -1);
  8588. if (p->dsp)
  8589. ast_dsp_digitreset(p->dsp);
  8590. /* set digit mode appropriately */
  8591. if (p->dsp) {
  8592. if (NEED_MFDETECT(p))
  8593. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
  8594. else
  8595. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
  8596. }
  8597. memset(dtmfbuf, 0, sizeof(dtmfbuf));
  8598. /* Wait for the first digit only if immediate=no */
  8599. if (!p->immediate)
  8600. /* Wait for the first digit (up to 5 seconds). */
  8601. res = ast_waitfordigit(chan, 5000);
  8602. else
  8603. res = 0;
  8604. if (res > 0) {
  8605. /* save first char */
  8606. dtmfbuf[0] = res;
  8607. switch (p->sig) {
  8608. case SIG_FEATD:
  8609. case SIG_SF_FEATD:
  8610. res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
  8611. if (res > 0)
  8612. res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
  8613. if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
  8614. break;
  8615. case SIG_FEATDMF_TA:
  8616. res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
  8617. if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
  8618. if (dahdi_wink(p, idx)) goto quit;
  8619. dtmfbuf[0] = 0;
  8620. /* Wait for the first digit (up to 5 seconds). */
  8621. res = ast_waitfordigit(chan, 5000);
  8622. if (res <= 0) break;
  8623. dtmfbuf[0] = res;
  8624. /* fall through intentionally */
  8625. case SIG_FEATDMF:
  8626. case SIG_E911:
  8627. case SIG_FGC_CAMAMF:
  8628. case SIG_SF_FEATDMF:
  8629. res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
  8630. /* if international caca, do it again to get real ANO */
  8631. if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
  8632. {
  8633. if (dahdi_wink(p, idx)) goto quit;
  8634. dtmfbuf[0] = 0;
  8635. /* Wait for the first digit (up to 5 seconds). */
  8636. res = ast_waitfordigit(chan, 5000);
  8637. if (res <= 0) break;
  8638. dtmfbuf[0] = res;
  8639. res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
  8640. }
  8641. if (res > 0) {
  8642. /* if E911, take off hook */
  8643. if (p->sig == SIG_E911)
  8644. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  8645. res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
  8646. }
  8647. if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
  8648. break;
  8649. case SIG_FEATB:
  8650. case SIG_SF_FEATB:
  8651. res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
  8652. if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
  8653. break;
  8654. case SIG_EMWINK:
  8655. /* if we received a '*', we are actually receiving Feature Group D
  8656. dial syntax, so use that mode; otherwise, fall through to normal
  8657. mode
  8658. */
  8659. if (res == '*') {
  8660. res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
  8661. if (res > 0)
  8662. res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
  8663. if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
  8664. break;
  8665. }
  8666. default:
  8667. /* If we got the first digit, get the rest */
  8668. len = 1;
  8669. dtmfbuf[len] = '\0';
  8670. while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
  8671. if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
  8672. timeout = matchdigittimeout;
  8673. } else {
  8674. timeout = gendigittimeout;
  8675. }
  8676. res = ast_waitfordigit(chan, timeout);
  8677. if (res < 0) {
  8678. ast_debug(1, "waitfordigit returned < 0...\n");
  8679. ast_hangup(chan);
  8680. goto quit;
  8681. } else if (res) {
  8682. dtmfbuf[len++] = res;
  8683. dtmfbuf[len] = '\0';
  8684. } else {
  8685. break;
  8686. }
  8687. }
  8688. break;
  8689. }
  8690. }
  8691. if (res == -1) {
  8692. ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
  8693. ast_hangup(chan);
  8694. goto quit;
  8695. } else if (res < 0) {
  8696. ast_debug(1, "Got hung up before digits finished\n");
  8697. ast_hangup(chan);
  8698. goto quit;
  8699. }
  8700. if (p->sig == SIG_FGC_CAMA) {
  8701. char anibuf[100];
  8702. if (ast_safe_sleep(chan,1000) == -1) {
  8703. ast_hangup(chan);
  8704. goto quit;
  8705. }
  8706. dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  8707. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
  8708. res = my_getsigstr(chan, anibuf, "#", 10000);
  8709. if ((res > 0) && (strlen(anibuf) > 2)) {
  8710. if (anibuf[strlen(anibuf) - 1] == '#')
  8711. anibuf[strlen(anibuf) - 1] = 0;
  8712. ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
  8713. }
  8714. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
  8715. }
  8716. ast_copy_string(exten, dtmfbuf, sizeof(exten));
  8717. if (ast_strlen_zero(exten))
  8718. ast_copy_string(exten, "s", sizeof(exten));
  8719. if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
  8720. /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
  8721. if (exten[0] == '*') {
  8722. char *stringp=NULL;
  8723. ast_copy_string(exten2, exten, sizeof(exten2));
  8724. /* Parse out extension and callerid */
  8725. stringp=exten2 +1;
  8726. s1 = strsep(&stringp, "*");
  8727. s2 = strsep(&stringp, "*");
  8728. if (s2) {
  8729. if (!ast_strlen_zero(p->cid_num))
  8730. ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
  8731. else
  8732. ast_set_callerid(chan, s1, NULL, s1);
  8733. ast_copy_string(exten, s2, sizeof(exten));
  8734. } else
  8735. ast_copy_string(exten, s1, sizeof(exten));
  8736. } else if (p->sig == SIG_FEATD)
  8737. ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
  8738. }
  8739. if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
  8740. if (exten[0] == '*') {
  8741. char *stringp=NULL;
  8742. ast_copy_string(exten2, exten, sizeof(exten2));
  8743. /* Parse out extension and callerid */
  8744. stringp=exten2 +1;
  8745. s1 = strsep(&stringp, "#");
  8746. s2 = strsep(&stringp, "#");
  8747. if (s2) {
  8748. if (!ast_strlen_zero(p->cid_num))
  8749. ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
  8750. else
  8751. if (*(s1 + 2))
  8752. ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
  8753. ast_copy_string(exten, s2 + 1, sizeof(exten));
  8754. } else
  8755. ast_copy_string(exten, s1 + 2, sizeof(exten));
  8756. } else
  8757. ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
  8758. }
  8759. if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
  8760. if (exten[0] == '*') {
  8761. char *stringp=NULL;
  8762. ast_copy_string(exten2, exten, sizeof(exten2));
  8763. /* Parse out extension and callerid */
  8764. stringp=exten2 +1;
  8765. s1 = strsep(&stringp, "#");
  8766. s2 = strsep(&stringp, "#");
  8767. if (s2 && (*(s2 + 1) == '0')) {
  8768. if (*(s2 + 2))
  8769. ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
  8770. }
  8771. if (s1) ast_copy_string(exten, s1, sizeof(exten));
  8772. else ast_copy_string(exten, "911", sizeof(exten));
  8773. } else
  8774. ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel);
  8775. }
  8776. if (p->sig == SIG_FEATB) {
  8777. if (exten[0] == '*') {
  8778. char *stringp=NULL;
  8779. ast_copy_string(exten2, exten, sizeof(exten2));
  8780. /* Parse out extension and callerid */
  8781. stringp=exten2 +1;
  8782. s1 = strsep(&stringp, "#");
  8783. ast_copy_string(exten, exten2 + 1, sizeof(exten));
  8784. } else
  8785. ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel);
  8786. }
  8787. if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
  8788. dahdi_wink(p, idx);
  8789. /* some switches require a minimum guard time between
  8790. the last FGD wink and something that answers
  8791. immediately. This ensures it */
  8792. if (ast_safe_sleep(chan, 100)) {
  8793. ast_hangup(chan);
  8794. goto quit;
  8795. }
  8796. }
  8797. dahdi_ec_enable(p);
  8798. if (NEED_MFDETECT(p)) {
  8799. if (p->dsp) {
  8800. if (!p->hardwaredtmf)
  8801. ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
  8802. else {
  8803. ast_dsp_free(p->dsp);
  8804. p->dsp = NULL;
  8805. }
  8806. }
  8807. }
  8808. if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1,
  8809. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
  8810. ast_channel_exten_set(chan, exten);
  8811. if (p->dsp) ast_dsp_digitreset(p->dsp);
  8812. res = ast_pbx_run(chan);
  8813. if (res) {
  8814. ast_log(LOG_WARNING, "PBX exited non-zero\n");
  8815. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  8816. }
  8817. goto quit;
  8818. } else {
  8819. ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, ast_channel_context(chan));
  8820. sleep(2);
  8821. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO);
  8822. if (res < 0)
  8823. ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
  8824. else
  8825. sleep(1);
  8826. res = ast_streamfile(chan, "ss-noservice", ast_channel_language(chan));
  8827. if (res >= 0)
  8828. ast_waitstream(chan, "");
  8829. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  8830. ast_hangup(chan);
  8831. goto quit;
  8832. }
  8833. break;
  8834. case SIG_FXOLS:
  8835. case SIG_FXOGS:
  8836. case SIG_FXOKS:
  8837. /* Read the first digit */
  8838. timeout = firstdigittimeout;
  8839. /* If starting a threeway call, never timeout on the first digit so someone
  8840. can use flash-hook as a "hold" feature */
  8841. if (p->subs[SUB_THREEWAY].owner)
  8842. timeout = 999999;
  8843. while (len < AST_MAX_EXTENSION-1) {
  8844. int is_exten_parking = 0;
  8845. /* Read digit unless it's supposed to be immediate, in which case the
  8846. only answer is 's' */
  8847. if (p->immediate)
  8848. res = 's';
  8849. else
  8850. res = ast_waitfordigit(chan, timeout);
  8851. timeout = 0;
  8852. if (res < 0) {
  8853. ast_debug(1, "waitfordigit returned < 0...\n");
  8854. res = tone_zone_play_tone(p->subs[idx].dfd, -1);
  8855. ast_hangup(chan);
  8856. goto quit;
  8857. } else if (res) {
  8858. ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
  8859. exten[len++]=res;
  8860. exten[len] = '\0';
  8861. }
  8862. if (!ast_ignore_pattern(ast_channel_context(chan), exten)) {
  8863. tone_zone_play_tone(p->subs[idx].dfd, -1);
  8864. } else {
  8865. tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
  8866. }
  8867. if (ast_parking_provider_registered()) {
  8868. is_exten_parking = ast_parking_is_exten_park(ast_channel_context(chan), exten);
  8869. }
  8870. if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
  8871. if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
  8872. if (getforward) {
  8873. /* Record this as the forwarding extension */
  8874. ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
  8875. ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
  8876. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8877. if (res)
  8878. break;
  8879. usleep(500000);
  8880. res = tone_zone_play_tone(p->subs[idx].dfd, -1);
  8881. sleep(1);
  8882. memset(exten, 0, sizeof(exten));
  8883. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
  8884. len = 0;
  8885. getforward = 0;
  8886. } else {
  8887. res = tone_zone_play_tone(p->subs[idx].dfd, -1);
  8888. ast_channel_lock(chan);
  8889. ast_channel_exten_set(chan, exten);
  8890. if (!ast_strlen_zero(p->cid_num)) {
  8891. if (!p->hidecallerid)
  8892. ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
  8893. else
  8894. ast_set_callerid(chan, NULL, NULL, p->cid_num);
  8895. }
  8896. if (!ast_strlen_zero(p->cid_name)) {
  8897. if (!p->hidecallerid)
  8898. ast_set_callerid(chan, NULL, p->cid_name, NULL);
  8899. }
  8900. ast_setstate(chan, AST_STATE_RING);
  8901. ast_channel_unlock(chan);
  8902. dahdi_ec_enable(p);
  8903. res = ast_pbx_run(chan);
  8904. if (res) {
  8905. ast_log(LOG_WARNING, "PBX exited non-zero\n");
  8906. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  8907. }
  8908. goto quit;
  8909. }
  8910. } else {
  8911. /* It's a match, but they just typed a digit, and there is an ambiguous match,
  8912. so just set the timeout to matchdigittimeout and wait some more */
  8913. timeout = matchdigittimeout;
  8914. }
  8915. } else if (res == 0) {
  8916. ast_debug(1, "not enough digits (and no ambiguous match)...\n");
  8917. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  8918. dahdi_wait_event(p->subs[idx].dfd);
  8919. ast_hangup(chan);
  8920. goto quit;
  8921. } else if (p->callwaiting && !strcmp(exten, "*70")) {
  8922. ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
  8923. /* Disable call waiting if enabled */
  8924. p->callwaiting = 0;
  8925. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8926. if (res) {
  8927. ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
  8928. ast_channel_name(chan), strerror(errno));
  8929. }
  8930. len = 0;
  8931. ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
  8932. memset(exten, 0, sizeof(exten));
  8933. timeout = firstdigittimeout;
  8934. } else if (!strcmp(exten, pickupexten)) {
  8935. /* Scan all channels and see if there are any
  8936. * ringing channels that have call groups
  8937. * that equal this channels pickup group
  8938. */
  8939. if (idx == SUB_REAL) {
  8940. /* Switch us from Third call to Call Wait */
  8941. if (p->subs[SUB_THREEWAY].owner) {
  8942. /* If you make a threeway call and the *8# a call, it should actually
  8943. look like a callwait */
  8944. alloc_sub(p, SUB_CALLWAIT);
  8945. swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
  8946. unalloc_sub(p, SUB_THREEWAY);
  8947. }
  8948. dahdi_ec_enable(p);
  8949. if (ast_pickup_call(chan)) {
  8950. ast_debug(1, "No call pickup possible...\n");
  8951. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  8952. dahdi_wait_event(p->subs[idx].dfd);
  8953. }
  8954. ast_hangup(chan);
  8955. goto quit;
  8956. } else {
  8957. ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
  8958. ast_hangup(chan);
  8959. goto quit;
  8960. }
  8961. } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
  8962. ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
  8963. /* Disable Caller*ID if enabled */
  8964. p->hidecallerid = 1;
  8965. ast_party_number_free(&ast_channel_caller(chan)->id.number);
  8966. ast_party_number_init(&ast_channel_caller(chan)->id.number);
  8967. ast_party_name_free(&ast_channel_caller(chan)->id.name);
  8968. ast_party_name_init(&ast_channel_caller(chan)->id.name);
  8969. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8970. if (res) {
  8971. ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
  8972. ast_channel_name(chan), strerror(errno));
  8973. }
  8974. len = 0;
  8975. memset(exten, 0, sizeof(exten));
  8976. timeout = firstdigittimeout;
  8977. } else if (p->callreturn && !strcmp(exten, "*69")) {
  8978. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8979. break;
  8980. } else if (!strcmp(exten, "*78")) {
  8981. dahdi_dnd(p, 1);
  8982. /* Do not disturb */
  8983. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8984. getforward = 0;
  8985. memset(exten, 0, sizeof(exten));
  8986. len = 0;
  8987. } else if (!strcmp(exten, "*79")) {
  8988. dahdi_dnd(p, 0);
  8989. /* Do not disturb */
  8990. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8991. getforward = 0;
  8992. memset(exten, 0, sizeof(exten));
  8993. len = 0;
  8994. } else if (p->cancallforward && !strcmp(exten, "*72")) {
  8995. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  8996. getforward = 1;
  8997. memset(exten, 0, sizeof(exten));
  8998. len = 0;
  8999. } else if (p->cancallforward && !strcmp(exten, "*73")) {
  9000. ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
  9001. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  9002. memset(p->call_forward, 0, sizeof(p->call_forward));
  9003. getforward = 0;
  9004. memset(exten, 0, sizeof(exten));
  9005. len = 0;
  9006. } else if ((p->transfer || p->canpark) && is_exten_parking
  9007. && p->subs[SUB_THREEWAY].owner) {
  9008. struct ast_bridge_channel *bridge_channel;
  9009. /*
  9010. * This is a three way call, the main call being a real channel,
  9011. * and we're parking the first call.
  9012. */
  9013. ast_channel_lock(p->subs[SUB_THREEWAY].owner);
  9014. bridge_channel = ast_channel_get_bridge_channel(p->subs[SUB_THREEWAY].owner);
  9015. ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
  9016. if (bridge_channel) {
  9017. if (!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten, NULL, NULL)) {
  9018. /*
  9019. * Swap things around between the three-way and real call so we
  9020. * can hear where the channel got parked.
  9021. */
  9022. ast_mutex_lock(&p->lock);
  9023. p->owner = p->subs[SUB_THREEWAY].owner;
  9024. swap_subs(p, SUB_THREEWAY, SUB_REAL);
  9025. ast_mutex_unlock(&p->lock);
  9026. ast_verb(3, "%s: Parked call\n", ast_channel_name(chan));
  9027. ast_hangup(chan);
  9028. ao2_ref(bridge_channel, -1);
  9029. goto quit;
  9030. }
  9031. ao2_ref(bridge_channel, -1);
  9032. }
  9033. break;
  9034. } else if (p->hidecallerid && !strcmp(exten, "*82")) {
  9035. ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
  9036. /* Enable Caller*ID if enabled */
  9037. p->hidecallerid = 0;
  9038. ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
  9039. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
  9040. if (res) {
  9041. ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
  9042. ast_channel_name(chan), strerror(errno));
  9043. }
  9044. len = 0;
  9045. memset(exten, 0, sizeof(exten));
  9046. timeout = firstdigittimeout;
  9047. } else if (!strcmp(exten, "*0")) {
  9048. struct ast_channel *nbridge =
  9049. p->subs[SUB_THREEWAY].owner;
  9050. struct dahdi_pvt *pbridge = NULL;
  9051. RAII_VAR(struct ast_channel *, bridged, nbridge ? ast_channel_bridge_peer(nbridge) : NULL, ast_channel_cleanup);
  9052. /* set up the private struct of the bridged one, if any */
  9053. if (nbridge && bridged) {
  9054. pbridge = ast_channel_tech_pvt(bridged);
  9055. }
  9056. if (nbridge && pbridge &&
  9057. (ast_channel_tech(nbridge) == &dahdi_tech) &&
  9058. (ast_channel_tech(bridged) == &dahdi_tech) &&
  9059. ISTRUNK(pbridge)) {
  9060. int func = DAHDI_FLASH;
  9061. /* Clear out the dial buffer */
  9062. p->dop.dialstr[0] = '\0';
  9063. /* flash hookswitch */
  9064. if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
  9065. ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
  9066. ast_channel_name(nbridge), strerror(errno));
  9067. }
  9068. swap_subs(p, SUB_REAL, SUB_THREEWAY);
  9069. unalloc_sub(p, SUB_THREEWAY);
  9070. p->owner = p->subs[SUB_REAL].owner;
  9071. ast_queue_unhold(p->subs[SUB_REAL].owner);
  9072. ast_hangup(chan);
  9073. goto quit;
  9074. } else {
  9075. tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  9076. dahdi_wait_event(p->subs[idx].dfd);
  9077. tone_zone_play_tone(p->subs[idx].dfd, -1);
  9078. swap_subs(p, SUB_REAL, SUB_THREEWAY);
  9079. unalloc_sub(p, SUB_THREEWAY);
  9080. p->owner = p->subs[SUB_REAL].owner;
  9081. ast_hangup(chan);
  9082. goto quit;
  9083. }
  9084. } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
  9085. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
  9086. && !canmatch_featurecode(pickupexten, exten)) {
  9087. ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
  9088. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
  9089. ast_channel_context(chan));
  9090. break;
  9091. }
  9092. if (!timeout)
  9093. timeout = gendigittimeout;
  9094. if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))
  9095. tone_zone_play_tone(p->subs[idx].dfd, -1);
  9096. }
  9097. break;
  9098. case SIG_FXSLS:
  9099. case SIG_FXSGS:
  9100. case SIG_FXSKS:
  9101. /* check for SMDI messages */
  9102. if (p->use_smdi && p->smdi_iface) {
  9103. smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
  9104. if (smdi_msg != NULL) {
  9105. ast_channel_exten_set(chan, smdi_msg->fwd_st);
  9106. if (smdi_msg->type == 'B')
  9107. pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
  9108. else if (smdi_msg->type == 'N')
  9109. pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
  9110. ast_debug(1, "Received SMDI message on %s\n", ast_channel_name(chan));
  9111. } else {
  9112. ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
  9113. }
  9114. }
  9115. if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
  9116. number = smdi_msg->calling_st;
  9117. /* If we want caller id, we're in a prering state due to a polarity reversal
  9118. * and we're set to use a polarity reversal to trigger the start of caller id,
  9119. * grab the caller id and wait for ringing to start... */
  9120. } else if (p->use_callerid && (ast_channel_state(chan) == AST_STATE_PRERING &&
  9121. (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) {
  9122. /* If set to use DTMF CID signalling, listen for DTMF */
  9123. if (p->cid_signalling == CID_SIG_DTMF) {
  9124. int k = 0;
  9125. int off_ms;
  9126. struct timeval start = ast_tvnow();
  9127. int ms;
  9128. cs = NULL;
  9129. ast_debug(1, "Receiving DTMF cid on channel %s\n", ast_channel_name(chan));
  9130. dahdi_setlinear(p->subs[idx].dfd, 0);
  9131. /*
  9132. * We are the only party interested in the Rx stream since
  9133. * we have not answered yet. We don't need or even want DTMF
  9134. * emulation. The DTMF digits can come so fast that emulation
  9135. * can drop some of them.
  9136. */
  9137. ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
  9138. off_ms = 4000;/* This is a typical OFF time between rings. */
  9139. for (;;) {
  9140. struct ast_frame *f;
  9141. ms = ast_remaining_ms(start, off_ms);
  9142. res = ast_waitfor(chan, ms);
  9143. if (res <= 0) {
  9144. /*
  9145. * We do not need to restore the dahdi_setlinear()
  9146. * or AST_FLAG_END_DTMF_ONLY flag settings since we
  9147. * are hanging up the channel.
  9148. */
  9149. ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
  9150. "Exiting simple switch\n");
  9151. ast_hangup(chan);
  9152. goto quit;
  9153. }
  9154. f = ast_read(chan);
  9155. if (!f)
  9156. break;
  9157. if (f->frametype == AST_FRAME_DTMF) {
  9158. if (k < ARRAY_LEN(dtmfbuf) - 1) {
  9159. dtmfbuf[k++] = f->subclass.integer;
  9160. }
  9161. ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
  9162. start = ast_tvnow();
  9163. }
  9164. ast_frfree(f);
  9165. if (ast_channel_state(chan) == AST_STATE_RING ||
  9166. ast_channel_state(chan) == AST_STATE_RINGING)
  9167. break; /* Got ring */
  9168. }
  9169. ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
  9170. dtmfbuf[k] = '\0';
  9171. dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  9172. /* Got cid and ring. */
  9173. ast_debug(1, "CID got string '%s'\n", dtmfbuf);
  9174. callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
  9175. ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
  9176. /* If first byte is NULL, we have no cid */
  9177. if (!ast_strlen_zero(dtmfcid))
  9178. number = dtmfcid;
  9179. else
  9180. number = NULL;
  9181. /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
  9182. } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
  9183. cs = callerid_new(p->cid_signalling);
  9184. if (cs) {
  9185. int off_ms;
  9186. struct timeval start;
  9187. int ms;
  9188. samples = 0;
  9189. #if 1
  9190. bump_gains(p);
  9191. #endif
  9192. /* Take out of linear mode for Caller*ID processing */
  9193. dahdi_setlinear(p->subs[idx].dfd, 0);
  9194. /* First we wait and listen for the Caller*ID */
  9195. for (;;) {
  9196. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  9197. if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
  9198. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  9199. callerid_free(cs);
  9200. ast_hangup(chan);
  9201. goto quit;
  9202. }
  9203. if (i & DAHDI_IOMUX_SIGEVENT) {
  9204. res = dahdi_get_event(p->subs[idx].dfd);
  9205. ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
  9206. if (res == DAHDI_EVENT_NOALARM) {
  9207. p->inalarm = 0;
  9208. }
  9209. if (p->cid_signalling == CID_SIG_V23_JP) {
  9210. if (res == DAHDI_EVENT_RINGBEGIN) {
  9211. res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  9212. usleep(1);
  9213. }
  9214. } else {
  9215. res = 0;
  9216. break;
  9217. }
  9218. } else if (i & DAHDI_IOMUX_READ) {
  9219. res = read(p->subs[idx].dfd, buf, sizeof(buf));
  9220. if (res < 0) {
  9221. if (errno != ELAST) {
  9222. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  9223. callerid_free(cs);
  9224. ast_hangup(chan);
  9225. goto quit;
  9226. }
  9227. break;
  9228. }
  9229. samples += res;
  9230. if (p->cid_signalling == CID_SIG_V23_JP) {
  9231. res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
  9232. } else {
  9233. res = callerid_feed(cs, buf, res, AST_LAW(p));
  9234. }
  9235. if (res < 0) {
  9236. /*
  9237. * The previous diagnostic message output likely
  9238. * explains why it failed.
  9239. */
  9240. ast_log(LOG_WARNING,
  9241. "Failed to decode CallerID on channel '%s'\n",
  9242. ast_channel_name(chan));
  9243. break;
  9244. } else if (res)
  9245. break;
  9246. else if (samples > (8000 * 10))
  9247. break;
  9248. }
  9249. }
  9250. if (res == 1) {
  9251. callerid_get(cs, &name, &number, &flags);
  9252. ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
  9253. }
  9254. if (p->cid_signalling == CID_SIG_V23_JP) {
  9255. res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
  9256. usleep(1);
  9257. }
  9258. /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
  9259. start = ast_tvnow();
  9260. off_ms = 4000;/* This is a typical OFF time between rings. */
  9261. for (;;) {
  9262. struct ast_frame *f;
  9263. ms = ast_remaining_ms(start, off_ms);
  9264. res = ast_waitfor(chan, ms);
  9265. if (res <= 0) {
  9266. ast_log(LOG_WARNING, "CID timed out waiting for ring. "
  9267. "Exiting simple switch\n");
  9268. ast_hangup(chan);
  9269. goto quit;
  9270. }
  9271. if (!(f = ast_read(chan))) {
  9272. ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
  9273. ast_hangup(chan);
  9274. goto quit;
  9275. }
  9276. ast_frfree(f);
  9277. if (ast_channel_state(chan) == AST_STATE_RING ||
  9278. ast_channel_state(chan) == AST_STATE_RINGING)
  9279. break; /* Got ring */
  9280. }
  9281. /* We must have a ring by now, so, if configured, lets try to listen for
  9282. * distinctive ringing */
  9283. if (p->usedistinctiveringdetection) {
  9284. len = 0;
  9285. distMatches = 0;
  9286. /* Clear the current ring data array so we don't have old data in it. */
  9287. for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
  9288. curRingData[receivedRingT] = 0;
  9289. receivedRingT = 0;
  9290. counter = 0;
  9291. counter1 = 0;
  9292. /* Check to see if context is what it should be, if not set to be. */
  9293. if (strcmp(p->context,p->defcontext) != 0) {
  9294. ast_copy_string(p->context, p->defcontext, sizeof(p->context));
  9295. ast_channel_context_set(chan, p->defcontext);
  9296. }
  9297. for (;;) {
  9298. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  9299. if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
  9300. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  9301. callerid_free(cs);
  9302. ast_hangup(chan);
  9303. goto quit;
  9304. }
  9305. if (i & DAHDI_IOMUX_SIGEVENT) {
  9306. res = dahdi_get_event(p->subs[idx].dfd);
  9307. ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
  9308. if (res == DAHDI_EVENT_NOALARM) {
  9309. p->inalarm = 0;
  9310. }
  9311. res = 0;
  9312. /* Let us detect distinctive ring */
  9313. curRingData[receivedRingT] = p->ringt;
  9314. if (p->ringt < p->ringt_base/2)
  9315. break;
  9316. /* Increment the ringT counter so we can match it against
  9317. values in chan_dahdi.conf for distinctive ring */
  9318. if (++receivedRingT == ARRAY_LEN(curRingData))
  9319. break;
  9320. } else if (i & DAHDI_IOMUX_READ) {
  9321. res = read(p->subs[idx].dfd, buf, sizeof(buf));
  9322. if (res < 0) {
  9323. if (errno != ELAST) {
  9324. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  9325. callerid_free(cs);
  9326. ast_hangup(chan);
  9327. goto quit;
  9328. }
  9329. break;
  9330. }
  9331. if (p->ringt > 0) {
  9332. if (!(--p->ringt)) {
  9333. res = -1;
  9334. break;
  9335. }
  9336. }
  9337. }
  9338. }
  9339. /* this only shows up if you have n of the dring patterns filled in */
  9340. ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
  9341. for (counter = 0; counter < 3; counter++) {
  9342. /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
  9343. channel */
  9344. distMatches = 0;
  9345. for (counter1 = 0; counter1 < 3; counter1++) {
  9346. ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
  9347. if (p->drings.ringnum[counter].ring[counter1] == -1) {
  9348. ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
  9349. curRingData[counter1]);
  9350. distMatches++;
  9351. } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
  9352. curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
  9353. ast_verb(3, "Ring pattern matched in range: %d to %d\n",
  9354. (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
  9355. (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
  9356. distMatches++;
  9357. }
  9358. }
  9359. if (distMatches == 3) {
  9360. /* The ring matches, set the context to whatever is for distinctive ring.. */
  9361. ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
  9362. ast_channel_context_set(chan, S_OR(p->drings.ringContext[counter].contextData, p->defcontext));
  9363. ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
  9364. break;
  9365. }
  9366. }
  9367. }
  9368. /* Restore linear mode (if appropriate) for Caller*ID processing */
  9369. dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  9370. #if 1
  9371. restore_gains(p);
  9372. #endif
  9373. } else
  9374. ast_log(LOG_WARNING, "Unable to get caller ID space\n");
  9375. } else {
  9376. ast_log(LOG_WARNING, "Channel %s in prering "
  9377. "state, but I have nothing to do. "
  9378. "Terminating simple switch, should be "
  9379. "restarted by the actual ring.\n",
  9380. ast_channel_name(chan));
  9381. ast_hangup(chan);
  9382. goto quit;
  9383. }
  9384. } else if (p->use_callerid && p->cid_start == CID_START_RING) {
  9385. if (p->cid_signalling == CID_SIG_DTMF) {
  9386. int k = 0;
  9387. int off_ms;
  9388. struct timeval start;
  9389. int ms;
  9390. cs = NULL;
  9391. dahdi_setlinear(p->subs[idx].dfd, 0);
  9392. off_ms = 2000;
  9393. start = ast_tvnow();
  9394. for (;;) {
  9395. struct ast_frame *f;
  9396. ms = ast_remaining_ms(start, off_ms);
  9397. res = ast_waitfor(chan, ms);
  9398. if (res <= 0) {
  9399. ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
  9400. "Exiting simple switch\n");
  9401. ast_hangup(chan);
  9402. goto quit;
  9403. }
  9404. f = ast_read(chan);
  9405. if (!f) {
  9406. /* Hangup received waiting for DTMFCID. Exiting simple switch. */
  9407. ast_hangup(chan);
  9408. goto quit;
  9409. }
  9410. if (f->frametype == AST_FRAME_DTMF) {
  9411. dtmfbuf[k++] = f->subclass.integer;
  9412. ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
  9413. start = ast_tvnow();
  9414. }
  9415. ast_frfree(f);
  9416. if (p->ringt_base == p->ringt)
  9417. break;
  9418. }
  9419. dtmfbuf[k] = '\0';
  9420. dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  9421. /* Got cid and ring. */
  9422. callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
  9423. ast_debug(1, "CID is '%s', flags %d\n",
  9424. dtmfcid, flags);
  9425. /* If first byte is NULL, we have no cid */
  9426. if (!ast_strlen_zero(dtmfcid))
  9427. number = dtmfcid;
  9428. else
  9429. number = NULL;
  9430. /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
  9431. } else {
  9432. /* FSK Bell202 callerID */
  9433. cs = callerid_new(p->cid_signalling);
  9434. if (cs) {
  9435. #if 1
  9436. bump_gains(p);
  9437. #endif
  9438. samples = 0;
  9439. len = 0;
  9440. distMatches = 0;
  9441. /* Clear the current ring data array so we don't have old data in it. */
  9442. for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
  9443. curRingData[receivedRingT] = 0;
  9444. receivedRingT = 0;
  9445. counter = 0;
  9446. counter1 = 0;
  9447. /* Check to see if context is what it should be, if not set to be. */
  9448. if (strcmp(p->context,p->defcontext) != 0) {
  9449. ast_copy_string(p->context, p->defcontext, sizeof(p->context));
  9450. ast_channel_context_set(chan, p->defcontext);
  9451. }
  9452. /* Take out of linear mode for Caller*ID processing */
  9453. dahdi_setlinear(p->subs[idx].dfd, 0);
  9454. for (;;) {
  9455. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  9456. if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
  9457. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  9458. callerid_free(cs);
  9459. ast_hangup(chan);
  9460. goto quit;
  9461. }
  9462. if (i & DAHDI_IOMUX_SIGEVENT) {
  9463. res = dahdi_get_event(p->subs[idx].dfd);
  9464. ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
  9465. if (res == DAHDI_EVENT_NOALARM) {
  9466. p->inalarm = 0;
  9467. }
  9468. /* If we get a PR event, they hung up while processing calerid */
  9469. if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
  9470. ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
  9471. p->polarity = POLARITY_IDLE;
  9472. callerid_free(cs);
  9473. ast_hangup(chan);
  9474. goto quit;
  9475. }
  9476. res = 0;
  9477. /* Let us detect callerid when the telco uses distinctive ring */
  9478. curRingData[receivedRingT] = p->ringt;
  9479. if (p->ringt < p->ringt_base/2)
  9480. break;
  9481. /* Increment the ringT counter so we can match it against
  9482. values in chan_dahdi.conf for distinctive ring */
  9483. if (++receivedRingT == ARRAY_LEN(curRingData))
  9484. break;
  9485. } else if (i & DAHDI_IOMUX_READ) {
  9486. res = read(p->subs[idx].dfd, buf, sizeof(buf));
  9487. if (res < 0) {
  9488. if (errno != ELAST) {
  9489. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  9490. callerid_free(cs);
  9491. ast_hangup(chan);
  9492. goto quit;
  9493. }
  9494. break;
  9495. }
  9496. if (p->ringt > 0) {
  9497. if (!(--p->ringt)) {
  9498. res = -1;
  9499. break;
  9500. }
  9501. }
  9502. samples += res;
  9503. res = callerid_feed(cs, buf, res, AST_LAW(p));
  9504. if (res < 0) {
  9505. /*
  9506. * The previous diagnostic message output likely
  9507. * explains why it failed.
  9508. */
  9509. ast_log(LOG_WARNING,
  9510. "Failed to decode CallerID on channel '%s'\n",
  9511. ast_channel_name(chan));
  9512. break;
  9513. } else if (res)
  9514. break;
  9515. else if (samples > (8000 * 10))
  9516. break;
  9517. }
  9518. }
  9519. if (res == 1) {
  9520. callerid_get(cs, &name, &number, &flags);
  9521. ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
  9522. }
  9523. if (distinctiveringaftercid == 1) {
  9524. /* Clear the current ring data array so we don't have old data in it. */
  9525. for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
  9526. curRingData[receivedRingT] = 0;
  9527. }
  9528. receivedRingT = 0;
  9529. ast_verb(3, "Detecting post-CID distinctive ring\n");
  9530. for (;;) {
  9531. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  9532. if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
  9533. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  9534. callerid_free(cs);
  9535. ast_hangup(chan);
  9536. goto quit;
  9537. }
  9538. if (i & DAHDI_IOMUX_SIGEVENT) {
  9539. res = dahdi_get_event(p->subs[idx].dfd);
  9540. ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
  9541. if (res == DAHDI_EVENT_NOALARM) {
  9542. p->inalarm = 0;
  9543. }
  9544. res = 0;
  9545. /* Let us detect callerid when the telco uses distinctive ring */
  9546. curRingData[receivedRingT] = p->ringt;
  9547. if (p->ringt < p->ringt_base/2)
  9548. break;
  9549. /* Increment the ringT counter so we can match it against
  9550. values in chan_dahdi.conf for distinctive ring */
  9551. if (++receivedRingT == ARRAY_LEN(curRingData))
  9552. break;
  9553. } else if (i & DAHDI_IOMUX_READ) {
  9554. res = read(p->subs[idx].dfd, buf, sizeof(buf));
  9555. if (res < 0) {
  9556. if (errno != ELAST) {
  9557. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  9558. callerid_free(cs);
  9559. ast_hangup(chan);
  9560. goto quit;
  9561. }
  9562. break;
  9563. }
  9564. if (p->ringt > 0) {
  9565. if (!(--p->ringt)) {
  9566. res = -1;
  9567. break;
  9568. }
  9569. }
  9570. }
  9571. }
  9572. }
  9573. if (p->usedistinctiveringdetection) {
  9574. /* this only shows up if you have n of the dring patterns filled in */
  9575. ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
  9576. for (counter = 0; counter < 3; counter++) {
  9577. /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
  9578. channel */
  9579. /* this only shows up if you have n of the dring patterns filled in */
  9580. ast_verb(3, "Checking %d,%d,%d\n",
  9581. p->drings.ringnum[counter].ring[0],
  9582. p->drings.ringnum[counter].ring[1],
  9583. p->drings.ringnum[counter].ring[2]);
  9584. distMatches = 0;
  9585. for (counter1 = 0; counter1 < 3; counter1++) {
  9586. ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
  9587. if (p->drings.ringnum[counter].ring[counter1] == -1) {
  9588. ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
  9589. curRingData[counter1]);
  9590. distMatches++;
  9591. }
  9592. else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
  9593. curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
  9594. ast_verb(3, "Ring pattern matched in range: %d to %d\n",
  9595. (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
  9596. (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
  9597. distMatches++;
  9598. }
  9599. }
  9600. if (distMatches == 3) {
  9601. /* The ring matches, set the context to whatever is for distinctive ring.. */
  9602. ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
  9603. ast_channel_context_set(chan, S_OR(p->drings.ringContext[counter].contextData, p->defcontext));
  9604. ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
  9605. break;
  9606. }
  9607. }
  9608. }
  9609. /* Restore linear mode (if appropriate) for Caller*ID processing */
  9610. dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
  9611. #if 1
  9612. restore_gains(p);
  9613. #endif
  9614. if (res < 0) {
  9615. ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", ast_channel_name(chan));
  9616. }
  9617. } else
  9618. ast_log(LOG_WARNING, "Unable to get caller ID space\n");
  9619. }
  9620. } else
  9621. cs = NULL;
  9622. if (number)
  9623. ast_shrink_phone_number(number);
  9624. ast_set_callerid(chan, number, name, number);
  9625. ao2_cleanup(smdi_msg);
  9626. if (cs)
  9627. callerid_free(cs);
  9628. my_handle_notify_message(chan, p, flags, -1);
  9629. ast_channel_lock(chan);
  9630. ast_setstate(chan, AST_STATE_RING);
  9631. ast_channel_rings_set(chan, 1);
  9632. ast_channel_unlock(chan);
  9633. p->ringt = p->ringt_base;
  9634. res = ast_pbx_run(chan);
  9635. if (res) {
  9636. ast_hangup(chan);
  9637. ast_log(LOG_WARNING, "PBX exited non-zero\n");
  9638. }
  9639. goto quit;
  9640. default:
  9641. ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
  9642. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  9643. if (res < 0)
  9644. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
  9645. }
  9646. res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
  9647. if (res < 0)
  9648. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
  9649. ast_hangup(chan);
  9650. quit:
  9651. ast_mutex_lock(&ss_thread_lock);
  9652. ss_thread_count--;
  9653. ast_cond_signal(&ss_thread_complete);
  9654. ast_mutex_unlock(&ss_thread_lock);
  9655. return NULL;
  9656. }
  9657. struct mwi_thread_data {
  9658. struct dahdi_pvt *pvt;
  9659. unsigned char buf[READ_SIZE];
  9660. size_t len;
  9661. };
  9662. static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
  9663. {
  9664. int x;
  9665. int sum = 0;
  9666. if (!len)
  9667. return 0;
  9668. for (x = 0; x < len; x++)
  9669. sum += abs(law == ast_format_ulaw ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
  9670. return sum / len;
  9671. }
  9672. static void *mwi_thread(void *data)
  9673. {
  9674. struct mwi_thread_data *mtd = data;
  9675. struct callerid_state *cs;
  9676. pthread_t threadid;
  9677. int samples = 0;
  9678. char *name, *number;
  9679. int flags;
  9680. int i, res;
  9681. unsigned int spill_done = 0;
  9682. int spill_result = -1;
  9683. if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
  9684. goto quit_no_clean;
  9685. }
  9686. callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
  9687. bump_gains(mtd->pvt);
  9688. for (;;) {
  9689. i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
  9690. if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) {
  9691. ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
  9692. goto quit;
  9693. }
  9694. if (i & DAHDI_IOMUX_SIGEVENT) {
  9695. struct ast_channel *chan;
  9696. struct ast_callid *callid = NULL;
  9697. int callid_created;
  9698. /* If we get an event, screen out events that we do not act on.
  9699. * Otherwise, cancel and go to the simple switch to let it deal with it.
  9700. */
  9701. res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd);
  9702. switch (res) {
  9703. case DAHDI_EVENT_NEONMWI_ACTIVE:
  9704. case DAHDI_EVENT_NEONMWI_INACTIVE:
  9705. case DAHDI_EVENT_NONE:
  9706. case DAHDI_EVENT_BITSCHANGED:
  9707. break;
  9708. case DAHDI_EVENT_NOALARM:
  9709. if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
  9710. struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
  9711. analog_p->inalarm = 0;
  9712. }
  9713. mtd->pvt->inalarm = 0;
  9714. handle_clear_alarms(mtd->pvt);
  9715. break;
  9716. case DAHDI_EVENT_ALARM:
  9717. if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
  9718. struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
  9719. analog_p->inalarm = 1;
  9720. }
  9721. mtd->pvt->inalarm = 1;
  9722. res = get_alarms(mtd->pvt);
  9723. handle_alarms(mtd->pvt, res);
  9724. break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
  9725. default:
  9726. callid_created = ast_callid_threadstorage_auto(&callid);
  9727. ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res));
  9728. callerid_free(cs);
  9729. restore_gains(mtd->pvt);
  9730. mtd->pvt->ringt = mtd->pvt->ringt_base;
  9731. if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid))) {
  9732. int result;
  9733. if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
  9734. result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan);
  9735. } else {
  9736. result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
  9737. }
  9738. if (result) {
  9739. ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel);
  9740. res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  9741. if (res < 0)
  9742. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel);
  9743. ast_hangup(chan);
  9744. }
  9745. } else {
  9746. ast_log(LOG_WARNING, "Could not create channel to handle call\n");
  9747. }
  9748. ast_callid_threadstorage_auto_clean(callid, callid_created);
  9749. goto quit_no_clean;
  9750. }
  9751. } else if (i & DAHDI_IOMUX_READ) {
  9752. if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) {
  9753. if (errno != ELAST) {
  9754. ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
  9755. goto quit;
  9756. }
  9757. break;
  9758. }
  9759. samples += res;
  9760. if (!spill_done) {
  9761. if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
  9762. /*
  9763. * The previous diagnostic message output likely
  9764. * explains why it failed.
  9765. */
  9766. ast_log(LOG_WARNING, "Failed to decode CallerID\n");
  9767. break;
  9768. } else if (spill_result) {
  9769. spill_done = 1;
  9770. }
  9771. } else {
  9772. /* keep reading data until the energy level drops below the threshold
  9773. so we don't get another 'trigger' on the remaining carrier signal
  9774. */
  9775. if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel)
  9776. break;
  9777. }
  9778. if (samples > (8000 * 4)) /*Termination case - time to give up*/
  9779. break;
  9780. }
  9781. }
  9782. if (spill_result == 1) {
  9783. callerid_get(cs, &name, &number, &flags);
  9784. if (flags & CID_MSGWAITING) {
  9785. ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel);
  9786. notify_message(mtd->pvt->mailbox, 1);
  9787. } else if (flags & CID_NOMSGWAITING) {
  9788. ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel);
  9789. notify_message(mtd->pvt->mailbox, 0);
  9790. } else {
  9791. ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel);
  9792. }
  9793. }
  9794. quit:
  9795. callerid_free(cs);
  9796. restore_gains(mtd->pvt);
  9797. quit_no_clean:
  9798. mtd->pvt->mwimonitoractive = 0;
  9799. ast_free(mtd);
  9800. return NULL;
  9801. }
  9802. /*
  9803. * The following three functions (mwi_send_init, mwi_send_process_buffer,
  9804. * mwi_send_process_event) work with the do_monitor thread to generate mwi spills
  9805. * that are sent out via FXS port on voicemail state change. The execution of
  9806. * the mwi send is state driven and can either generate a ring pulse prior to
  9807. * sending the fsk spill or simply send an fsk spill.
  9808. */
  9809. static int mwi_send_init(struct dahdi_pvt * pvt)
  9810. {
  9811. int x;
  9812. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  9813. /* Determine how this spill is to be sent */
  9814. if (pvt->mwisend_rpas) {
  9815. pvt->mwisend_data.mwisend_current = MWI_SEND_SA;
  9816. pvt->mwisendactive = 1;
  9817. } else if (pvt->mwisend_fsk) {
  9818. pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
  9819. pvt->mwisendactive = 1;
  9820. } else {
  9821. pvt->mwisendactive = 0;
  9822. return 0;
  9823. }
  9824. #else
  9825. if (mwisend_rpas) {
  9826. pvt->mwisend_data.mwisend_current = MWI_SEND_SA;
  9827. } else {
  9828. pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
  9829. }
  9830. pvt->mwisendactive = 1;
  9831. #endif
  9832. if (pvt->cidspill) {
  9833. ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n");
  9834. ast_free(pvt->cidspill);
  9835. pvt->cidspill = NULL;
  9836. pvt->cidpos = 0;
  9837. pvt->cidlen = 0;
  9838. }
  9839. pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE);
  9840. if (!pvt->cidspill) {
  9841. pvt->mwisendactive = 0;
  9842. return -1;
  9843. }
  9844. x = DAHDI_FLUSH_BOTH;
  9845. ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
  9846. x = 3000;
  9847. ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x);
  9848. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  9849. if (pvt->mwisend_fsk) {
  9850. #endif
  9851. pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt),
  9852. CID_MWI_TYPE_MDMF_FULL, AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
  9853. pvt->cidpos = 0;
  9854. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  9855. }
  9856. #endif
  9857. return 0;
  9858. }
  9859. static int mwi_send_process_buffer(struct dahdi_pvt * pvt, int num_read)
  9860. {
  9861. struct timeval now;
  9862. int res;
  9863. /* sanity check to catch if this had been interrupted previously
  9864. * i.e. state says there is more to do but there is no spill allocated
  9865. */
  9866. if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) {
  9867. pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
  9868. } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
  9869. /* Normal processing -- Perform mwi send action */
  9870. switch ( pvt->mwisend_data.mwisend_current) {
  9871. case MWI_SEND_SA:
  9872. /* Send the Ring Pulse Signal Alert */
  9873. res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence);
  9874. if (res) {
  9875. ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno));
  9876. goto quit;
  9877. }
  9878. res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING);
  9879. pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT;
  9880. break;
  9881. case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */
  9882. break;
  9883. case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/
  9884. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  9885. if (pvt->mwisend_fsk) {
  9886. #endif
  9887. gettimeofday(&now, NULL);
  9888. if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) {
  9889. pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
  9890. }
  9891. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  9892. } else { /* support for mwisendtype=nofsk */
  9893. pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP;
  9894. }
  9895. #endif
  9896. break;
  9897. case MWI_SEND_SPILL:
  9898. /* We read some number of bytes. Write an equal amount of data */
  9899. if (0 < num_read) {
  9900. if (num_read > pvt->cidlen - pvt->cidpos) {
  9901. num_read = pvt->cidlen - pvt->cidpos;
  9902. }
  9903. res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read);
  9904. if (res > 0) {
  9905. pvt->cidpos += res;
  9906. if (pvt->cidpos >= pvt->cidlen) {
  9907. pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP;
  9908. }
  9909. } else {
  9910. ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno));
  9911. goto quit;
  9912. }
  9913. }
  9914. break;
  9915. case MWI_SEND_CLEANUP:
  9916. /* For now, do nothing */
  9917. pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
  9918. break;
  9919. default:
  9920. /* Should not get here, punt*/
  9921. goto quit;
  9922. }
  9923. }
  9924. if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) {
  9925. if (pvt->cidspill) {
  9926. ast_free(pvt->cidspill);
  9927. pvt->cidspill = NULL;
  9928. pvt->cidpos = 0;
  9929. pvt->cidlen = 0;
  9930. }
  9931. pvt->mwisendactive = 0;
  9932. }
  9933. return 0;
  9934. quit:
  9935. if (pvt->cidspill) {
  9936. ast_free(pvt->cidspill);
  9937. pvt->cidspill = NULL;
  9938. pvt->cidpos = 0;
  9939. pvt->cidlen = 0;
  9940. }
  9941. pvt->mwisendactive = 0;
  9942. return -1;
  9943. }
  9944. static int mwi_send_process_event(struct dahdi_pvt * pvt, int event)
  9945. {
  9946. int handled = 0;
  9947. if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
  9948. switch (event) {
  9949. case DAHDI_EVENT_RINGEROFF:
  9950. if (pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) {
  9951. handled = 1;
  9952. if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) {
  9953. ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno));
  9954. ast_free(pvt->cidspill);
  9955. pvt->cidspill = NULL;
  9956. pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
  9957. pvt->mwisendactive = 0;
  9958. } else {
  9959. pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE;
  9960. gettimeofday(&pvt->mwisend_data.pause, NULL);
  9961. }
  9962. }
  9963. break;
  9964. /* Going off hook, I need to punt this spill */
  9965. case DAHDI_EVENT_RINGOFFHOOK:
  9966. if (pvt->cidspill) {
  9967. ast_free(pvt->cidspill);
  9968. pvt->cidspill = NULL;
  9969. pvt->cidpos = 0;
  9970. pvt->cidlen = 0;
  9971. }
  9972. pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
  9973. pvt->mwisendactive = 0;
  9974. break;
  9975. case DAHDI_EVENT_RINGERON:
  9976. case DAHDI_EVENT_HOOKCOMPLETE:
  9977. break;
  9978. default:
  9979. break;
  9980. }
  9981. }
  9982. return handled;
  9983. }
  9984. /* destroy a range DAHDI channels, identified by their number */
  9985. static void dahdi_destroy_channel_range(int start, int end)
  9986. {
  9987. struct dahdi_pvt *cur;
  9988. struct dahdi_pvt *next;
  9989. int destroyed_first = 0;
  9990. int destroyed_last = 0;
  9991. ast_mutex_lock(&iflock);
  9992. ast_debug(1, "range: %d-%d\n", start, end);
  9993. for (cur = iflist; cur; cur = next) {
  9994. next = cur->next;
  9995. if (cur->channel >= start && cur->channel <= end) {
  9996. int x = DAHDI_FLASH;
  9997. if (cur->channel > destroyed_last) {
  9998. destroyed_last = cur->channel;
  9999. }
  10000. if (destroyed_first < 1 || cur->channel < destroyed_first) {
  10001. destroyed_first = cur->channel;
  10002. }
  10003. ast_debug(3, "Destroying %d\n", cur->channel);
  10004. /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
  10005. ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  10006. destroy_channel(cur, 1);
  10007. ast_module_unref(ast_module_info->self);
  10008. }
  10009. }
  10010. ast_mutex_unlock(&iflock);
  10011. if (destroyed_first > start || destroyed_last < end) {
  10012. ast_debug(1, "Asked to destroy %d-%d, destroyed %d-%d,\n",
  10013. start, end, destroyed_first, destroyed_last);
  10014. }
  10015. }
  10016. static int setup_dahdi(int reload);
  10017. static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, struct dahdi_chan_conf *base_conf, struct dahdi_chan_conf *conf);
  10018. /*!
  10019. * \internal
  10020. * \brief create a range of new DAHDI channels
  10021. *
  10022. * \param start first channel in the range
  10023. * \param end last channel in the range
  10024. *
  10025. * \retval RESULT_SUCCESS on success.
  10026. * \retval RESULT_FAILURE on error.
  10027. */
  10028. static int dahdi_create_channel_range(int start, int end)
  10029. {
  10030. struct dahdi_pvt *cur;
  10031. struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
  10032. struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
  10033. struct dahdi_chan_conf conf = dahdi_chan_conf_default();
  10034. int ret = RESULT_FAILURE; /* be pessimistic */
  10035. ast_debug(1, "channel range caps: %d - %d\n", start, end);
  10036. ast_mutex_lock(&iflock);
  10037. for (cur = iflist; cur; cur = cur->next) {
  10038. if (cur->channel >= start && cur->channel <= end) {
  10039. ast_log(LOG_ERROR,
  10040. "channel range %d-%d is occupied\n",
  10041. start, end);
  10042. goto out;
  10043. }
  10044. }
  10045. #ifdef HAVE_PRI
  10046. {
  10047. int i, x;
  10048. for (x = 0; x < NUM_SPANS; x++) {
  10049. struct dahdi_pri *pri = pris + x;
  10050. if (!pris[x].pri.pvts[0]) {
  10051. break;
  10052. }
  10053. for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
  10054. int channo = pri->dchannels[i];
  10055. if (!channo) {
  10056. break;
  10057. }
  10058. if (!pri->pri.fds[i]) {
  10059. break;
  10060. }
  10061. if (channo >= start && channo <= end) {
  10062. ast_log(LOG_ERROR,
  10063. "channel range %d-%d is occupied by span %d\n",
  10064. start, end, x + 1);
  10065. goto out;
  10066. }
  10067. }
  10068. }
  10069. }
  10070. #endif
  10071. if (!default_conf.chan.cc_params || !base_conf.chan.cc_params ||
  10072. !conf.chan.cc_params) {
  10073. goto out;
  10074. }
  10075. default_conf.wanted_channels_start = start;
  10076. base_conf.wanted_channels_start = start;
  10077. conf.wanted_channels_start = start;
  10078. default_conf.wanted_channels_end = end;
  10079. base_conf.wanted_channels_end = end;
  10080. conf.wanted_channels_end = end;
  10081. if (setup_dahdi_int(0, &default_conf, &base_conf, &conf) == 0) {
  10082. ret = RESULT_SUCCESS;
  10083. }
  10084. out:
  10085. ast_cc_config_params_destroy(default_conf.chan.cc_params);
  10086. ast_cc_config_params_destroy(base_conf.chan.cc_params);
  10087. ast_cc_config_params_destroy(conf.chan.cc_params);
  10088. ast_mutex_unlock(&iflock);
  10089. return ret;
  10090. }
  10091. static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
  10092. {
  10093. int res;
  10094. pthread_t threadid;
  10095. struct ast_channel *chan;
  10096. struct ast_callid *callid = NULL;
  10097. int callid_created;
  10098. /* Handle an event on a given channel for the monitor thread. */
  10099. switch (event) {
  10100. case DAHDI_EVENT_NONE:
  10101. case DAHDI_EVENT_BITSCHANGED:
  10102. break;
  10103. case DAHDI_EVENT_WINKFLASH:
  10104. case DAHDI_EVENT_RINGOFFHOOK:
  10105. if (i->inalarm) break;
  10106. if (i->radio) break;
  10107. /* Got a ring/answer. What kind of channel are we? */
  10108. switch (i->sig) {
  10109. case SIG_FXOLS:
  10110. case SIG_FXOGS:
  10111. case SIG_FXOKS:
  10112. res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  10113. if (res && (errno == EBUSY)) {
  10114. break;
  10115. }
  10116. callid_created = ast_callid_threadstorage_auto(&callid);
  10117. /* Cancel VMWI spill */
  10118. ast_free(i->cidspill);
  10119. i->cidspill = NULL;
  10120. restore_conference(i);
  10121. if (i->immediate) {
  10122. dahdi_ec_enable(i);
  10123. /* The channel is immediately up. Start right away */
  10124. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
  10125. chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, NULL, callid);
  10126. if (!chan) {
  10127. ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
  10128. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  10129. if (res < 0)
  10130. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
  10131. }
  10132. } else {
  10133. /* Check for callerid, digits, etc */
  10134. chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, NULL, callid);
  10135. if (chan) {
  10136. if (has_voicemail(i))
  10137. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
  10138. else
  10139. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
  10140. if (res < 0)
  10141. ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
  10142. if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
  10143. ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
  10144. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  10145. if (res < 0)
  10146. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
  10147. ast_hangup(chan);
  10148. }
  10149. } else
  10150. ast_log(LOG_WARNING, "Unable to create channel\n");
  10151. }
  10152. ast_callid_threadstorage_auto_clean(callid, callid_created);
  10153. break;
  10154. case SIG_FXSLS:
  10155. case SIG_FXSGS:
  10156. case SIG_FXSKS:
  10157. i->ringt = i->ringt_base;
  10158. /* Fall through */
  10159. case SIG_EMWINK:
  10160. case SIG_FEATD:
  10161. case SIG_FEATDMF:
  10162. case SIG_FEATDMF_TA:
  10163. case SIG_E911:
  10164. case SIG_FGC_CAMA:
  10165. case SIG_FGC_CAMAMF:
  10166. case SIG_FEATB:
  10167. case SIG_EM:
  10168. case SIG_EM_E1:
  10169. case SIG_SFWINK:
  10170. case SIG_SF_FEATD:
  10171. case SIG_SF_FEATDMF:
  10172. case SIG_SF_FEATB:
  10173. case SIG_SF:
  10174. /* Check for callerid, digits, etc */
  10175. callid_created = ast_callid_threadstorage_auto(&callid);
  10176. if (i->cid_start == CID_START_POLARITY_IN) {
  10177. chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
  10178. } else {
  10179. chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid);
  10180. }
  10181. if (!chan) {
  10182. ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
  10183. } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
  10184. ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
  10185. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  10186. if (res < 0) {
  10187. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
  10188. }
  10189. ast_hangup(chan);
  10190. }
  10191. ast_callid_threadstorage_auto_clean(callid, callid_created);
  10192. break;
  10193. default:
  10194. ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
  10195. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
  10196. if (res < 0)
  10197. ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
  10198. return NULL;
  10199. }
  10200. break;
  10201. case DAHDI_EVENT_NOALARM:
  10202. switch (i->sig) {
  10203. #if defined(HAVE_PRI)
  10204. case SIG_PRI_LIB_HANDLE_CASES:
  10205. ast_mutex_lock(&i->lock);
  10206. sig_pri_chan_alarm_notify(i->sig_pvt, 1);
  10207. ast_mutex_unlock(&i->lock);
  10208. break;
  10209. #endif /* defined(HAVE_PRI) */
  10210. #if defined(HAVE_SS7)
  10211. case SIG_SS7:
  10212. sig_ss7_set_alarm(i->sig_pvt, 0);
  10213. break;
  10214. #endif /* defined(HAVE_SS7) */
  10215. default:
  10216. i->inalarm = 0;
  10217. break;
  10218. }
  10219. handle_clear_alarms(i);
  10220. break;
  10221. case DAHDI_EVENT_ALARM:
  10222. switch (i->sig) {
  10223. #if defined(HAVE_PRI)
  10224. case SIG_PRI_LIB_HANDLE_CASES:
  10225. ast_mutex_lock(&i->lock);
  10226. sig_pri_chan_alarm_notify(i->sig_pvt, 0);
  10227. ast_mutex_unlock(&i->lock);
  10228. break;
  10229. #endif /* defined(HAVE_PRI) */
  10230. #if defined(HAVE_SS7)
  10231. case SIG_SS7:
  10232. sig_ss7_set_alarm(i->sig_pvt, 1);
  10233. break;
  10234. #endif /* defined(HAVE_SS7) */
  10235. default:
  10236. i->inalarm = 1;
  10237. break;
  10238. }
  10239. res = get_alarms(i);
  10240. handle_alarms(i, res);
  10241. /* fall thru intentionally */
  10242. case DAHDI_EVENT_ONHOOK:
  10243. if (i->radio)
  10244. break;
  10245. /* Back on hook. Hang up. */
  10246. switch (i->sig) {
  10247. case SIG_FXOLS:
  10248. case SIG_FXOGS:
  10249. case SIG_FEATD:
  10250. case SIG_FEATDMF:
  10251. case SIG_FEATDMF_TA:
  10252. case SIG_E911:
  10253. case SIG_FGC_CAMA:
  10254. case SIG_FGC_CAMAMF:
  10255. case SIG_FEATB:
  10256. case SIG_EM:
  10257. case SIG_EM_E1:
  10258. case SIG_EMWINK:
  10259. case SIG_SF_FEATD:
  10260. case SIG_SF_FEATDMF:
  10261. case SIG_SF_FEATB:
  10262. case SIG_SF:
  10263. case SIG_SFWINK:
  10264. case SIG_FXSLS:
  10265. case SIG_FXSGS:
  10266. case SIG_FXSKS:
  10267. case SIG_FXOKS:
  10268. dahdi_ec_disable(i);
  10269. /* Diddle the battery for the zhone */
  10270. #ifdef ZHONE_HACK
  10271. dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
  10272. usleep(1);
  10273. #endif
  10274. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
  10275. dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
  10276. break;
  10277. case SIG_SS7:
  10278. case SIG_PRI_LIB_HANDLE_CASES:
  10279. dahdi_ec_disable(i);
  10280. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
  10281. break;
  10282. default:
  10283. ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
  10284. res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
  10285. return NULL;
  10286. }
  10287. break;
  10288. case DAHDI_EVENT_POLARITY:
  10289. switch (i->sig) {
  10290. case SIG_FXSLS:
  10291. case SIG_FXSKS:
  10292. case SIG_FXSGS:
  10293. /* We have already got a PR before the channel was
  10294. created, but it wasn't handled. We need polarity
  10295. to be REV for remote hangup detection to work.
  10296. At least in Spain */
  10297. callid_created = ast_callid_threadstorage_auto(&callid);
  10298. if (i->hanguponpolarityswitch)
  10299. i->polarity = POLARITY_REV;
  10300. if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) {
  10301. i->polarity = POLARITY_REV;
  10302. ast_verb(2, "Starting post polarity "
  10303. "CID detection on channel %d\n",
  10304. i->channel);
  10305. chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
  10306. if (!chan) {
  10307. ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
  10308. } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
  10309. ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
  10310. ast_hangup(chan);
  10311. }
  10312. }
  10313. ast_callid_threadstorage_auto_clean(callid, callid_created);
  10314. break;
  10315. default:
  10316. ast_log(LOG_WARNING, "handle_init_event detected "
  10317. "polarity reversal on non-FXO (SIG_FXS) "
  10318. "interface %d\n", i->channel);
  10319. }
  10320. break;
  10321. case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
  10322. ast_log(LOG_NOTICE,
  10323. "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
  10324. i->channel);
  10325. return i;
  10326. case DAHDI_EVENT_NEONMWI_ACTIVE:
  10327. if (i->mwimonitor_neon) {
  10328. notify_message(i->mailbox, 1);
  10329. ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox);
  10330. }
  10331. break;
  10332. case DAHDI_EVENT_NEONMWI_INACTIVE:
  10333. if (i->mwimonitor_neon) {
  10334. notify_message(i->mailbox, 0);
  10335. ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox);
  10336. }
  10337. break;
  10338. }
  10339. return NULL;
  10340. }
  10341. static void monitor_pfds_clean(void *arg) {
  10342. struct pollfd **pfds = arg;
  10343. ast_free(*pfds);
  10344. }
  10345. static void *do_monitor(void *data)
  10346. {
  10347. int count, res, res2, spoint, pollres=0;
  10348. struct dahdi_pvt *i;
  10349. struct dahdi_pvt *last = NULL;
  10350. struct dahdi_pvt *doomed;
  10351. time_t thispass = 0, lastpass = 0;
  10352. int found;
  10353. char buf[1024];
  10354. struct pollfd *pfds=NULL;
  10355. int lastalloc = -1;
  10356. /* This thread monitors all the frame relay interfaces which are not yet in use
  10357. (and thus do not have a separate thread) indefinitely */
  10358. /* From here on out, we die whenever asked */
  10359. #if 0
  10360. if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
  10361. ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
  10362. return NULL;
  10363. }
  10364. ast_debug(1, "Monitor starting...\n");
  10365. #endif
  10366. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  10367. pthread_cleanup_push(monitor_pfds_clean, &pfds);
  10368. for (;;) {
  10369. /* Lock the interface list */
  10370. ast_mutex_lock(&iflock);
  10371. if (!pfds || (lastalloc != ifcount)) {
  10372. if (pfds) {
  10373. ast_free(pfds);
  10374. pfds = NULL;
  10375. }
  10376. if (ifcount) {
  10377. if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
  10378. ast_mutex_unlock(&iflock);
  10379. return NULL;
  10380. }
  10381. }
  10382. lastalloc = ifcount;
  10383. }
  10384. /* Build the stuff we're going to poll on, that is the socket of every
  10385. dahdi_pvt that does not have an associated owner channel */
  10386. count = 0;
  10387. for (i = iflist; i; i = i->next) {
  10388. ast_mutex_lock(&i->lock);
  10389. if (pfds && (i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
  10390. if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
  10391. struct analog_pvt *p = i->sig_pvt;
  10392. if (!p) {
  10393. ast_log(LOG_ERROR, "No sig_pvt?\n");
  10394. } else if (!p->owner && !p->subs[SUB_REAL].owner) {
  10395. /* This needs to be watched, as it lacks an owner */
  10396. pfds[count].fd = i->subs[SUB_REAL].dfd;
  10397. pfds[count].events = POLLPRI;
  10398. pfds[count].revents = 0;
  10399. /* Message waiting or r2 channels also get watched for reading */
  10400. if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
  10401. (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
  10402. pfds[count].events |= POLLIN;
  10403. }
  10404. count++;
  10405. }
  10406. } else {
  10407. if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
  10408. /* This needs to be watched, as it lacks an owner */
  10409. pfds[count].fd = i->subs[SUB_REAL].dfd;
  10410. pfds[count].events = POLLPRI;
  10411. pfds[count].revents = 0;
  10412. /* If we are monitoring for VMWI or sending CID, we need to
  10413. read from the channel as well */
  10414. if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
  10415. (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
  10416. pfds[count].events |= POLLIN;
  10417. }
  10418. count++;
  10419. }
  10420. }
  10421. }
  10422. ast_mutex_unlock(&i->lock);
  10423. }
  10424. /* Okay, now that we know what to do, release the interface lock */
  10425. ast_mutex_unlock(&iflock);
  10426. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  10427. pthread_testcancel();
  10428. /* Wait at least a second for something to happen */
  10429. res = poll(pfds, count, 1000);
  10430. pthread_testcancel();
  10431. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  10432. /* Okay, poll has finished. Let's see what happened. */
  10433. if (res < 0) {
  10434. if ((errno != EAGAIN) && (errno != EINTR))
  10435. ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
  10436. continue;
  10437. }
  10438. /* Alright, lock the interface list again, and let's look and see what has
  10439. happened */
  10440. ast_mutex_lock(&iflock);
  10441. found = 0;
  10442. spoint = 0;
  10443. lastpass = thispass;
  10444. thispass = time(NULL);
  10445. doomed = NULL;
  10446. for (i = iflist;; i = i->next) {
  10447. if (doomed) {
  10448. dahdi_destroy_channel_range(doomed->channel, doomed->channel);
  10449. doomed = NULL;
  10450. }
  10451. if (!i) {
  10452. break;
  10453. }
  10454. if (thispass != lastpass) {
  10455. if (!found && ((i == last) || ((i == iflist) && !last))) {
  10456. last = i;
  10457. if (last) {
  10458. struct analog_pvt *analog_p = last->sig_pvt;
  10459. /* Only allow MWI to be initiated on a quiescent fxs port */
  10460. if (analog_p
  10461. && !last->mwisendactive
  10462. && (last->sig & __DAHDI_SIG_FXO)
  10463. && !analog_p->fxsoffhookstate
  10464. && !last->owner
  10465. && !ast_strlen_zero(last->mailbox)
  10466. && (thispass - analog_p->onhooktime > 3)) {
  10467. res = has_voicemail(last);
  10468. if (analog_p->msgstate != res) {
  10469. /* Set driver resources for signalling VMWI */
  10470. res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
  10471. if (res2) {
  10472. /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */
  10473. ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno));
  10474. }
  10475. /* If enabled for FSK spill then initiate it */
  10476. if (mwi_send_init(last)) {
  10477. ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
  10478. }
  10479. analog_p->msgstate = res;
  10480. found ++;
  10481. }
  10482. }
  10483. last = last->next;
  10484. }
  10485. }
  10486. }
  10487. if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
  10488. if (i->radio && !i->owner)
  10489. {
  10490. res = dahdi_get_event(i->subs[SUB_REAL].dfd);
  10491. if (res)
  10492. {
  10493. ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
  10494. /* Don't hold iflock while handling init events */
  10495. ast_mutex_unlock(&iflock);
  10496. if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
  10497. doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res));
  10498. else
  10499. doomed = handle_init_event(i, res);
  10500. ast_mutex_lock(&iflock);
  10501. }
  10502. continue;
  10503. }
  10504. pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
  10505. if (pollres & POLLIN) {
  10506. if (i->owner || i->subs[SUB_REAL].owner) {
  10507. #ifdef HAVE_PRI
  10508. if (!i->pri)
  10509. #endif
  10510. ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
  10511. continue;
  10512. }
  10513. if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) {
  10514. ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
  10515. continue;
  10516. }
  10517. res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
  10518. if (res > 0) {
  10519. if (i->mwimonitor_fsk) {
  10520. if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) {
  10521. pthread_attr_t attr;
  10522. pthread_t threadid;
  10523. struct mwi_thread_data *mtd;
  10524. pthread_attr_init(&attr);
  10525. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  10526. ast_debug(1, "Maybe some MWI on port %d!\n", i->channel);
  10527. if ((mtd = ast_calloc(1, sizeof(*mtd)))) {
  10528. mtd->pvt = i;
  10529. memcpy(mtd->buf, buf, res);
  10530. mtd->len = res;
  10531. i->mwimonitoractive = 1;
  10532. if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) {
  10533. ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel);
  10534. i->mwimonitoractive = 0;
  10535. ast_free(mtd);
  10536. }
  10537. }
  10538. }
  10539. /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
  10540. } else if (i->cid_start == CID_START_DTMF_NOALERT) {
  10541. int energy;
  10542. struct timeval now;
  10543. /* State machine dtmfcid_holdoff_state allows for the line to settle
  10544. * before checking agin for dtmf energy. Presently waits for 500 mS before checking again
  10545. */
  10546. if (1 == i->dtmfcid_holdoff_state) {
  10547. gettimeofday(&i->dtmfcid_delay, NULL);
  10548. i->dtmfcid_holdoff_state = 2;
  10549. } else if (2 == i->dtmfcid_holdoff_state) {
  10550. gettimeofday(&now, NULL);
  10551. if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
  10552. i->dtmfcid_holdoff_state = 0;
  10553. }
  10554. } else {
  10555. energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
  10556. if (!i->mwisendactive && energy > dtmfcid_level) {
  10557. pthread_t threadid;
  10558. struct ast_channel *chan;
  10559. ast_mutex_unlock(&iflock);
  10560. if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
  10561. /* just in case this event changes or somehow destroys a channel, set doomed here too */
  10562. doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID);
  10563. i->dtmfcid_holdoff_state = 1;
  10564. } else {
  10565. struct ast_callid *callid = NULL;
  10566. int callid_created = ast_callid_threadstorage_auto(&callid);
  10567. chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
  10568. if (!chan) {
  10569. ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
  10570. } else {
  10571. res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
  10572. if (res) {
  10573. ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
  10574. ast_hangup(chan);
  10575. } else {
  10576. i->dtmfcid_holdoff_state = 1;
  10577. }
  10578. }
  10579. ast_callid_threadstorage_auto_clean(callid, callid_created);
  10580. }
  10581. ast_mutex_lock(&iflock);
  10582. }
  10583. }
  10584. }
  10585. if (i->mwisendactive) {
  10586. mwi_send_process_buffer(i, res);
  10587. }
  10588. } else {
  10589. ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
  10590. }
  10591. }
  10592. if (pollres & POLLPRI) {
  10593. if (i->owner || i->subs[SUB_REAL].owner) {
  10594. #ifdef HAVE_PRI
  10595. if (!i->pri)
  10596. #endif
  10597. ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
  10598. continue;
  10599. }
  10600. res = dahdi_get_event(i->subs[SUB_REAL].dfd);
  10601. ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
  10602. /* Don't hold iflock while handling init events */
  10603. ast_mutex_unlock(&iflock);
  10604. if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
  10605. if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
  10606. doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res));
  10607. else
  10608. doomed = handle_init_event(i, res);
  10609. }
  10610. ast_mutex_lock(&iflock);
  10611. }
  10612. }
  10613. }
  10614. ast_mutex_unlock(&iflock);
  10615. release_doomed_pris();
  10616. }
  10617. /* Never reached */
  10618. pthread_cleanup_pop(1);
  10619. return NULL;
  10620. }
  10621. static int restart_monitor(void)
  10622. {
  10623. /* If we're supposed to be stopped -- stay stopped */
  10624. if (monitor_thread == AST_PTHREADT_STOP)
  10625. return 0;
  10626. ast_mutex_lock(&monlock);
  10627. if (monitor_thread == pthread_self()) {
  10628. ast_mutex_unlock(&monlock);
  10629. ast_log(LOG_WARNING, "Cannot kill myself\n");
  10630. return -1;
  10631. }
  10632. if (monitor_thread != AST_PTHREADT_NULL) {
  10633. /* Wake up the thread */
  10634. pthread_kill(monitor_thread, SIGURG);
  10635. } else {
  10636. /* Start a new monitor */
  10637. if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
  10638. ast_mutex_unlock(&monlock);
  10639. ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
  10640. return -1;
  10641. }
  10642. }
  10643. ast_mutex_unlock(&monlock);
  10644. return 0;
  10645. }
  10646. #if defined(HAVE_PRI)
  10647. static int pri_resolve_span(int *span, int channel, int offset, struct dahdi_spaninfo *si)
  10648. {
  10649. int x;
  10650. int trunkgroup;
  10651. /* Get appropriate trunk group if there is one */
  10652. trunkgroup = pris[*span].mastertrunkgroup;
  10653. if (trunkgroup) {
  10654. /* Select a specific trunk group */
  10655. for (x = 0; x < NUM_SPANS; x++) {
  10656. if (pris[x].pri.trunkgroup == trunkgroup) {
  10657. *span = x;
  10658. return 0;
  10659. }
  10660. }
  10661. ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
  10662. *span = -1;
  10663. } else {
  10664. if (pris[*span].pri.trunkgroup) {
  10665. ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].pri.trunkgroup);
  10666. *span = -1;
  10667. } else if (pris[*span].mastertrunkgroup) {
  10668. ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
  10669. *span = -1;
  10670. } else {
  10671. if (si->totalchans == 31) {
  10672. /* E1 */
  10673. pris[*span].dchannels[0] = 16 + offset;
  10674. } else if (si->totalchans == 24) {
  10675. /* T1 or J1 */
  10676. pris[*span].dchannels[0] = 24 + offset;
  10677. } else if (si->totalchans == 3) {
  10678. /* BRI */
  10679. pris[*span].dchannels[0] = 3 + offset;
  10680. } else {
  10681. ast_log(LOG_WARNING, "Unable to use span %d, since the D-channel cannot be located (unexpected span size of %d channels)\n", *span, si->totalchans);
  10682. *span = -1;
  10683. return 0;
  10684. }
  10685. pris[*span].pri.span = *span + 1;
  10686. }
  10687. }
  10688. return 0;
  10689. }
  10690. #endif /* defined(HAVE_PRI) */
  10691. #if defined(HAVE_PRI)
  10692. static int pri_create_trunkgroup(int trunkgroup, int *channels)
  10693. {
  10694. struct dahdi_spaninfo si;
  10695. struct dahdi_params p;
  10696. int fd;
  10697. int span;
  10698. int ospan=0;
  10699. int x,y;
  10700. for (x = 0; x < NUM_SPANS; x++) {
  10701. if (pris[x].pri.trunkgroup == trunkgroup) {
  10702. ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
  10703. return -1;
  10704. }
  10705. }
  10706. for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
  10707. if (!channels[y])
  10708. break;
  10709. memset(&si, 0, sizeof(si));
  10710. memset(&p, 0, sizeof(p));
  10711. fd = open("/dev/dahdi/channel", O_RDWR);
  10712. if (fd < 0) {
  10713. ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
  10714. return -1;
  10715. }
  10716. x = channels[y];
  10717. if (ioctl(fd, DAHDI_SPECIFY, &x)) {
  10718. ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
  10719. close(fd);
  10720. return -1;
  10721. }
  10722. if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
  10723. ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
  10724. close(fd);
  10725. return -1;
  10726. }
  10727. if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
  10728. ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d): %s\n", channels[y], p.spanno, strerror(errno));
  10729. close(fd);
  10730. return -1;
  10731. }
  10732. span = p.spanno - 1;
  10733. if (pris[span].pri.trunkgroup) {
  10734. ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].pri.trunkgroup);
  10735. close(fd);
  10736. return -1;
  10737. }
  10738. if (pris[span].pri.pvts[0]) {
  10739. ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
  10740. close(fd);
  10741. return -1;
  10742. }
  10743. if (!y) {
  10744. pris[span].pri.trunkgroup = trunkgroup;
  10745. ospan = span;
  10746. }
  10747. pris[ospan].dchannels[y] = channels[y];
  10748. pris[span].pri.span = span + 1;
  10749. close(fd);
  10750. }
  10751. return 0;
  10752. }
  10753. #endif /* defined(HAVE_PRI) */
  10754. #if defined(HAVE_PRI)
  10755. static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
  10756. {
  10757. if (pris[span].mastertrunkgroup) {
  10758. ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
  10759. return -1;
  10760. }
  10761. pris[span].mastertrunkgroup = trunkgroup;
  10762. pris[span].prilogicalspan = logicalspan;
  10763. return 0;
  10764. }
  10765. #endif /* defined(HAVE_PRI) */
  10766. #if defined(HAVE_SS7)
  10767. static unsigned int parse_pointcode(const char *pcstring)
  10768. {
  10769. unsigned int code1, code2, code3;
  10770. int numvals;
  10771. numvals = sscanf(pcstring, "%30d-%30d-%30d", &code1, &code2, &code3);
  10772. if (numvals == 1)
  10773. return code1;
  10774. if (numvals == 3)
  10775. return (code1 << 16) | (code2 << 8) | code3;
  10776. return 0;
  10777. }
  10778. #endif /* defined(HAVE_SS7) */
  10779. #if defined(HAVE_SS7)
  10780. static struct dahdi_ss7 * ss7_resolve_linkset(int linkset)
  10781. {
  10782. if ((linkset < 0) || (linkset >= NUM_SPANS))
  10783. return NULL;
  10784. else
  10785. return &linksets[linkset - 1];
  10786. }
  10787. #endif /* defined(HAVE_SS7) */
  10788. #ifdef HAVE_OPENR2
  10789. static void dahdi_r2_destroy_links(void)
  10790. {
  10791. int i = 0;
  10792. if (!r2links) {
  10793. return;
  10794. }
  10795. for (; i < r2links_count; i++) {
  10796. if (r2links[i]->r2master != AST_PTHREADT_NULL) {
  10797. pthread_cancel(r2links[i]->r2master);
  10798. pthread_join(r2links[i]->r2master, NULL);
  10799. openr2_context_delete(r2links[i]->protocol_context);
  10800. }
  10801. ast_free(r2links[i]);
  10802. }
  10803. ast_free(r2links);
  10804. r2links = NULL;
  10805. r2links_count = 0;
  10806. }
  10807. /* This is an artificial convenient capacity, to keep at most a full E1 of channels in a single thread */
  10808. #define R2_LINK_CAPACITY 30
  10809. static struct dahdi_mfcr2 *dahdi_r2_get_link(const struct dahdi_chan_conf *conf)
  10810. {
  10811. struct dahdi_mfcr2 *new_r2link = NULL;
  10812. struct dahdi_mfcr2 **new_r2links = NULL;
  10813. /* Only create a new R2 link if
  10814. 1. This is the first link requested
  10815. 2. Configuration changed
  10816. 3. We got more channels than supported per link */
  10817. if (!r2links_count ||
  10818. memcmp(&conf->mfcr2, &r2links[r2links_count - 1]->conf, sizeof(conf->mfcr2)) ||
  10819. (r2links[r2links_count - 1]->numchans == R2_LINK_CAPACITY)) {
  10820. new_r2link = ast_calloc(1, sizeof(**r2links));
  10821. if (!new_r2link) {
  10822. ast_log(LOG_ERROR, "Cannot allocate R2 link!\n");
  10823. return NULL;
  10824. }
  10825. new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links)));
  10826. if (!new_r2links) {
  10827. ast_log(LOG_ERROR, "Cannot allocate R2 link!\n");
  10828. ast_free(new_r2link);
  10829. return NULL;
  10830. }
  10831. r2links = new_r2links;
  10832. new_r2link->r2master = AST_PTHREADT_NULL;
  10833. r2links[r2links_count] = new_r2link;
  10834. r2links_count++;
  10835. ast_debug(1, "Created new R2 link!\n");
  10836. }
  10837. return r2links[r2links_count - 1];
  10838. }
  10839. static int dahdi_r2_set_context(struct dahdi_mfcr2 *r2_link, const struct dahdi_chan_conf *conf)
  10840. {
  10841. char tmplogdir[] = "/tmp";
  10842. char logdir[OR2_MAX_PATH];
  10843. int threshold = 0;
  10844. int snres = 0;
  10845. r2_link->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface,
  10846. &dahdi_r2_transcode_iface, conf->mfcr2.variant, conf->mfcr2.max_ani,
  10847. conf->mfcr2.max_dnis);
  10848. if (!r2_link->protocol_context) {
  10849. return -1;
  10850. }
  10851. openr2_context_set_log_level(r2_link->protocol_context, conf->mfcr2.loglevel);
  10852. openr2_context_set_ani_first(r2_link->protocol_context, conf->mfcr2.get_ani_first);
  10853. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  10854. openr2_context_set_skip_category_request(r2_link->protocol_context, conf->mfcr2.skip_category_request);
  10855. #endif
  10856. openr2_context_set_mf_threshold(r2_link->protocol_context, threshold);
  10857. openr2_context_set_mf_back_timeout(r2_link->protocol_context, conf->mfcr2.mfback_timeout);
  10858. openr2_context_set_metering_pulse_timeout(r2_link->protocol_context, conf->mfcr2.metering_pulse_timeout);
  10859. openr2_context_set_double_answer(r2_link->protocol_context, conf->mfcr2.double_answer);
  10860. openr2_context_set_immediate_accept(r2_link->protocol_context, conf->mfcr2.immediate_accept);
  10861. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  10862. openr2_context_set_dtmf_dialing(r2_link->protocol_context, conf->mfcr2.dtmf_dialing, conf->mfcr2.dtmf_time_on, conf->mfcr2.dtmf_time_off);
  10863. openr2_context_set_dtmf_detection(r2_link->protocol_context, conf->mfcr2.dtmf_detection);
  10864. #endif
  10865. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
  10866. openr2_context_set_dtmf_detection_end_timeout(r2_link->protocol_context, conf->mfcr2.dtmf_end_timeout);
  10867. #endif
  10868. if (ast_strlen_zero(conf->mfcr2.logdir)) {
  10869. if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
  10870. ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
  10871. }
  10872. } else {
  10873. snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", conf->mfcr2.logdir);
  10874. if (snres >= sizeof(logdir)) {
  10875. ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir);
  10876. if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
  10877. ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
  10878. }
  10879. } else {
  10880. if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
  10881. ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir);
  10882. }
  10883. }
  10884. }
  10885. if (!ast_strlen_zero(conf->mfcr2.r2proto_file)) {
  10886. if (openr2_context_configure_from_advanced_file(r2_link->protocol_context, conf->mfcr2.r2proto_file)) {
  10887. ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file);
  10888. }
  10889. }
  10890. /* Save the configuration used to setup this link */
  10891. memcpy(&r2_link->conf, conf, sizeof(r2_link->conf));
  10892. return 0;
  10893. }
  10894. #endif
  10895. /* converts a DAHDI sigtype to signalling as can be configured from
  10896. * chan_dahdi.conf.
  10897. * While both have basically the same values, this will later be the
  10898. * place to add filters and sanity checks
  10899. */
  10900. static int sigtype_to_signalling(int sigtype)
  10901. {
  10902. return sigtype;
  10903. }
  10904. /*!
  10905. * \internal
  10906. * \brief Get file name and channel number from (subdir,number)
  10907. *
  10908. * \param subdir name of the subdirectory under /dev/dahdi/
  10909. * \param channel name of device file under /dev/dahdi/<subdir>/
  10910. * \param path buffer to put file name in
  10911. * \param pathlen maximal length of path
  10912. *
  10913. * \retval minor number of dahdi channel.
  10914. * \retval -errno on error.
  10915. */
  10916. static int device2chan(const char *subdir, int channel, char *path, int pathlen)
  10917. {
  10918. struct stat stbuf;
  10919. int num;
  10920. snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel);
  10921. if (stat(path, &stbuf) < 0) {
  10922. ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno));
  10923. return -errno;
  10924. }
  10925. if (!S_ISCHR(stbuf.st_mode)) {
  10926. ast_log(LOG_ERROR, "%s: Not a character device file\n", path);
  10927. return -EINVAL;
  10928. }
  10929. num = minor(stbuf.st_rdev);
  10930. ast_debug(1, "%s -> %d\n", path, num);
  10931. return num;
  10932. }
  10933. /*!
  10934. * \internal
  10935. * \brief Initialize/create a channel interface.
  10936. *
  10937. * \param channel Channel interface number to initialize/create.
  10938. * \param conf Configuration parameters to initialize interface with.
  10939. * \param reloading What we are doing now:
  10940. * 0 - initial module load,
  10941. * 1 - module reload,
  10942. * 2 - module restart
  10943. *
  10944. * \retval Interface-pointer initialized/created
  10945. * \retval NULL if error
  10946. */
  10947. static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
  10948. {
  10949. /* Make a dahdi_pvt structure for this interface */
  10950. struct dahdi_pvt *tmp;/*!< Current channel structure initializing */
  10951. char fn[80];
  10952. struct dahdi_bufferinfo bi;
  10953. int res;
  10954. #if defined(HAVE_PRI)
  10955. int span = 0;
  10956. #endif /* defined(HAVE_PRI) */
  10957. int here = 0;/*!< TRUE if the channel interface already exists. */
  10958. int x;
  10959. struct analog_pvt *analog_p = NULL;
  10960. struct dahdi_params p;
  10961. #if defined(HAVE_PRI)
  10962. struct dahdi_spaninfo si;
  10963. struct sig_pri_chan *pri_chan = NULL;
  10964. #endif /* defined(HAVE_PRI) */
  10965. #if defined(HAVE_SS7)
  10966. struct sig_ss7_chan *ss7_chan = NULL;
  10967. #endif /* defined(HAVE_SS7) */
  10968. /* Search channel interface list to see if it already exists. */
  10969. for (tmp = iflist; tmp; tmp = tmp->next) {
  10970. if (!tmp->destroy) {
  10971. if (tmp->channel == channel) {
  10972. /* The channel interface already exists. */
  10973. here = 1;
  10974. break;
  10975. }
  10976. if (tmp->channel > channel) {
  10977. /* No way it can be in the sorted list. */
  10978. tmp = NULL;
  10979. break;
  10980. }
  10981. }
  10982. }
  10983. if (!here && reloading != 1) {
  10984. tmp = ast_calloc(1, sizeof(*tmp));
  10985. if (!tmp) {
  10986. return NULL;
  10987. }
  10988. tmp->cc_params = ast_cc_config_params_init();
  10989. if (!tmp->cc_params) {
  10990. ast_free(tmp);
  10991. return NULL;
  10992. }
  10993. ast_mutex_init(&tmp->lock);
  10994. ifcount++;
  10995. for (x = 0; x < 3; x++)
  10996. tmp->subs[x].dfd = -1;
  10997. tmp->channel = channel;
  10998. tmp->priindication_oob = conf->chan.priindication_oob;
  10999. }
  11000. if (tmp) {
  11001. int chan_sig = conf->chan.sig;
  11002. /* If there are variables in tmp before it is updated to match the new config, clear them */
  11003. if (reloading && tmp->vars) {
  11004. ast_variables_destroy(tmp->vars);
  11005. tmp->vars = NULL;
  11006. }
  11007. if (!here) {
  11008. /* Can only get here if this is a new channel interface being created. */
  11009. if ((channel != CHAN_PSEUDO)) {
  11010. int count = 0;
  11011. snprintf(fn, sizeof(fn), "%d", channel);
  11012. /* Open non-blocking */
  11013. tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
  11014. while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
  11015. usleep(1);
  11016. tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
  11017. count++;
  11018. }
  11019. /* Allocate a DAHDI structure */
  11020. if (tmp->subs[SUB_REAL].dfd < 0) {
  11021. ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
  11022. destroy_dahdi_pvt(tmp);
  11023. return NULL;
  11024. }
  11025. memset(&p, 0, sizeof(p));
  11026. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
  11027. if (res < 0) {
  11028. ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno));
  11029. destroy_dahdi_pvt(tmp);
  11030. return NULL;
  11031. }
  11032. if (conf->is_sig_auto)
  11033. chan_sig = sigtype_to_signalling(p.sigtype);
  11034. if (p.sigtype != (chan_sig & 0x3ffff)) {
  11035. ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(chan_sig), sig2str(p.sigtype));
  11036. destroy_dahdi_pvt(tmp);
  11037. return NULL;
  11038. }
  11039. tmp->law_default = p.curlaw;
  11040. tmp->law = p.curlaw;
  11041. tmp->span = p.spanno;
  11042. #if defined(HAVE_PRI)
  11043. span = p.spanno - 1;
  11044. #endif /* defined(HAVE_PRI) */
  11045. } else {
  11046. chan_sig = 0;
  11047. }
  11048. tmp->sig = chan_sig;
  11049. tmp->outsigmod = conf->chan.outsigmod;
  11050. if (dahdi_analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) {
  11051. analog_p = analog_new(dahdisig_to_analogsig(chan_sig), tmp);
  11052. if (!analog_p) {
  11053. destroy_dahdi_pvt(tmp);
  11054. return NULL;
  11055. }
  11056. tmp->sig_pvt = analog_p;
  11057. }
  11058. #if defined(HAVE_SS7)
  11059. if (chan_sig == SIG_SS7) {
  11060. struct dahdi_ss7 *ss7;
  11061. int clear = 0;
  11062. if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) {
  11063. ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
  11064. destroy_dahdi_pvt(tmp);
  11065. return NULL;
  11066. }
  11067. ss7 = ss7_resolve_linkset(cur_linkset);
  11068. if (!ss7) {
  11069. ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset);
  11070. destroy_dahdi_pvt(tmp);
  11071. return NULL;
  11072. }
  11073. ss7->ss7.span = cur_linkset;
  11074. if (cur_cicbeginswith < 0) {
  11075. ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n");
  11076. destroy_dahdi_pvt(tmp);
  11077. return NULL;
  11078. }
  11079. ss7_chan = sig_ss7_chan_new(tmp, &ss7->ss7);
  11080. if (!ss7_chan) {
  11081. destroy_dahdi_pvt(tmp);
  11082. return NULL;
  11083. }
  11084. tmp->sig_pvt = ss7_chan;
  11085. tmp->ss7 = &ss7->ss7;
  11086. ss7_chan->channel = tmp->channel;
  11087. ss7_chan->cic = cur_cicbeginswith++;
  11088. /* DB: Add CIC's DPC information */
  11089. ss7_chan->dpc = cur_defaultdpc;
  11090. ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
  11091. ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix));
  11092. ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix));
  11093. ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix));
  11094. ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix));
  11095. ast_copy_string(ss7->ss7.networkroutedprefix, conf->ss7.ss7.networkroutedprefix, sizeof(ss7->ss7.networkroutedprefix));
  11096. ss7->ss7.called_nai = conf->ss7.ss7.called_nai;
  11097. ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai;
  11098. }
  11099. #endif /* defined(HAVE_SS7) */
  11100. #ifdef HAVE_OPENR2
  11101. if (chan_sig == SIG_MFCR2) {
  11102. struct dahdi_mfcr2 *r2_link;
  11103. r2_link = dahdi_r2_get_link(conf);
  11104. if (!r2_link) {
  11105. ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
  11106. destroy_dahdi_pvt(tmp);
  11107. return NULL;
  11108. }
  11109. if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) {
  11110. ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
  11111. destroy_dahdi_pvt(tmp);
  11112. return NULL;
  11113. }
  11114. if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) {
  11115. ast_log(LOG_ERROR, "Cannot add more channels to this link!\n");
  11116. destroy_dahdi_pvt(tmp);
  11117. return NULL;
  11118. }
  11119. r2_link->pvts[r2_link->numchans++] = tmp;
  11120. tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
  11121. tmp->subs[SUB_REAL].dfd,
  11122. NULL, NULL);
  11123. if (!tmp->r2chan) {
  11124. openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
  11125. ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
  11126. destroy_dahdi_pvt(tmp);
  11127. return NULL;
  11128. }
  11129. tmp->mfcr2 = r2_link;
  11130. if (conf->mfcr2.call_files) {
  11131. openr2_chan_enable_call_files(tmp->r2chan);
  11132. }
  11133. openr2_chan_set_client_data(tmp->r2chan, tmp);
  11134. /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
  11135. openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
  11136. openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel);
  11137. tmp->mfcr2_category = conf->mfcr2.category;
  11138. tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
  11139. tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
  11140. tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
  11141. tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer;
  11142. tmp->mfcr2call = 0;
  11143. tmp->mfcr2_dnis_index = 0;
  11144. tmp->mfcr2_ani_index = 0;
  11145. }
  11146. #endif
  11147. #ifdef HAVE_PRI
  11148. if (dahdi_sig_pri_lib_handles(chan_sig)) {
  11149. int offset;
  11150. int matchesdchan;
  11151. int x,y;
  11152. int myswitchtype = 0;
  11153. offset = 0;
  11154. if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) {
  11155. ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
  11156. destroy_dahdi_pvt(tmp);
  11157. return NULL;
  11158. }
  11159. if (span >= NUM_SPANS) {
  11160. ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
  11161. destroy_dahdi_pvt(tmp);
  11162. return NULL;
  11163. } else {
  11164. si.spanno = 0;
  11165. if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) {
  11166. ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
  11167. destroy_dahdi_pvt(tmp);
  11168. return NULL;
  11169. }
  11170. /* Store the logical span first based upon the real span */
  11171. tmp->logicalspan = pris[span].prilogicalspan;
  11172. pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
  11173. if (span < 0) {
  11174. ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
  11175. destroy_dahdi_pvt(tmp);
  11176. return NULL;
  11177. }
  11178. myswitchtype = conf->pri.pri.switchtype;
  11179. /* Make sure this isn't a d-channel */
  11180. matchesdchan=0;
  11181. for (x = 0; x < NUM_SPANS; x++) {
  11182. for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
  11183. if (pris[x].dchannels[y] == tmp->channel) {
  11184. matchesdchan = 1;
  11185. break;
  11186. }
  11187. }
  11188. }
  11189. if (!matchesdchan) {
  11190. if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) {
  11191. ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype));
  11192. destroy_dahdi_pvt(tmp);
  11193. return NULL;
  11194. }
  11195. if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) {
  11196. ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype));
  11197. destroy_dahdi_pvt(tmp);
  11198. return NULL;
  11199. }
  11200. if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) {
  11201. ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, pris[span].pri.dialplan == -1 ? "Dynamically set dialplan in ISDN" : pri_plan2str(pris[span].pri.dialplan));
  11202. destroy_dahdi_pvt(tmp);
  11203. return NULL;
  11204. }
  11205. if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) {
  11206. ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial);
  11207. destroy_dahdi_pvt(tmp);
  11208. return NULL;
  11209. }
  11210. if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) {
  11211. ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext);
  11212. destroy_dahdi_pvt(tmp);
  11213. return NULL;
  11214. }
  11215. if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) {
  11216. ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused);
  11217. destroy_dahdi_pvt(tmp);
  11218. return NULL;
  11219. }
  11220. if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) {
  11221. ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle);
  11222. destroy_dahdi_pvt(tmp);
  11223. return NULL;
  11224. }
  11225. if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) {
  11226. ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
  11227. pris[span].pri.trunkgroup);
  11228. destroy_dahdi_pvt(tmp);
  11229. return NULL;
  11230. }
  11231. pri_chan = sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
  11232. if (!pri_chan) {
  11233. destroy_dahdi_pvt(tmp);
  11234. return NULL;
  11235. }
  11236. tmp->sig_pvt = pri_chan;
  11237. tmp->pri = &pris[span].pri;
  11238. tmp->priexclusive = conf->chan.priexclusive;
  11239. if (!tmp->pri->cc_params) {
  11240. tmp->pri->cc_params = ast_cc_config_params_init();
  11241. if (!tmp->pri->cc_params) {
  11242. destroy_dahdi_pvt(tmp);
  11243. return NULL;
  11244. }
  11245. }
  11246. ast_cc_copy_config_params(tmp->pri->cc_params,
  11247. conf->chan.cc_params);
  11248. pris[span].pri.sig = chan_sig;
  11249. pris[span].pri.nodetype = conf->pri.pri.nodetype;
  11250. pris[span].pri.switchtype = myswitchtype;
  11251. pris[span].pri.nsf = conf->pri.pri.nsf;
  11252. pris[span].pri.dialplan = conf->pri.pri.dialplan;
  11253. pris[span].pri.localdialplan = conf->pri.pri.localdialplan;
  11254. pris[span].pri.cpndialplan = conf->pri.pri.cpndialplan;
  11255. pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt;
  11256. pris[span].pri.minunused = conf->pri.pri.minunused;
  11257. pris[span].pri.minidle = conf->pri.pri.minidle;
  11258. pris[span].pri.overlapdial = conf->pri.pri.overlapdial;
  11259. pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping;
  11260. pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval;
  11261. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  11262. pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support;
  11263. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  11264. #ifdef HAVE_PRI_INBANDDISCONNECT
  11265. pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect;
  11266. #endif
  11267. #if defined(HAVE_PRI_CALL_HOLD)
  11268. pris[span].pri.hold_disconnect_transfer =
  11269. conf->pri.pri.hold_disconnect_transfer;
  11270. #endif /* defined(HAVE_PRI_CALL_HOLD) */
  11271. #if defined(HAVE_PRI_CCSS)
  11272. pris[span].pri.cc_ptmp_recall_mode =
  11273. conf->pri.pri.cc_ptmp_recall_mode;
  11274. pris[span].pri.cc_qsig_signaling_link_req =
  11275. conf->pri.pri.cc_qsig_signaling_link_req;
  11276. pris[span].pri.cc_qsig_signaling_link_rsp =
  11277. conf->pri.pri.cc_qsig_signaling_link_rsp;
  11278. #endif /* defined(HAVE_PRI_CCSS) */
  11279. #if defined(HAVE_PRI_CALL_WAITING)
  11280. pris[span].pri.max_call_waiting_calls =
  11281. conf->pri.pri.max_call_waiting_calls;
  11282. pris[span].pri.allow_call_waiting_calls =
  11283. conf->pri.pri.allow_call_waiting_calls;
  11284. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  11285. pris[span].pri.transfer = conf->chan.transfer;
  11286. pris[span].pri.facilityenable = conf->pri.pri.facilityenable;
  11287. #if defined(HAVE_PRI_L2_PERSISTENCE)
  11288. pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence;
  11289. #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
  11290. pris[span].pri.colp_send = conf->pri.pri.colp_send;
  11291. #if defined(HAVE_PRI_AOC_EVENTS)
  11292. pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag;
  11293. pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
  11294. #endif /* defined(HAVE_PRI_AOC_EVENTS) */
  11295. if (chan_sig == SIG_BRI_PTMP) {
  11296. pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored;
  11297. } else {
  11298. /* Option does not apply to this line type. */
  11299. pris[span].pri.layer1_ignored = 0;
  11300. }
  11301. pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag;
  11302. pris[span].pri.inband_on_setup_ack = conf->pri.pri.inband_on_setup_ack;
  11303. pris[span].pri.inband_on_proceeding = conf->pri.pri.inband_on_proceeding;
  11304. ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag));
  11305. ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
  11306. #if defined(HAVE_PRI_MWI)
  11307. ast_copy_string(pris[span].pri.mwi_mailboxes,
  11308. conf->pri.pri.mwi_mailboxes,
  11309. sizeof(pris[span].pri.mwi_mailboxes));
  11310. ast_copy_string(pris[span].pri.mwi_vm_boxes,
  11311. conf->pri.pri.mwi_vm_boxes,
  11312. sizeof(pris[span].pri.mwi_vm_boxes));
  11313. ast_copy_string(pris[span].pri.mwi_vm_numbers,
  11314. conf->pri.pri.mwi_vm_numbers,
  11315. sizeof(pris[span].pri.mwi_vm_numbers));
  11316. #endif /* defined(HAVE_PRI_MWI) */
  11317. ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial));
  11318. ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext));
  11319. ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix));
  11320. ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix));
  11321. ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix));
  11322. ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix));
  11323. ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix));
  11324. pris[span].pri.moh_signaling = conf->pri.pri.moh_signaling;
  11325. pris[span].pri.resetinterval = conf->pri.pri.resetinterval;
  11326. #if defined(HAVE_PRI_DISPLAY_TEXT)
  11327. pris[span].pri.display_flags_send = conf->pri.pri.display_flags_send;
  11328. pris[span].pri.display_flags_receive = conf->pri.pri.display_flags_receive;
  11329. #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
  11330. #if defined(HAVE_PRI_MCID)
  11331. pris[span].pri.mcid_send = conf->pri.pri.mcid_send;
  11332. #endif /* defined(HAVE_PRI_MCID) */
  11333. #if defined(HAVE_PRI_DATETIME_SEND)
  11334. pris[span].pri.datetime_send = conf->pri.pri.datetime_send;
  11335. #endif /* defined(HAVE_PRI_DATETIME_SEND) */
  11336. for (x = 0; x < PRI_MAX_TIMERS; x++) {
  11337. pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x];
  11338. }
  11339. #if defined(HAVE_PRI_CALL_WAITING)
  11340. /* Channel initial config parameters. */
  11341. pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd;
  11342. pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid;
  11343. pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname;
  11344. pris[span].pri.ch_cfg.immediate = conf->chan.immediate;
  11345. pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive;
  11346. pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob;
  11347. pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid;
  11348. pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres;
  11349. ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context));
  11350. ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret));
  11351. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  11352. } else {
  11353. ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos);
  11354. destroy_dahdi_pvt(tmp);
  11355. return NULL;
  11356. }
  11357. }
  11358. }
  11359. #endif
  11360. } else {
  11361. /* already exists in interface list */
  11362. ast_log(LOG_WARNING, "Attempt to configure channel %d with signaling %s ignored because it is already configured to be %s.\n", tmp->channel, dahdi_sig2str(chan_sig), dahdi_sig2str(tmp->sig));
  11363. chan_sig = tmp->sig;
  11364. if (tmp->subs[SUB_REAL].dfd > -1) {
  11365. memset(&p, 0, sizeof(p));
  11366. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
  11367. }
  11368. }
  11369. /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
  11370. switch (chan_sig) {
  11371. case SIG_FXSKS:
  11372. case SIG_FXSLS:
  11373. case SIG_EM:
  11374. case SIG_EM_E1:
  11375. case SIG_EMWINK:
  11376. case SIG_FEATD:
  11377. case SIG_FEATDMF:
  11378. case SIG_FEATDMF_TA:
  11379. case SIG_FEATB:
  11380. case SIG_E911:
  11381. case SIG_SF:
  11382. case SIG_SFWINK:
  11383. case SIG_FGC_CAMA:
  11384. case SIG_FGC_CAMAMF:
  11385. case SIG_SF_FEATD:
  11386. case SIG_SF_FEATDMF:
  11387. case SIG_SF_FEATB:
  11388. p.starttime = 250;
  11389. break;
  11390. }
  11391. if (tmp->radio) {
  11392. /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
  11393. p.channo = channel;
  11394. p.rxwinktime = 1;
  11395. p.rxflashtime = 1;
  11396. p.starttime = 1;
  11397. p.debouncetime = 5;
  11398. } else {
  11399. p.channo = channel;
  11400. /* Override timing settings based on config file */
  11401. if (conf->timing.prewinktime >= 0)
  11402. p.prewinktime = conf->timing.prewinktime;
  11403. if (conf->timing.preflashtime >= 0)
  11404. p.preflashtime = conf->timing.preflashtime;
  11405. if (conf->timing.winktime >= 0)
  11406. p.winktime = conf->timing.winktime;
  11407. if (conf->timing.flashtime >= 0)
  11408. p.flashtime = conf->timing.flashtime;
  11409. if (conf->timing.starttime >= 0)
  11410. p.starttime = conf->timing.starttime;
  11411. if (conf->timing.rxwinktime >= 0)
  11412. p.rxwinktime = conf->timing.rxwinktime;
  11413. if (conf->timing.rxflashtime >= 0)
  11414. p.rxflashtime = conf->timing.rxflashtime;
  11415. if (conf->timing.debouncetime >= 0)
  11416. p.debouncetime = conf->timing.debouncetime;
  11417. }
  11418. /* don't set parms on a pseudo-channel */
  11419. if (tmp->subs[SUB_REAL].dfd >= 0)
  11420. {
  11421. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p);
  11422. if (res < 0) {
  11423. ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno));
  11424. destroy_dahdi_pvt(tmp);
  11425. return NULL;
  11426. }
  11427. }
  11428. #if 1
  11429. if (!here && (tmp->subs[SUB_REAL].dfd > -1)) {
  11430. memset(&bi, 0, sizeof(bi));
  11431. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
  11432. if (!res) {
  11433. bi.txbufpolicy = conf->chan.buf_policy;
  11434. bi.rxbufpolicy = conf->chan.buf_policy;
  11435. bi.numbufs = conf->chan.buf_no;
  11436. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
  11437. if (res < 0) {
  11438. ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno));
  11439. }
  11440. } else {
  11441. ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno));
  11442. }
  11443. tmp->buf_policy = conf->chan.buf_policy;
  11444. tmp->buf_no = conf->chan.buf_no;
  11445. tmp->usefaxbuffers = conf->chan.usefaxbuffers;
  11446. tmp->faxbuf_policy = conf->chan.faxbuf_policy;
  11447. tmp->faxbuf_no = conf->chan.faxbuf_no;
  11448. /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting
  11449. * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail.
  11450. * The reason the ioctl call above failed should to be determined before worrying about the
  11451. * faxbuffer-related ioctl calls */
  11452. tmp->bufsize = bi.bufsize;
  11453. }
  11454. #endif
  11455. tmp->immediate = conf->chan.immediate;
  11456. tmp->transfertobusy = conf->chan.transfertobusy;
  11457. if (chan_sig & __DAHDI_SIG_FXS) {
  11458. tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
  11459. tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
  11460. tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas;
  11461. }
  11462. tmp->ringt_base = ringt_base;
  11463. tmp->firstradio = 0;
  11464. if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
  11465. tmp->permcallwaiting = conf->chan.callwaiting;
  11466. else
  11467. tmp->permcallwaiting = 0;
  11468. /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
  11469. tmp->destroy = 0;
  11470. tmp->drings = conf->chan.drings;
  11471. /* 10 is a nice default. */
  11472. if (tmp->drings.ringnum[0].range == 0)
  11473. tmp->drings.ringnum[0].range = 10;
  11474. if (tmp->drings.ringnum[1].range == 0)
  11475. tmp->drings.ringnum[1].range = 10;
  11476. if (tmp->drings.ringnum[2].range == 0)
  11477. tmp->drings.ringnum[2].range = 10;
  11478. tmp->usedistinctiveringdetection = usedistinctiveringdetection;
  11479. tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
  11480. tmp->threewaycalling = conf->chan.threewaycalling;
  11481. tmp->adsi = conf->chan.adsi;
  11482. tmp->use_smdi = conf->chan.use_smdi;
  11483. tmp->permhidecallerid = conf->chan.hidecallerid;
  11484. tmp->hidecalleridname = conf->chan.hidecalleridname;
  11485. tmp->callreturn = conf->chan.callreturn;
  11486. tmp->echocancel = conf->chan.echocancel;
  11487. tmp->echotraining = conf->chan.echotraining;
  11488. tmp->pulse = conf->chan.pulse;
  11489. if (tmp->echocancel.head.tap_length) {
  11490. tmp->echocanbridged = conf->chan.echocanbridged;
  11491. } else {
  11492. if (conf->chan.echocanbridged)
  11493. ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
  11494. tmp->echocanbridged = 0;
  11495. }
  11496. tmp->busydetect = conf->chan.busydetect;
  11497. tmp->busycount = conf->chan.busycount;
  11498. tmp->busy_cadence = conf->chan.busy_cadence;
  11499. tmp->callprogress = conf->chan.callprogress;
  11500. tmp->waitfordialtone = conf->chan.waitfordialtone;
  11501. tmp->dialtone_detect = conf->chan.dialtone_detect;
  11502. tmp->cancallforward = conf->chan.cancallforward;
  11503. tmp->dtmfrelax = conf->chan.dtmfrelax;
  11504. tmp->callwaiting = tmp->permcallwaiting;
  11505. tmp->hidecallerid = tmp->permhidecallerid;
  11506. tmp->channel = channel;
  11507. tmp->stripmsd = conf->chan.stripmsd;
  11508. tmp->use_callerid = conf->chan.use_callerid;
  11509. tmp->cid_signalling = conf->chan.cid_signalling;
  11510. tmp->cid_start = conf->chan.cid_start;
  11511. tmp->dahditrcallerid = conf->chan.dahditrcallerid;
  11512. tmp->restrictcid = conf->chan.restrictcid;
  11513. tmp->use_callingpres = conf->chan.use_callingpres;
  11514. if (tmp->usedistinctiveringdetection) {
  11515. if (!tmp->use_callerid) {
  11516. ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
  11517. tmp->use_callerid = 1;
  11518. }
  11519. }
  11520. if (tmp->cid_signalling == CID_SIG_SMDI) {
  11521. if (!tmp->use_smdi) {
  11522. ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
  11523. tmp->use_smdi = 1;
  11524. }
  11525. }
  11526. if (tmp->use_smdi) {
  11527. tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
  11528. if (!(tmp->smdi_iface)) {
  11529. ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
  11530. tmp->use_smdi = 0;
  11531. }
  11532. }
  11533. ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
  11534. tmp->amaflags = conf->chan.amaflags;
  11535. if (!here) {
  11536. tmp->confno = -1;
  11537. tmp->propconfno = -1;
  11538. }
  11539. tmp->canpark = conf->chan.canpark;
  11540. tmp->transfer = conf->chan.transfer;
  11541. ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
  11542. ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
  11543. ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
  11544. ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
  11545. ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
  11546. ast_copy_string(tmp->description, conf->chan.description, sizeof(tmp->description));
  11547. ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot));
  11548. tmp->cid_ton = 0;
  11549. if (dahdi_analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) {
  11550. ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
  11551. ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
  11552. } else {
  11553. tmp->cid_num[0] = '\0';
  11554. tmp->cid_name[0] = '\0';
  11555. }
  11556. #if defined(HAVE_PRI)
  11557. if (dahdi_sig_pri_lib_handles(tmp->sig)) {
  11558. tmp->cid_tag[0] = '\0';
  11559. } else
  11560. #endif /* defined(HAVE_PRI) */
  11561. {
  11562. ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag));
  11563. }
  11564. tmp->cid_subaddr[0] = '\0';
  11565. ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
  11566. if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) {
  11567. struct stasis_topic *mailbox_specific_topic;
  11568. mailbox_specific_topic = ast_mwi_topic(tmp->mailbox);
  11569. if (mailbox_specific_topic) {
  11570. tmp->mwi_event_sub = stasis_subscribe(mailbox_specific_topic, mwi_event_cb, NULL);
  11571. }
  11572. }
  11573. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  11574. tmp->mwisend_setting = conf->chan.mwisend_setting;
  11575. tmp->mwisend_fsk = conf->chan.mwisend_fsk;
  11576. tmp->mwisend_rpas = conf->chan.mwisend_rpas;
  11577. #endif
  11578. tmp->group = conf->chan.group;
  11579. tmp->callgroup = conf->chan.callgroup;
  11580. tmp->pickupgroup= conf->chan.pickupgroup;
  11581. ast_unref_namedgroups(tmp->named_callgroups);
  11582. tmp->named_callgroups = ast_ref_namedgroups(conf->chan.named_callgroups);
  11583. ast_unref_namedgroups(tmp->named_pickupgroups);
  11584. tmp->named_pickupgroups = ast_ref_namedgroups(conf->chan.named_pickupgroups);
  11585. if (conf->chan.vars) {
  11586. struct ast_variable *v, *tmpvar;
  11587. for (v = conf->chan.vars ; v ; v = v->next) {
  11588. if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
  11589. tmpvar->next = tmp->vars;
  11590. tmp->vars = tmpvar;
  11591. }
  11592. }
  11593. }
  11594. tmp->hwrxgain_enabled = conf->chan.hwrxgain_enabled;
  11595. tmp->hwtxgain_enabled = conf->chan.hwtxgain_enabled;
  11596. tmp->hwrxgain = conf->chan.hwrxgain;
  11597. tmp->hwtxgain = conf->chan.hwtxgain;
  11598. tmp->cid_rxgain = conf->chan.cid_rxgain;
  11599. tmp->rxgain = conf->chan.rxgain;
  11600. tmp->txgain = conf->chan.txgain;
  11601. tmp->txdrc = conf->chan.txdrc;
  11602. tmp->rxdrc = conf->chan.rxdrc;
  11603. tmp->tonezone = conf->chan.tonezone;
  11604. if (tmp->subs[SUB_REAL].dfd > -1) {
  11605. if (tmp->hwrxgain_enabled) {
  11606. tmp->hwrxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwrxgain, 0);
  11607. }
  11608. if (tmp->hwtxgain_enabled) {
  11609. tmp->hwtxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwtxgain, 1);
  11610. }
  11611. set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law);
  11612. if (tmp->dsp)
  11613. ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
  11614. dahdi_conf_update(tmp);
  11615. if (!here) {
  11616. switch (chan_sig) {
  11617. case SIG_PRI_LIB_HANDLE_CASES:
  11618. case SIG_SS7:
  11619. case SIG_MFCR2:
  11620. break;
  11621. default:
  11622. /* Hang it up to be sure it's good */
  11623. dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
  11624. break;
  11625. }
  11626. }
  11627. ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone);
  11628. if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) {
  11629. /* the dchannel is down so put the channel in alarm */
  11630. switch (tmp->sig) {
  11631. #ifdef HAVE_PRI
  11632. case SIG_PRI_LIB_HANDLE_CASES:
  11633. sig_pri_set_alarm(tmp->sig_pvt, 1);
  11634. break;
  11635. #endif
  11636. #if defined(HAVE_SS7)
  11637. case SIG_SS7:
  11638. sig_ss7_set_alarm(tmp->sig_pvt, 1);
  11639. break;
  11640. #endif /* defined(HAVE_SS7) */
  11641. default:
  11642. /* The only sig submodule left should be sig_analog. */
  11643. analog_p = tmp->sig_pvt;
  11644. if (analog_p) {
  11645. analog_p->inalarm = 1;
  11646. }
  11647. tmp->inalarm = 1;
  11648. break;
  11649. }
  11650. handle_alarms(tmp, res);
  11651. }
  11652. }
  11653. tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
  11654. tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
  11655. tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
  11656. tmp->sendcalleridafter = conf->chan.sendcalleridafter;
  11657. ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params);
  11658. if (!here) {
  11659. tmp->locallyblocked = 0;
  11660. tmp->remotelyblocked = 0;
  11661. switch (tmp->sig) {
  11662. #if defined(HAVE_PRI)
  11663. case SIG_PRI_LIB_HANDLE_CASES:
  11664. tmp->inservice = 1;/* Inservice until actually implemented. */
  11665. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  11666. ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0;
  11667. if (chan_sig == SIG_PRI) {
  11668. char db_chan_name[20];
  11669. char db_answer[5];
  11670. /*
  11671. * Initialize the active out-of-service status
  11672. * and delete any record if the feature is not enabled.
  11673. */
  11674. snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel);
  11675. if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
  11676. unsigned *why;
  11677. why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status;
  11678. if (tmp->pri->enable_service_message_support) {
  11679. char state;
  11680. sscanf(db_answer, "%1c:%30u", &state, why);
  11681. /* Ensure that only the implemented bits could be set.*/
  11682. *why &= (SRVST_NEAREND | SRVST_FAREND);
  11683. }
  11684. if (!*why) {
  11685. ast_db_del(db_chan_name, SRVST_DBKEY);
  11686. }
  11687. }
  11688. }
  11689. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  11690. break;
  11691. #endif /* defined(HAVE_PRI) */
  11692. #if defined(HAVE_SS7)
  11693. case SIG_SS7:
  11694. tmp->inservice = 0;
  11695. if (tmp->ss7->flags & LINKSET_FLAG_INITIALHWBLO) {
  11696. tmp->remotelyblocked |= SS7_BLOCKED_HARDWARE;
  11697. }
  11698. break;
  11699. #endif /* defined(HAVE_SS7) */
  11700. default:
  11701. /* We default to in service on protocols that don't have a reset */
  11702. tmp->inservice = 1;
  11703. break;
  11704. }
  11705. }
  11706. switch (tmp->sig) {
  11707. #if defined(HAVE_PRI)
  11708. case SIG_PRI_LIB_HANDLE_CASES:
  11709. if (pri_chan) {
  11710. pri_chan->channel = tmp->channel;
  11711. pri_chan->hidecallerid = tmp->hidecallerid;
  11712. pri_chan->hidecalleridname = tmp->hidecalleridname;
  11713. pri_chan->immediate = tmp->immediate;
  11714. pri_chan->inalarm = tmp->inalarm;
  11715. pri_chan->priexclusive = tmp->priexclusive;
  11716. pri_chan->priindication_oob = tmp->priindication_oob;
  11717. pri_chan->use_callerid = tmp->use_callerid;
  11718. pri_chan->use_callingpres = tmp->use_callingpres;
  11719. ast_copy_string(pri_chan->context, tmp->context,
  11720. sizeof(pri_chan->context));
  11721. ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret,
  11722. sizeof(pri_chan->mohinterpret));
  11723. pri_chan->stripmsd = tmp->stripmsd;
  11724. }
  11725. break;
  11726. #endif /* defined(HAVE_PRI) */
  11727. #if defined(HAVE_SS7)
  11728. case SIG_SS7:
  11729. if (ss7_chan) {
  11730. ss7_chan->inalarm = tmp->inalarm;
  11731. ss7_chan->inservice = tmp->inservice;
  11732. ss7_chan->stripmsd = tmp->stripmsd;
  11733. ss7_chan->hidecallerid = tmp->hidecallerid;
  11734. ss7_chan->use_callerid = tmp->use_callerid;
  11735. ss7_chan->use_callingpres = tmp->use_callingpres;
  11736. ss7_chan->immediate = tmp->immediate;
  11737. ss7_chan->locallyblocked = tmp->locallyblocked;
  11738. ss7_chan->remotelyblocked = tmp->remotelyblocked;
  11739. ast_copy_string(ss7_chan->context, tmp->context,
  11740. sizeof(ss7_chan->context));
  11741. ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret,
  11742. sizeof(ss7_chan->mohinterpret));
  11743. }
  11744. break;
  11745. #endif /* defined(HAVE_SS7) */
  11746. default:
  11747. /* The only sig submodule left should be sig_analog. */
  11748. analog_p = tmp->sig_pvt;
  11749. if (analog_p) {
  11750. analog_p->channel = tmp->channel;
  11751. analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
  11752. analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
  11753. analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
  11754. analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */
  11755. analog_p->callreturn = conf->chan.callreturn;
  11756. analog_p->cancallforward = conf->chan.cancallforward;
  11757. analog_p->canpark = conf->chan.canpark;
  11758. analog_p->dahditrcallerid = conf->chan.dahditrcallerid;
  11759. analog_p->immediate = conf->chan.immediate;
  11760. analog_p->permhidecallerid = conf->chan.permhidecallerid;
  11761. analog_p->pulse = conf->chan.pulse;
  11762. analog_p->threewaycalling = conf->chan.threewaycalling;
  11763. analog_p->transfer = conf->chan.transfer;
  11764. analog_p->transfertobusy = conf->chan.transfertobusy;
  11765. analog_p->use_callerid = tmp->use_callerid;
  11766. analog_p->use_smdi = tmp->use_smdi;
  11767. analog_p->smdi_iface = tmp->smdi_iface;
  11768. analog_p->outsigmod = ANALOG_SIG_NONE;
  11769. analog_p->echotraining = conf->chan.echotraining;
  11770. analog_p->cid_signalling = conf->chan.cid_signalling;
  11771. analog_p->stripmsd = conf->chan.stripmsd;
  11772. switch (conf->chan.cid_start) {
  11773. case CID_START_POLARITY:
  11774. analog_p->cid_start = ANALOG_CID_START_POLARITY;
  11775. break;
  11776. case CID_START_POLARITY_IN:
  11777. analog_p->cid_start = ANALOG_CID_START_POLARITY_IN;
  11778. break;
  11779. case CID_START_DTMF_NOALERT:
  11780. analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT;
  11781. break;
  11782. default:
  11783. analog_p->cid_start = ANALOG_CID_START_RING;
  11784. break;
  11785. }
  11786. analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid;
  11787. analog_p->ringt = conf->chan.ringt;
  11788. analog_p->ringt_base = ringt_base;
  11789. analog_p->onhooktime = time(NULL);
  11790. if (chan_sig & __DAHDI_SIG_FXO) {
  11791. memset(&p, 0, sizeof(p));
  11792. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
  11793. if (!res) {
  11794. analog_p->fxsoffhookstate = p.rxisoffhook;
  11795. }
  11796. #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
  11797. res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
  11798. #endif
  11799. }
  11800. analog_p->msgstate = -1;
  11801. ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest));
  11802. ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num));
  11803. ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name));
  11804. analog_config_complete(analog_p);
  11805. }
  11806. break;
  11807. }
  11808. #if defined(HAVE_PRI)
  11809. if (tmp->channel == CHAN_PSEUDO) {
  11810. /*
  11811. * Save off pseudo channel buffer policy values for dynamic creation of
  11812. * no B channel interfaces.
  11813. */
  11814. dahdi_pseudo_parms.buf_no = tmp->buf_no;
  11815. dahdi_pseudo_parms.buf_policy = tmp->buf_policy;
  11816. dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no;
  11817. dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy;
  11818. }
  11819. #endif /* defined(HAVE_PRI) */
  11820. }
  11821. if (tmp && !here) {
  11822. /* Add the new channel interface to the sorted channel interface list. */
  11823. dahdi_iflist_insert(tmp);
  11824. }
  11825. return tmp;
  11826. }
  11827. static int is_group_or_channel_match(struct dahdi_pvt *p, int span, ast_group_t groupmatch, int *groupmatched, int channelmatch, int *channelmatched)
  11828. {
  11829. #if defined(HAVE_PRI)
  11830. if (0 < span) {
  11831. /* The channel must be on the specified PRI span. */
  11832. if (!p->pri || p->pri->span != span) {
  11833. return 0;
  11834. }
  11835. if (!groupmatch && channelmatch == -1) {
  11836. /* Match any group since it only needs to be on the PRI span. */
  11837. *groupmatched = 1;
  11838. return 1;
  11839. }
  11840. }
  11841. #endif /* defined(HAVE_PRI) */
  11842. /* check group matching */
  11843. if (groupmatch) {
  11844. if ((p->group & groupmatch) != groupmatch)
  11845. /* Doesn't match the specified group, try the next one */
  11846. return 0;
  11847. *groupmatched = 1;
  11848. }
  11849. /* Check to see if we have a channel match */
  11850. if (channelmatch != -1) {
  11851. if (p->channel != channelmatch)
  11852. /* Doesn't match the specified channel, try the next one */
  11853. return 0;
  11854. *channelmatched = 1;
  11855. }
  11856. return 1;
  11857. }
  11858. static int available(struct dahdi_pvt **pvt, int is_specific_channel)
  11859. {
  11860. struct dahdi_pvt *p = *pvt;
  11861. if (p->inalarm)
  11862. return 0;
  11863. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode))
  11864. return analog_available(p->sig_pvt);
  11865. switch (p->sig) {
  11866. #if defined(HAVE_PRI)
  11867. case SIG_PRI_LIB_HANDLE_CASES:
  11868. {
  11869. struct sig_pri_chan *pvt_chan;
  11870. int res;
  11871. pvt_chan = p->sig_pvt;
  11872. res = sig_pri_available(&pvt_chan, is_specific_channel);
  11873. *pvt = pvt_chan->chan_pvt;
  11874. return res;
  11875. }
  11876. #endif /* defined(HAVE_PRI) */
  11877. #if defined(HAVE_SS7)
  11878. case SIG_SS7:
  11879. return sig_ss7_available(p->sig_pvt);
  11880. #endif /* defined(HAVE_SS7) */
  11881. default:
  11882. break;
  11883. }
  11884. if (p->locallyblocked || p->remotelyblocked) {
  11885. return 0;
  11886. }
  11887. /* If no owner definitely available */
  11888. if (!p->owner) {
  11889. #ifdef HAVE_OPENR2
  11890. /* Trust MFC/R2 */
  11891. if (p->mfcr2) {
  11892. if (p->mfcr2call) {
  11893. return 0;
  11894. } else {
  11895. return 1;
  11896. }
  11897. }
  11898. #endif
  11899. return 1;
  11900. }
  11901. return 0;
  11902. }
  11903. #if defined(HAVE_PRI)
  11904. #if defined(HAVE_PRI_CALL_WAITING)
  11905. /*!
  11906. * \internal
  11907. * \brief Init the private channel configuration using the span controller.
  11908. * \since 1.8
  11909. *
  11910. * \param priv Channel to init the configuration.
  11911. * \param pri sig_pri PRI control structure.
  11912. *
  11913. * \note Assumes the pri->lock is already obtained.
  11914. *
  11915. * \return Nothing
  11916. */
  11917. static void my_pri_init_config(void *priv, struct sig_pri_span *pri)
  11918. {
  11919. struct dahdi_pvt *pvt = priv;
  11920. pvt->stripmsd = pri->ch_cfg.stripmsd;
  11921. pvt->hidecallerid = pri->ch_cfg.hidecallerid;
  11922. pvt->hidecalleridname = pri->ch_cfg.hidecalleridname;
  11923. pvt->immediate = pri->ch_cfg.immediate;
  11924. pvt->priexclusive = pri->ch_cfg.priexclusive;
  11925. pvt->priindication_oob = pri->ch_cfg.priindication_oob;
  11926. pvt->use_callerid = pri->ch_cfg.use_callerid;
  11927. pvt->use_callingpres = pri->ch_cfg.use_callingpres;
  11928. ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
  11929. ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
  11930. }
  11931. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  11932. #endif /* defined(HAVE_PRI) */
  11933. #if defined(HAVE_PRI)
  11934. /*!
  11935. * \internal
  11936. * \brief Create a no B channel interface.
  11937. * \since 1.8
  11938. *
  11939. * \param pri sig_pri span controller to add interface.
  11940. *
  11941. * \note Assumes the pri->lock is already obtained.
  11942. *
  11943. * \retval array-index into private pointer array on success.
  11944. * \retval -1 on error.
  11945. */
  11946. static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri)
  11947. {
  11948. int pvt_idx;
  11949. int res;
  11950. unsigned idx;
  11951. struct dahdi_pvt *pvt;
  11952. struct sig_pri_chan *chan;
  11953. struct dahdi_bufferinfo bi;
  11954. static int nobch_channel = CHAN_PSEUDO;
  11955. /* Find spot in the private pointer array for new interface. */
  11956. for (pvt_idx = 0; pvt_idx < pri->numchans; ++pvt_idx) {
  11957. if (!pri->pvts[pvt_idx]) {
  11958. break;
  11959. }
  11960. }
  11961. if (pri->numchans == pvt_idx) {
  11962. if (ARRAY_LEN(pri->pvts) <= pvt_idx) {
  11963. ast_log(LOG_ERROR, "Unable to add a no-B-channel interface!\n");
  11964. return -1;
  11965. }
  11966. /* Add new spot to the private pointer array. */
  11967. pri->pvts[pvt_idx] = NULL;
  11968. ++pri->numchans;
  11969. }
  11970. pvt = ast_calloc(1, sizeof(*pvt));
  11971. if (!pvt) {
  11972. return -1;
  11973. }
  11974. pvt->cc_params = ast_cc_config_params_init();
  11975. if (!pvt->cc_params) {
  11976. ast_free(pvt);
  11977. return -1;
  11978. }
  11979. ast_mutex_init(&pvt->lock);
  11980. for (idx = 0; idx < ARRAY_LEN(pvt->subs); ++idx) {
  11981. pvt->subs[idx].dfd = -1;
  11982. }
  11983. pvt->buf_no = dahdi_pseudo_parms.buf_no;
  11984. pvt->buf_policy = dahdi_pseudo_parms.buf_policy;
  11985. pvt->faxbuf_no = dahdi_pseudo_parms.faxbuf_no;
  11986. pvt->faxbuf_policy = dahdi_pseudo_parms.faxbuf_policy;
  11987. chan = sig_pri_chan_new(pvt, pri, 0, 0, 0);
  11988. if (!chan) {
  11989. destroy_dahdi_pvt(pvt);
  11990. return -1;
  11991. }
  11992. chan->no_b_channel = 1;
  11993. /*
  11994. * Pseudo channel companding law.
  11995. * Needed for outgoing call waiting calls.
  11996. * XXX May need to make this determined by switchtype or user option.
  11997. */
  11998. pvt->law_default = DAHDI_LAW_ALAW;
  11999. pvt->sig = pri->sig;
  12000. pvt->outsigmod = -1;
  12001. pvt->pri = pri;
  12002. pvt->sig_pvt = chan;
  12003. pri->pvts[pvt_idx] = chan;
  12004. pvt->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
  12005. if (pvt->subs[SUB_REAL].dfd < 0) {
  12006. ast_log(LOG_ERROR, "Unable to open no B channel interface pseudo channel: %s\n",
  12007. strerror(errno));
  12008. destroy_dahdi_pvt(pvt);
  12009. return -1;
  12010. }
  12011. memset(&bi, 0, sizeof(bi));
  12012. res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
  12013. if (!res) {
  12014. pvt->bufsize = bi.bufsize;
  12015. bi.txbufpolicy = pvt->buf_policy;
  12016. bi.rxbufpolicy = pvt->buf_policy;
  12017. bi.numbufs = pvt->buf_no;
  12018. res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
  12019. if (res < 0) {
  12020. ast_log(LOG_WARNING,
  12021. "Unable to set buffer policy on no B channel interface: %s\n",
  12022. strerror(errno));
  12023. }
  12024. } else
  12025. ast_log(LOG_WARNING,
  12026. "Unable to check buffer policy on no B channel interface: %s\n",
  12027. strerror(errno));
  12028. --nobch_channel;
  12029. if (CHAN_PSEUDO < nobch_channel) {
  12030. nobch_channel = CHAN_PSEUDO - 1;
  12031. }
  12032. pvt->channel = nobch_channel;
  12033. pvt->span = pri->span;
  12034. chan->channel = pvt->channel;
  12035. dahdi_nobch_insert(pri, pvt);
  12036. return pvt_idx;
  12037. }
  12038. #endif /* defined(HAVE_PRI) */
  12039. /* This function can *ONLY* be used for copying pseudo (CHAN_PSEUDO) private
  12040. structures; it makes no attempt to safely copy regular channel private
  12041. structures that might contain reference-counted object pointers and other
  12042. scary bits
  12043. */
  12044. static struct dahdi_pvt *duplicate_pseudo(struct dahdi_pvt *src)
  12045. {
  12046. struct dahdi_pvt *p;
  12047. struct dahdi_bufferinfo bi;
  12048. int res;
  12049. p = ast_malloc(sizeof(*p));
  12050. if (!p) {
  12051. return NULL;
  12052. }
  12053. *p = *src;
  12054. /* Must deep copy the cc_params. */
  12055. p->cc_params = ast_cc_config_params_init();
  12056. if (!p->cc_params) {
  12057. ast_free(p);
  12058. return NULL;
  12059. }
  12060. ast_cc_copy_config_params(p->cc_params, src->cc_params);
  12061. p->which_iflist = DAHDI_IFLIST_NONE;
  12062. p->next = NULL;
  12063. p->prev = NULL;
  12064. ast_mutex_init(&p->lock);
  12065. p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
  12066. if (p->subs[SUB_REAL].dfd < 0) {
  12067. ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
  12068. destroy_dahdi_pvt(p);
  12069. return NULL;
  12070. }
  12071. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
  12072. if (!res) {
  12073. bi.txbufpolicy = src->buf_policy;
  12074. bi.rxbufpolicy = src->buf_policy;
  12075. bi.numbufs = src->buf_no;
  12076. res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
  12077. if (res < 0) {
  12078. ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
  12079. }
  12080. } else
  12081. ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
  12082. p->destroy = 1;
  12083. dahdi_iflist_insert(p);
  12084. return p;
  12085. }
  12086. struct dahdi_starting_point {
  12087. /*! Group matching mask. Zero if not specified. */
  12088. ast_group_t groupmatch;
  12089. /*! DAHDI channel to match with. -1 if not specified. */
  12090. int channelmatch;
  12091. /*! Round robin saved search location index. (Valid if roundrobin TRUE) */
  12092. int rr_starting_point;
  12093. /*! ISDN span where channels can be picked (Zero if not specified) */
  12094. int span;
  12095. /*! Analog channel distinctive ring cadance index. */
  12096. int cadance;
  12097. /*! Dialing option. c/r/d if present and valid. */
  12098. char opt;
  12099. /*! TRUE if to search the channel list backwards. */
  12100. char backwards;
  12101. /*! TRUE if search is done with round robin sequence. */
  12102. char roundrobin;
  12103. };
  12104. static struct dahdi_pvt *determine_starting_point(const char *data, struct dahdi_starting_point *param)
  12105. {
  12106. char *dest;
  12107. char *s;
  12108. int x;
  12109. int res = 0;
  12110. struct dahdi_pvt *p;
  12111. char *subdir = NULL;
  12112. AST_DECLARE_APP_ARGS(args,
  12113. AST_APP_ARG(group); /* channel/group token */
  12114. //AST_APP_ARG(ext); /* extension token */
  12115. //AST_APP_ARG(opts); /* options token */
  12116. AST_APP_ARG(other); /* Any remining unused arguments */
  12117. );
  12118. /*
  12119. * data is ---v
  12120. * Dial(DAHDI/pseudo[/extension[/options]])
  12121. * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]])
  12122. * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]])
  12123. * Dial(DAHDI/i<span>[/extension[/options]])
  12124. * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]])
  12125. *
  12126. * i - ISDN span channel restriction.
  12127. * Used by CC to ensure that the CC recall goes out the same span.
  12128. * Also to make ISDN channel names dialable when the sequence number
  12129. * is stripped off. (Used by DTMF attended transfer feature.)
  12130. *
  12131. * g - channel group allocation search forward
  12132. * G - channel group allocation search backward
  12133. * r - channel group allocation round robin search forward
  12134. * R - channel group allocation round robin search backward
  12135. *
  12136. * c - Wait for DTMF digit to confirm answer
  12137. * r<cadance#> - Set distintive ring cadance number
  12138. * d - Force bearer capability for ISDN/SS7 call to digital.
  12139. */
  12140. if (data) {
  12141. dest = ast_strdupa(data);
  12142. } else {
  12143. ast_log(LOG_WARNING, "Channel requested with no data\n");
  12144. return NULL;
  12145. }
  12146. AST_NONSTANDARD_APP_ARGS(args, dest, '/');
  12147. if (!args.argc || ast_strlen_zero(args.group)) {
  12148. ast_log(LOG_WARNING, "No channel/group specified\n");
  12149. return NULL;
  12150. }
  12151. /* Initialize the output parameters */
  12152. memset(param, 0, sizeof(*param));
  12153. param->channelmatch = -1;
  12154. if (strchr(args.group, '!') != NULL) {
  12155. char *prev = args.group;
  12156. while ((s = strchr(prev, '!')) != NULL) {
  12157. *s++ = '/';
  12158. prev = s;
  12159. }
  12160. *(prev - 1) = '\0';
  12161. subdir = args.group;
  12162. args.group = prev;
  12163. } else if (args.group[0] == 'i') {
  12164. /* Extract the ISDN span channel restriction specifier. */
  12165. res = sscanf(args.group + 1, "%30d", &x);
  12166. if (res < 1) {
  12167. ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data);
  12168. return NULL;
  12169. }
  12170. param->span = x;
  12171. /* Remove the ISDN span channel restriction specifier. */
  12172. s = strchr(args.group, '-');
  12173. if (!s) {
  12174. /* Search all groups since we are ISDN span restricted. */
  12175. return iflist;
  12176. }
  12177. args.group = s + 1;
  12178. res = 0;
  12179. }
  12180. if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') {
  12181. /* Retrieve the group number */
  12182. s = args.group + 1;
  12183. res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadance);
  12184. if (res < 1) {
  12185. ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data);
  12186. return NULL;
  12187. }
  12188. param->groupmatch = ((ast_group_t) 1 << x);
  12189. if (toupper(args.group[0]) == 'G') {
  12190. if (args.group[0] == 'G') {
  12191. param->backwards = 1;
  12192. p = ifend;
  12193. } else
  12194. p = iflist;
  12195. } else {
  12196. if (ARRAY_LEN(round_robin) <= x) {
  12197. ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n",
  12198. x, data);
  12199. return NULL;
  12200. }
  12201. if (args.group[0] == 'R') {
  12202. param->backwards = 1;
  12203. p = round_robin[x] ? round_robin[x]->prev : ifend;
  12204. if (!p)
  12205. p = ifend;
  12206. } else {
  12207. p = round_robin[x] ? round_robin[x]->next : iflist;
  12208. if (!p)
  12209. p = iflist;
  12210. }
  12211. param->roundrobin = 1;
  12212. param->rr_starting_point = x;
  12213. }
  12214. } else {
  12215. s = args.group;
  12216. if (!strcasecmp(s, "pseudo")) {
  12217. /* Special case for pseudo */
  12218. x = CHAN_PSEUDO;
  12219. param->channelmatch = x;
  12220. } else {
  12221. res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadance);
  12222. if (res < 1) {
  12223. ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data);
  12224. return NULL;
  12225. } else {
  12226. param->channelmatch = x;
  12227. }
  12228. }
  12229. if (subdir) {
  12230. char path[PATH_MAX];
  12231. struct stat stbuf;
  12232. snprintf(path, sizeof(path), "/dev/dahdi/%s/%d",
  12233. subdir, param->channelmatch);
  12234. if (stat(path, &stbuf) < 0) {
  12235. ast_log(LOG_WARNING, "stat(%s) failed: %s\n",
  12236. path, strerror(errno));
  12237. return NULL;
  12238. }
  12239. if (!S_ISCHR(stbuf.st_mode)) {
  12240. ast_log(LOG_ERROR, "%s: Not a character device file\n",
  12241. path);
  12242. return NULL;
  12243. }
  12244. param->channelmatch = minor(stbuf.st_rdev);
  12245. }
  12246. p = iflist;
  12247. }
  12248. if (param->opt == 'r' && res < 3) {
  12249. ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data);
  12250. param->opt = '\0';
  12251. }
  12252. return p;
  12253. }
  12254. static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap,
  12255. const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
  12256. const char *data, int *cause)
  12257. {
  12258. int callwait = 0;
  12259. struct dahdi_pvt *p;
  12260. struct ast_channel *tmp = NULL;
  12261. struct dahdi_pvt *exitpvt;
  12262. int channelmatched = 0;
  12263. int groupmatched = 0;
  12264. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  12265. int transcapdigital = 0;
  12266. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  12267. struct dahdi_starting_point start;
  12268. struct ast_callid *callid = NULL;
  12269. int callid_created = ast_callid_threadstorage_auto(&callid);
  12270. ast_mutex_lock(&iflock);
  12271. p = determine_starting_point(data, &start);
  12272. if (!p) {
  12273. /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */
  12274. ast_mutex_unlock(&iflock);
  12275. ast_callid_threadstorage_auto_clean(callid, callid_created);
  12276. return NULL;
  12277. }
  12278. /* Search for an unowned channel */
  12279. exitpvt = p;
  12280. while (p && !tmp) {
  12281. if (start.roundrobin)
  12282. round_robin[start.rr_starting_point] = p;
  12283. if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)
  12284. && available(&p, channelmatched)) {
  12285. ast_debug(1, "Using channel %d\n", p->channel);
  12286. callwait = (p->owner != NULL);
  12287. #ifdef HAVE_OPENR2
  12288. if (p->mfcr2) {
  12289. ast_mutex_lock(&p->lock);
  12290. if (p->mfcr2call) {
  12291. ast_mutex_unlock(&p->lock);
  12292. ast_debug(1, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
  12293. goto next;
  12294. }
  12295. p->mfcr2call = 1;
  12296. ast_mutex_unlock(&p->lock);
  12297. }
  12298. #endif
  12299. if (p->channel == CHAN_PSEUDO) {
  12300. p = duplicate_pseudo(p);
  12301. if (!p) {
  12302. break;
  12303. }
  12304. }
  12305. p->distinctivering = 0;
  12306. /* Make special notes */
  12307. switch (start.opt) {
  12308. case '\0':
  12309. /* No option present. */
  12310. break;
  12311. case 'c':
  12312. /* Confirm answer */
  12313. p->confirmanswer = 1;
  12314. break;
  12315. case 'r':
  12316. /* Distinctive ring */
  12317. p->distinctivering = start.cadance;
  12318. break;
  12319. case 'd':
  12320. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  12321. /* If this is an ISDN call, make it digital */
  12322. transcapdigital = AST_TRANS_CAP_DIGITAL;
  12323. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  12324. break;
  12325. default:
  12326. ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, data);
  12327. break;
  12328. }
  12329. p->outgoing = 1;
  12330. if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
  12331. tmp = analog_request(p->sig_pvt, &callwait, requestor);
  12332. #ifdef HAVE_PRI
  12333. } else if (dahdi_sig_pri_lib_handles(p->sig)) {
  12334. /*
  12335. * We already have the B channel reserved for this call. We
  12336. * just need to make sure that dahdi_hangup() has completed
  12337. * cleaning up before continuing.
  12338. */
  12339. ast_mutex_lock(&p->lock);
  12340. ast_mutex_unlock(&p->lock);
  12341. sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid,
  12342. sizeof(p->dnid));
  12343. tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, assignedids, requestor, transcapdigital);
  12344. #endif
  12345. #if defined(HAVE_SS7)
  12346. } else if (p->sig == SIG_SS7) {
  12347. tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, assignedids, requestor, transcapdigital);
  12348. #endif /* defined(HAVE_SS7) */
  12349. } else {
  12350. tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, assignedids, requestor, callid);
  12351. }
  12352. if (!tmp) {
  12353. p->outgoing = 0;
  12354. #if defined(HAVE_PRI)
  12355. switch (p->sig) {
  12356. case SIG_PRI_LIB_HANDLE_CASES:
  12357. #if defined(HAVE_PRI_CALL_WAITING)
  12358. if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) {
  12359. ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0;
  12360. ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
  12361. }
  12362. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  12363. /*
  12364. * This should be the last thing to clear when we are done with
  12365. * the channel.
  12366. */
  12367. ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0;
  12368. break;
  12369. default:
  12370. break;
  12371. }
  12372. #endif /* defined(HAVE_PRI) */
  12373. } else {
  12374. snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", data);
  12375. }
  12376. break;
  12377. }
  12378. #ifdef HAVE_OPENR2
  12379. next:
  12380. #endif
  12381. if (start.backwards) {
  12382. p = p->prev;
  12383. if (!p)
  12384. p = ifend;
  12385. } else {
  12386. p = p->next;
  12387. if (!p)
  12388. p = iflist;
  12389. }
  12390. /* stop when you roll to the one that we started from */
  12391. if (p == exitpvt)
  12392. break;
  12393. }
  12394. ast_mutex_unlock(&iflock);
  12395. restart_monitor();
  12396. if (cause && !tmp) {
  12397. if (callwait || channelmatched) {
  12398. *cause = AST_CAUSE_BUSY;
  12399. } else if (groupmatched) {
  12400. *cause = AST_CAUSE_CONGESTION;
  12401. } else {
  12402. /*
  12403. * We did not match any channel requested.
  12404. * Dialplan error requesting non-existant channel?
  12405. */
  12406. }
  12407. }
  12408. ast_callid_threadstorage_auto_clean(callid, callid_created);
  12409. return tmp;
  12410. }
  12411. /*!
  12412. * \internal
  12413. * \brief Determine the device state for a given DAHDI device if we can.
  12414. * \since 1.8
  12415. *
  12416. * \param data DAHDI device name after "DAHDI/".
  12417. *
  12418. * \retval device_state enum ast_device_state value.
  12419. * \retval AST_DEVICE_UNKNOWN if we could not determine the device's state.
  12420. */
  12421. static int dahdi_devicestate(const char *data)
  12422. {
  12423. #if defined(HAVE_PRI)
  12424. const char *device;
  12425. unsigned span;
  12426. int res;
  12427. device = data;
  12428. if (*device != 'I') {
  12429. /* The request is not for an ISDN span device. */
  12430. return AST_DEVICE_UNKNOWN;
  12431. }
  12432. res = sscanf(device, "I%30u", &span);
  12433. if (res != 1 || !span || NUM_SPANS < span) {
  12434. /* Bad format for ISDN span device name. */
  12435. return AST_DEVICE_UNKNOWN;
  12436. }
  12437. device = strchr(device, '/');
  12438. if (!device) {
  12439. /* Bad format for ISDN span device name. */
  12440. return AST_DEVICE_UNKNOWN;
  12441. }
  12442. /*
  12443. * Since there are currently no other span devstate's defined,
  12444. * it must be congestion.
  12445. */
  12446. #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
  12447. ++device;
  12448. if (!strcmp(device, "congestion"))
  12449. #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
  12450. {
  12451. return pris[span - 1].pri.congestion_devstate;
  12452. }
  12453. #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
  12454. else if (!strcmp(device, "threshold")) {
  12455. return pris[span - 1].pri.threshold_devstate;
  12456. }
  12457. return AST_DEVICE_UNKNOWN;
  12458. #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
  12459. #else
  12460. return AST_DEVICE_UNKNOWN;
  12461. #endif /* defined(HAVE_PRI) */
  12462. }
  12463. /*!
  12464. * \brief Callback made when dial failed to get a channel out of dahdi_request().
  12465. * \since 1.8
  12466. *
  12467. * \param inbound Incoming asterisk channel.
  12468. * \param dest Same dial string passed to dahdi_request().
  12469. * \param callback Callback into CC core to announce a busy channel available for CC.
  12470. *
  12471. * \details
  12472. * This callback acts like a forked dial with all prongs of the fork busy.
  12473. * Essentially, for each channel that could have taken the call, indicate that
  12474. * it is busy.
  12475. *
  12476. * \retval 0 on success.
  12477. * \retval -1 on error.
  12478. */
  12479. static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback)
  12480. {
  12481. struct dahdi_pvt *p;
  12482. struct dahdi_pvt *exitpvt;
  12483. struct dahdi_starting_point start;
  12484. int groupmatched = 0;
  12485. int channelmatched = 0;
  12486. ast_mutex_lock(&iflock);
  12487. p = determine_starting_point(dest, &start);
  12488. if (!p) {
  12489. ast_mutex_unlock(&iflock);
  12490. return -1;
  12491. }
  12492. exitpvt = p;
  12493. for (;;) {
  12494. if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) {
  12495. /* We found a potential match. call the callback */
  12496. struct ast_str *device_name;
  12497. char *dash;
  12498. const char *monitor_type;
  12499. char dialstring[AST_CHANNEL_NAME];
  12500. char full_device_name[AST_CHANNEL_NAME];
  12501. switch (ast_get_cc_monitor_policy(p->cc_params)) {
  12502. case AST_CC_MONITOR_NEVER:
  12503. break;
  12504. case AST_CC_MONITOR_NATIVE:
  12505. case AST_CC_MONITOR_ALWAYS:
  12506. case AST_CC_MONITOR_GENERIC:
  12507. #if defined(HAVE_PRI)
  12508. if (dahdi_sig_pri_lib_handles(p->sig)) {
  12509. /*
  12510. * ISDN is in a trunk busy condition so we need to monitor
  12511. * the span congestion device state.
  12512. */
  12513. snprintf(full_device_name, sizeof(full_device_name),
  12514. "DAHDI/I%d/congestion", p->pri->span);
  12515. } else
  12516. #endif /* defined(HAVE_PRI) */
  12517. {
  12518. #if defined(HAVE_PRI)
  12519. device_name = create_channel_name(p, 1, "");
  12520. #else
  12521. device_name = create_channel_name(p);
  12522. #endif /* defined(HAVE_PRI) */
  12523. snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s",
  12524. device_name ? ast_str_buffer(device_name) : "");
  12525. ast_free(device_name);
  12526. /*
  12527. * The portion after the '-' in the channel name is either a random
  12528. * number, a sequence number, or a subchannel number. None are
  12529. * necessary so strip them off.
  12530. */
  12531. dash = strrchr(full_device_name, '-');
  12532. if (dash) {
  12533. *dash = '\0';
  12534. }
  12535. }
  12536. snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest);
  12537. /*
  12538. * Analog can only do generic monitoring.
  12539. * ISDN is in a trunk busy condition and any "device" is going
  12540. * to be busy until a B channel becomes available. The generic
  12541. * monitor can do this task.
  12542. */
  12543. monitor_type = AST_CC_GENERIC_MONITOR_TYPE;
  12544. callback(inbound,
  12545. #if defined(HAVE_PRI)
  12546. p->pri ? p->pri->cc_params : p->cc_params,
  12547. #else
  12548. p->cc_params,
  12549. #endif /* defined(HAVE_PRI) */
  12550. monitor_type, full_device_name, dialstring, NULL);
  12551. break;
  12552. }
  12553. }
  12554. p = start.backwards ? p->prev : p->next;
  12555. if (!p) {
  12556. p = start.backwards ? ifend : iflist;
  12557. }
  12558. if (p == exitpvt) {
  12559. break;
  12560. }
  12561. }
  12562. ast_mutex_unlock(&iflock);
  12563. return 0;
  12564. }
  12565. #if defined(HAVE_SS7)
  12566. static void dahdi_ss7_message(struct ss7 *ss7, char *s)
  12567. {
  12568. int i;
  12569. if (ss7) {
  12570. for (i = 0; i < NUM_SPANS; i++) {
  12571. if (linksets[i].ss7.ss7 == ss7) {
  12572. ast_verbose_callid(NULL, "[%d] %s", i + 1, s);
  12573. return;
  12574. }
  12575. }
  12576. }
  12577. ast_verbose_callid(NULL, "%s", s);
  12578. }
  12579. #endif /* defined(HAVE_SS7) */
  12580. #if defined(HAVE_SS7)
  12581. static void dahdi_ss7_error(struct ss7 *ss7, char *s)
  12582. {
  12583. int i;
  12584. if (ss7) {
  12585. for (i = 0; i < NUM_SPANS; i++) {
  12586. if (linksets[i].ss7.ss7 == ss7) {
  12587. ast_log_callid(LOG_ERROR, NULL, "[%d] %s", i + 1, s);
  12588. return;
  12589. }
  12590. }
  12591. }
  12592. ast_log_callid(LOG_ERROR, NULL, "%s", s);
  12593. }
  12594. #endif /* defined(HAVE_SS7) */
  12595. #if defined(HAVE_OPENR2)
  12596. static void *mfcr2_monitor(void *data)
  12597. {
  12598. struct dahdi_mfcr2 *mfcr2 = data;
  12599. /* we should be using pthread_key_create
  12600. and allocate pollers dynamically.
  12601. I think do_monitor() could be leaking, since it
  12602. could be cancelled at any time and is not
  12603. using thread keys, why?, */
  12604. struct pollfd pollers[ARRAY_LEN(mfcr2->pvts)];
  12605. int res = 0;
  12606. int i = 0;
  12607. int oldstate = 0;
  12608. int quit_loop = 0;
  12609. int maxsleep = 20;
  12610. int was_idle = 0;
  12611. int pollsize = 0;
  12612. /* now that we're ready to get calls, unblock our side and
  12613. get current line state */
  12614. for (i = 0; i < mfcr2->numchans; i++) {
  12615. openr2_chan_set_idle(mfcr2->pvts[i]->r2chan);
  12616. openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan);
  12617. }
  12618. while (1) {
  12619. /* we trust here that the mfcr2 channel list will not ever change once
  12620. the module is loaded */
  12621. pollsize = 0;
  12622. for (i = 0; i < mfcr2->numchans; i++) {
  12623. pollers[i].revents = 0;
  12624. pollers[i].events = 0;
  12625. if (mfcr2->pvts[i]->owner) {
  12626. continue;
  12627. }
  12628. if (!mfcr2->pvts[i]->r2chan) {
  12629. ast_debug(1, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel);
  12630. quit_loop = 1;
  12631. break;
  12632. }
  12633. openr2_chan_enable_read(mfcr2->pvts[i]->r2chan);
  12634. pollers[i].events = POLLIN | POLLPRI;
  12635. pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd;
  12636. pollsize++;
  12637. }
  12638. if (quit_loop) {
  12639. break;
  12640. }
  12641. if (pollsize == 0) {
  12642. if (!was_idle) {
  12643. ast_debug(1, "Monitor thread going idle since everybody has an owner\n");
  12644. was_idle = 1;
  12645. }
  12646. poll(NULL, 0, maxsleep);
  12647. continue;
  12648. }
  12649. was_idle = 0;
  12650. /* probably poll() is a valid cancel point, lets just be on the safe side
  12651. by calling pthread_testcancel */
  12652. pthread_testcancel();
  12653. res = poll(pollers, mfcr2->numchans, maxsleep);
  12654. pthread_testcancel();
  12655. if ((res < 0) && (errno != EINTR)) {
  12656. ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno));
  12657. break;
  12658. }
  12659. /* do we want to allow to cancel while processing events? */
  12660. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
  12661. for (i = 0; i < mfcr2->numchans; i++) {
  12662. if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
  12663. openr2_chan_process_event(mfcr2->pvts[i]->r2chan);
  12664. }
  12665. }
  12666. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
  12667. }
  12668. ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n");
  12669. return 0;
  12670. }
  12671. #endif /* HAVE_OPENR2 */
  12672. #if defined(HAVE_PRI)
  12673. static void dahdi_pri_message(struct pri *pri, char *s)
  12674. {
  12675. int x;
  12676. int y;
  12677. int dchan = -1;
  12678. int span = -1;
  12679. int dchancount = 0;
  12680. if (pri) {
  12681. for (x = 0; x < NUM_SPANS; x++) {
  12682. for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
  12683. if (pris[x].pri.dchans[y]) {
  12684. dchancount++;
  12685. }
  12686. if (pris[x].pri.dchans[y] == pri) {
  12687. dchan = y;
  12688. }
  12689. }
  12690. if (dchan >= 0) {
  12691. span = x;
  12692. break;
  12693. }
  12694. dchancount = 0;
  12695. }
  12696. if (-1 < span) {
  12697. if (1 < dchancount) {
  12698. ast_verbose_callid(NULL, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
  12699. } else {
  12700. ast_verbose_callid(NULL, "PRI Span: %d %s", span + 1, s);
  12701. }
  12702. } else {
  12703. ast_verbose_callid(NULL, "PRI Span: ? %s", s);
  12704. }
  12705. } else {
  12706. ast_verbose_callid(NULL, "PRI Span: ? %s", s);
  12707. }
  12708. ast_mutex_lock(&pridebugfdlock);
  12709. if (pridebugfd >= 0) {
  12710. if (write(pridebugfd, s, strlen(s)) < 0) {
  12711. ast_log_callid(LOG_WARNING, NULL, "write() failed: %s\n", strerror(errno));
  12712. }
  12713. }
  12714. ast_mutex_unlock(&pridebugfdlock);
  12715. }
  12716. #endif /* defined(HAVE_PRI) */
  12717. #if defined(HAVE_PRI)
  12718. static void dahdi_pri_error(struct pri *pri, char *s)
  12719. {
  12720. int x;
  12721. int y;
  12722. int dchan = -1;
  12723. int span = -1;
  12724. int dchancount = 0;
  12725. if (pri) {
  12726. for (x = 0; x < NUM_SPANS; x++) {
  12727. for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
  12728. if (pris[x].pri.dchans[y]) {
  12729. dchancount++;
  12730. }
  12731. if (pris[x].pri.dchans[y] == pri) {
  12732. dchan = y;
  12733. }
  12734. }
  12735. if (dchan >= 0) {
  12736. span = x;
  12737. break;
  12738. }
  12739. dchancount = 0;
  12740. }
  12741. if (-1 < span) {
  12742. if (1 < dchancount) {
  12743. ast_log_callid(LOG_ERROR, NULL, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
  12744. } else {
  12745. ast_log_callid(LOG_ERROR, NULL, "PRI Span: %d %s", span + 1, s);
  12746. }
  12747. } else {
  12748. ast_log_callid(LOG_ERROR, NULL, "PRI Span: ? %s", s);
  12749. }
  12750. } else {
  12751. ast_log_callid(LOG_ERROR, NULL, "PRI Span: ? %s", s);
  12752. }
  12753. ast_mutex_lock(&pridebugfdlock);
  12754. if (pridebugfd >= 0) {
  12755. if (write(pridebugfd, s, strlen(s)) < 0) {
  12756. ast_log_callid(LOG_WARNING, NULL, "write() failed: %s\n", strerror(errno));
  12757. }
  12758. }
  12759. ast_mutex_unlock(&pridebugfdlock);
  12760. }
  12761. #endif /* defined(HAVE_PRI) */
  12762. #if defined(HAVE_PRI)
  12763. static int prepare_pri(struct dahdi_pri *pri)
  12764. {
  12765. int i, res, x;
  12766. struct dahdi_params p;
  12767. struct dahdi_bufferinfo bi;
  12768. struct dahdi_spaninfo si;
  12769. for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
  12770. if (!pri->dchannels[i])
  12771. break;
  12772. if (pri->pri.fds[i] >= 0) {
  12773. /* A partial range addition. Not a complete setup. */
  12774. break;
  12775. }
  12776. pri->pri.fds[i] = open("/dev/dahdi/channel", O_RDWR);
  12777. if ((pri->pri.fds[i] < 0)) {
  12778. ast_log(LOG_ERROR, "Unable to open D-channel (fd=%d) (%s)\n",
  12779. pri->pri.fds[i], strerror(errno));
  12780. return -1;
  12781. }
  12782. x = pri->dchannels[i];
  12783. res = ioctl(pri->pri.fds[i], DAHDI_SPECIFY, &x);
  12784. if (res) {
  12785. dahdi_close_pri_fd(pri, i);
  12786. ast_log(LOG_ERROR, "Unable to SPECIFY channel %d (%s)\n", x, strerror(errno));
  12787. return -1;
  12788. }
  12789. memset(&p, 0, sizeof(p));
  12790. res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p);
  12791. if (res) {
  12792. dahdi_close_pri_fd(pri, i);
  12793. ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
  12794. return -1;
  12795. }
  12796. if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
  12797. dahdi_close_pri_fd(pri, i);
  12798. ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.\n", x);
  12799. return -1;
  12800. }
  12801. memset(&si, 0, sizeof(si));
  12802. res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si);
  12803. if (res) {
  12804. dahdi_close_pri_fd(pri, i);
  12805. ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
  12806. }
  12807. if (!si.alarms) {
  12808. pri_event_noalarm(&pri->pri, i, 1);
  12809. } else {
  12810. pri_event_alarm(&pri->pri, i, 1);
  12811. }
  12812. memset(&bi, 0, sizeof(bi));
  12813. bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
  12814. bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
  12815. bi.numbufs = 32;
  12816. bi.bufsize = 1024;
  12817. if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) {
  12818. ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno));
  12819. dahdi_close_pri_fd(pri, i);
  12820. return -1;
  12821. }
  12822. pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan;
  12823. }
  12824. return 0;
  12825. }
  12826. #endif /* defined(HAVE_PRI) */
  12827. #if defined(HAVE_PRI)
  12828. static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
  12829. {
  12830. int which, span;
  12831. char *ret = NULL;
  12832. if (pos != rpos)
  12833. return ret;
  12834. for (which = span = 0; span < NUM_SPANS; span++) {
  12835. if (pris[span].pri.pri && ++which > state) {
  12836. if (ast_asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */
  12837. ret = NULL;
  12838. }
  12839. break;
  12840. }
  12841. }
  12842. return ret;
  12843. }
  12844. #endif /* defined(HAVE_PRI) */
  12845. #if defined(HAVE_PRI)
  12846. static char *complete_span_4(const char *line, const char *word, int pos, int state)
  12847. {
  12848. return complete_span_helper(line,word,pos,state,3);
  12849. }
  12850. #endif /* defined(HAVE_PRI) */
  12851. #if defined(HAVE_PRI)
  12852. static char *handle_pri_set_debug_file(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  12853. {
  12854. int myfd;
  12855. switch (cmd) {
  12856. case CLI_INIT:
  12857. e->command = "pri set debug file";
  12858. e->usage = "Usage: pri set debug file [output-file]\n"
  12859. " Sends PRI debug output to the specified output file\n";
  12860. return NULL;
  12861. case CLI_GENERATE:
  12862. return NULL;
  12863. }
  12864. if (a->argc < 5)
  12865. return CLI_SHOWUSAGE;
  12866. if (ast_strlen_zero(a->argv[4]))
  12867. return CLI_SHOWUSAGE;
  12868. myfd = open(a->argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE);
  12869. if (myfd < 0) {
  12870. ast_cli(a->fd, "Unable to open '%s' for writing\n", a->argv[4]);
  12871. return CLI_SUCCESS;
  12872. }
  12873. ast_mutex_lock(&pridebugfdlock);
  12874. if (pridebugfd >= 0)
  12875. close(pridebugfd);
  12876. pridebugfd = myfd;
  12877. ast_copy_string(pridebugfilename,a->argv[4],sizeof(pridebugfilename));
  12878. ast_mutex_unlock(&pridebugfdlock);
  12879. ast_cli(a->fd, "PRI debug output will be sent to '%s'\n", a->argv[4]);
  12880. return CLI_SUCCESS;
  12881. }
  12882. #endif /* defined(HAVE_PRI) */
  12883. #if defined(HAVE_PRI)
  12884. static int action_pri_debug_file_set(struct mansession *s, const struct message *m)
  12885. {
  12886. const char *output_file = astman_get_header(m, "File");
  12887. int myfd;
  12888. if (ast_strlen_zero(output_file)) {
  12889. astman_send_error(s, m, "Action must define a 'File'");
  12890. }
  12891. myfd = open(output_file, O_CREAT|O_WRONLY, AST_FILE_MODE);
  12892. if (myfd < 0) {
  12893. astman_send_error(s, m, "Unable to open requested file for writing");
  12894. return 0;
  12895. }
  12896. ast_mutex_lock(&pridebugfdlock);
  12897. if (pridebugfd >= 0) {
  12898. close(pridebugfd);
  12899. }
  12900. pridebugfd = myfd;
  12901. ast_copy_string(pridebugfilename, output_file, sizeof(pridebugfilename));
  12902. ast_mutex_unlock(&pridebugfdlock);
  12903. astman_send_ack(s, m, "PRI debug output will now be sent to requested file.");
  12904. return 0;
  12905. }
  12906. #endif /* defined(HAVE_PRI) */
  12907. #if defined(HAVE_PRI)
  12908. static int action_pri_debug_file_unset(struct mansession *s, const struct message *m)
  12909. {
  12910. ast_mutex_lock(&pridebugfdlock);
  12911. if (pridebugfd >= 0) {
  12912. close(pridebugfd);
  12913. }
  12914. pridebugfd = -1;
  12915. ast_mutex_unlock(&pridebugfdlock);
  12916. astman_send_ack(s, m, "PRI Debug output to file disabled");
  12917. return 0;
  12918. }
  12919. #endif /* defined(HAVE_PRI) */
  12920. #if defined(HAVE_PRI)
  12921. static char *handle_pri_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  12922. {
  12923. int span;
  12924. int x;
  12925. int debugmask = 0;
  12926. int level = 0;
  12927. switch (cmd) {
  12928. case CLI_INIT:
  12929. e->command = "pri set debug {on|off|hex|intense|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15} span";
  12930. e->usage =
  12931. "Usage: pri set debug {<level>|on|off|hex|intense} span <span>\n"
  12932. " Enables debugging on a given PRI span\n"
  12933. " Level is a bitmap of the following values:\n"
  12934. " 1 General debugging incl. state changes\n"
  12935. " 2 Decoded Q.931 messages\n"
  12936. " 4 Decoded Q.921 messages\n"
  12937. " 8 Raw hex dumps of Q.921 frames\n"
  12938. " on - equivalent to 3\n"
  12939. " hex - equivalent to 8\n"
  12940. " intense - equivalent to 15\n";
  12941. return NULL;
  12942. case CLI_GENERATE:
  12943. return complete_span_4(a->line, a->word, a->pos, a->n);
  12944. }
  12945. if (a->argc < 6) {
  12946. return CLI_SHOWUSAGE;
  12947. }
  12948. if (!strcasecmp(a->argv[3], "on")) {
  12949. level = 3;
  12950. } else if (!strcasecmp(a->argv[3], "off")) {
  12951. level = 0;
  12952. } else if (!strcasecmp(a->argv[3], "intense")) {
  12953. level = 15;
  12954. } else if (!strcasecmp(a->argv[3], "hex")) {
  12955. level = 8;
  12956. } else {
  12957. level = atoi(a->argv[3]);
  12958. }
  12959. span = atoi(a->argv[5]);
  12960. if ((span < 1) || (span > NUM_SPANS)) {
  12961. ast_cli(a->fd, "Invalid span %s. Should be a number %d to %d\n", a->argv[5], 1, NUM_SPANS);
  12962. return CLI_SUCCESS;
  12963. }
  12964. if (!pris[span-1].pri.pri) {
  12965. ast_cli(a->fd, "No PRI running on span %d\n", span);
  12966. return CLI_SUCCESS;
  12967. }
  12968. if (level & 1) debugmask |= SIG_PRI_DEBUG_NORMAL;
  12969. if (level & 2) debugmask |= PRI_DEBUG_Q931_DUMP;
  12970. if (level & 4) debugmask |= PRI_DEBUG_Q921_DUMP;
  12971. if (level & 8) debugmask |= PRI_DEBUG_Q921_RAW;
  12972. /* Set debug level in libpri */
  12973. for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
  12974. if (pris[span - 1].pri.dchans[x]) {
  12975. pri_set_debug(pris[span - 1].pri.dchans[x], debugmask);
  12976. }
  12977. }
  12978. if (level == 0) {
  12979. /* Close the debugging file if it's set */
  12980. ast_mutex_lock(&pridebugfdlock);
  12981. if (0 <= pridebugfd) {
  12982. close(pridebugfd);
  12983. pridebugfd = -1;
  12984. ast_cli(a->fd, "Disabled PRI debug output to file '%s'\n",
  12985. pridebugfilename);
  12986. }
  12987. ast_mutex_unlock(&pridebugfdlock);
  12988. }
  12989. pris[span - 1].pri.debug = (level) ? 1 : 0;
  12990. ast_cli(a->fd, "%s debugging on span %d\n", (level) ? "Enabled" : "Disabled", span);
  12991. return CLI_SUCCESS;
  12992. }
  12993. #endif /* defined(HAVE_PRI) */
  12994. #if defined(HAVE_PRI)
  12995. static int action_pri_debug_set(struct mansession *s, const struct message *m)
  12996. {
  12997. const char *level = astman_get_header(m, "Level");
  12998. const char *span = astman_get_header(m, "Span");
  12999. int level_val;
  13000. int span_val;
  13001. int x;
  13002. int debugmask = 0;
  13003. if (ast_strlen_zero(level)) {
  13004. astman_send_error(s, m, "'Level' was not specified");
  13005. return 0;
  13006. }
  13007. if (ast_strlen_zero(span)) {
  13008. astman_send_error(s, m, "'Span' was not specified");
  13009. return 0;
  13010. }
  13011. if (!strcasecmp(level, "on")) {
  13012. level_val = 3;
  13013. } else if (!strcasecmp(level, "off")) {
  13014. level_val = 0;
  13015. } else if (!strcasecmp(level, "intense")) {
  13016. level_val = 15;
  13017. } else if (!strcasecmp(level, "hex")) {
  13018. level_val = 8;
  13019. } else {
  13020. if (sscanf(level, "%30d", &level_val) != 1) {
  13021. astman_send_error(s, m, "Invalid value for 'Level'");
  13022. return 0;
  13023. }
  13024. }
  13025. if (sscanf(span, "%30d", &span_val) != 1) {
  13026. astman_send_error(s, m, "Invalid value for 'Span'");
  13027. }
  13028. if ((span_val < 1) || (span_val > NUM_SPANS)) {
  13029. const char *id = astman_get_header(m, "ActionID");
  13030. char id_text[256] = "";
  13031. if (!ast_strlen_zero(id)) {
  13032. snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
  13033. }
  13034. astman_append(s, "Response: Error\r\n"
  13035. "%s" /* id_text */
  13036. "Message: Invalid span '%s' - Should be a number from 1 to %d\r\n"
  13037. "\r\n",
  13038. id_text,
  13039. span, NUM_SPANS);
  13040. return 0;
  13041. }
  13042. if (!pris[span_val-1].pri.pri) {
  13043. astman_send_error(s, m, "No PRI running on requested span");
  13044. return 0;
  13045. }
  13046. if (level_val & 1) {
  13047. debugmask |= SIG_PRI_DEBUG_NORMAL;
  13048. }
  13049. if (level_val & 2) {
  13050. debugmask |= PRI_DEBUG_Q931_DUMP;
  13051. }
  13052. if (level_val & 4) {
  13053. debugmask |= PRI_DEBUG_Q921_DUMP;
  13054. }
  13055. if (level_val & 8) {
  13056. debugmask |= PRI_DEBUG_Q921_RAW;
  13057. }
  13058. /* Set debug level in libpri */
  13059. for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
  13060. if (pris[span_val - 1].pri.dchans[x]) {
  13061. pri_set_debug(pris[span_val - 1].pri.dchans[x], debugmask);
  13062. }
  13063. }
  13064. pris[span_val - 1].pri.debug = (level_val) ? 1 : 0;
  13065. astman_send_ack(s, m, "Debug level set for requested span");
  13066. return 0;
  13067. }
  13068. #endif /* defined(HAVE_PRI) */
  13069. #if defined(HAVE_PRI)
  13070. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  13071. static char *handle_pri_service_generic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a, int changestatus)
  13072. {
  13073. unsigned *why;
  13074. int channel;
  13075. int trunkgroup;
  13076. int x, y, fd = a->fd;
  13077. int interfaceid = 0;
  13078. char db_chan_name[20], db_answer[5];
  13079. struct dahdi_pvt *tmp;
  13080. struct dahdi_pri *pri;
  13081. if (a->argc < 5 || a->argc > 6)
  13082. return CLI_SHOWUSAGE;
  13083. if (strchr(a->argv[4], ':')) {
  13084. if (sscanf(a->argv[4], "%30d:%30d", &trunkgroup, &channel) != 2)
  13085. return CLI_SHOWUSAGE;
  13086. if ((trunkgroup < 1) || (channel < 1))
  13087. return CLI_SHOWUSAGE;
  13088. pri = NULL;
  13089. for (x=0;x<NUM_SPANS;x++) {
  13090. if (pris[x].pri.trunkgroup == trunkgroup) {
  13091. pri = pris + x;
  13092. break;
  13093. }
  13094. }
  13095. if (!pri) {
  13096. ast_cli(fd, "No such trunk group %d\n", trunkgroup);
  13097. return CLI_FAILURE;
  13098. }
  13099. } else
  13100. channel = atoi(a->argv[4]);
  13101. if (a->argc == 6)
  13102. interfaceid = atoi(a->argv[5]);
  13103. /* either servicing a D-Channel */
  13104. for (x = 0; x < NUM_SPANS; x++) {
  13105. for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
  13106. if (pris[x].dchannels[y] == channel) {
  13107. pri = pris + x;
  13108. if (pri->pri.enable_service_message_support) {
  13109. ast_mutex_lock(&pri->pri.lock);
  13110. pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus);
  13111. ast_mutex_unlock(&pri->pri.lock);
  13112. } else {
  13113. ast_cli(fd,
  13114. "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
  13115. "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
  13116. }
  13117. return CLI_SUCCESS;
  13118. }
  13119. }
  13120. }
  13121. /* or servicing a B-Channel */
  13122. ast_mutex_lock(&iflock);
  13123. for (tmp = iflist; tmp; tmp = tmp->next) {
  13124. if (tmp->pri && tmp->channel == channel) {
  13125. ast_mutex_unlock(&iflock);
  13126. ast_mutex_lock(&tmp->pri->lock);
  13127. if (!tmp->pri->enable_service_message_support) {
  13128. ast_mutex_unlock(&tmp->pri->lock);
  13129. ast_cli(fd,
  13130. "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
  13131. "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
  13132. return CLI_SUCCESS;
  13133. }
  13134. snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, channel);
  13135. why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status;
  13136. switch(changestatus) {
  13137. case 0: /* enable */
  13138. /* Near end wants to be in service now. */
  13139. ast_db_del(db_chan_name, SRVST_DBKEY);
  13140. *why &= ~SRVST_NEAREND;
  13141. if (*why) {
  13142. snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why);
  13143. ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
  13144. } else {
  13145. dahdi_pri_update_span_devstate(tmp->pri);
  13146. }
  13147. break;
  13148. /* case 1: -- loop */
  13149. case 2: /* disable */
  13150. /* Near end wants to be out-of-service now. */
  13151. ast_db_del(db_chan_name, SRVST_DBKEY);
  13152. *why |= SRVST_NEAREND;
  13153. snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why);
  13154. ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
  13155. dahdi_pri_update_span_devstate(tmp->pri);
  13156. break;
  13157. /* case 3: -- continuity */
  13158. /* case 4: -- shutdown */
  13159. default:
  13160. ast_log(LOG_WARNING, "Unsupported changestatus: '%d'\n", changestatus);
  13161. break;
  13162. }
  13163. pri_maintenance_bservice(tmp->pri->pri, tmp->sig_pvt, changestatus);
  13164. ast_mutex_unlock(&tmp->pri->lock);
  13165. return CLI_SUCCESS;
  13166. }
  13167. }
  13168. ast_mutex_unlock(&iflock);
  13169. ast_cli(fd, "Unable to find given channel %d, possibly not a PRI\n", channel);
  13170. return CLI_FAILURE;
  13171. }
  13172. static char *handle_pri_service_enable_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13173. {
  13174. switch (cmd) {
  13175. case CLI_INIT:
  13176. e->command = "pri service enable channel";
  13177. e->usage =
  13178. "Usage: pri service enable channel <channel> [<interface id>]\n"
  13179. " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
  13180. " to restore a channel to service, with optional interface id\n"
  13181. " as agreed upon with remote switch operator\n";
  13182. return NULL;
  13183. case CLI_GENERATE:
  13184. return NULL;
  13185. }
  13186. return handle_pri_service_generic(e, cmd, a, 0);
  13187. }
  13188. static char *handle_pri_service_disable_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13189. {
  13190. switch (cmd) {
  13191. case CLI_INIT:
  13192. e->command = "pri service disable channel";
  13193. e->usage =
  13194. "Usage: pri service disable channel <chan num> [<interface id>]\n"
  13195. " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
  13196. " to remove a channel from service, with optional interface id\n"
  13197. " as agreed upon with remote switch operator\n";
  13198. return NULL;
  13199. case CLI_GENERATE:
  13200. return NULL;
  13201. }
  13202. return handle_pri_service_generic(e, cmd, a, 2);
  13203. }
  13204. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  13205. #endif /* defined(HAVE_PRI) */
  13206. #if defined(HAVE_PRI)
  13207. static char *handle_pri_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13208. {
  13209. int span;
  13210. switch (cmd) {
  13211. case CLI_INIT:
  13212. e->command = "pri show channels";
  13213. e->usage =
  13214. "Usage: pri show channels\n"
  13215. " Displays PRI channel information such as the current mapping\n"
  13216. " of DAHDI B channels to Asterisk channel names and which calls\n"
  13217. " are on hold or call-waiting. Calls on hold or call-waiting\n"
  13218. " are not associated with any B channel.\n";
  13219. return NULL;
  13220. case CLI_GENERATE:
  13221. return NULL;
  13222. }
  13223. if (a->argc != 3)
  13224. return CLI_SHOWUSAGE;
  13225. sig_pri_cli_show_channels_header(a->fd);
  13226. for (span = 0; span < NUM_SPANS; ++span) {
  13227. if (pris[span].pri.pri) {
  13228. sig_pri_cli_show_channels(a->fd, &pris[span].pri);
  13229. }
  13230. }
  13231. return CLI_SUCCESS;
  13232. }
  13233. #endif /* defined(HAVE_PRI) */
  13234. #if defined(HAVE_PRI)
  13235. static char *handle_pri_show_spans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13236. {
  13237. int span;
  13238. switch (cmd) {
  13239. case CLI_INIT:
  13240. e->command = "pri show spans";
  13241. e->usage =
  13242. "Usage: pri show spans\n"
  13243. " Displays PRI span information\n";
  13244. return NULL;
  13245. case CLI_GENERATE:
  13246. return NULL;
  13247. }
  13248. if (a->argc != 3)
  13249. return CLI_SHOWUSAGE;
  13250. for (span = 0; span < NUM_SPANS; span++) {
  13251. if (pris[span].pri.pri) {
  13252. sig_pri_cli_show_spans(a->fd, span + 1, &pris[span].pri);
  13253. }
  13254. }
  13255. return CLI_SUCCESS;
  13256. }
  13257. #endif /* defined(HAVE_PRI) */
  13258. #if defined(HAVE_PRI)
  13259. #define container_of(ptr, type, member) \
  13260. ((type *)((char *)(ptr) - offsetof(type, member)))
  13261. /*!
  13262. * \internal
  13263. * \brief Destroy a D-Channel of a PRI span
  13264. * \since 12
  13265. *
  13266. * \param pri the pri span
  13267. *
  13268. * Shuts down a span and destroys its D-Channel. Further destruction
  13269. * of the B-channels using dahdi_destroy_channel() would probably be required
  13270. * for the B-Channels.
  13271. */
  13272. static void pri_destroy_span(struct sig_pri_span *pri)
  13273. {
  13274. int i;
  13275. int res;
  13276. int cancel_code;
  13277. struct dahdi_pri* dahdi_pri;
  13278. pthread_t master = pri->master;
  13279. if (!master || (master == AST_PTHREADT_NULL)) {
  13280. return;
  13281. }
  13282. ast_debug(2, "About to destroy DAHDI channels of span %d.\n", pri->span);
  13283. for (i = 0; i < pri->numchans; i++) {
  13284. int channel;
  13285. struct sig_pri_chan *pvt = pri->pvts[i];
  13286. if (!pvt) {
  13287. continue;
  13288. }
  13289. channel = pvt->channel;
  13290. ast_debug(2, "About to destroy B-channel %d.\n", channel);
  13291. dahdi_destroy_channel_range(channel, channel);
  13292. }
  13293. cancel_code = pthread_cancel(master);
  13294. pthread_kill(master, SIGURG);
  13295. ast_debug(4,
  13296. "Waiting to join thread of span %d "
  13297. "with pid=%p cancel_code=%d\n",
  13298. pri->span, (void *)master, cancel_code);
  13299. res = pthread_join(master, NULL);
  13300. if (res != 0) {
  13301. ast_log(LOG_NOTICE, "pthread_join failed: %d\n", res);
  13302. }
  13303. pri->master = AST_PTHREADT_NULL;
  13304. /* The 'struct dahdi_pri' that contains our 'struct sig_pri_span' */
  13305. dahdi_pri = container_of(pri, struct dahdi_pri, pri);
  13306. for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
  13307. ast_debug(4, "closing pri_fd %d\n", i);
  13308. dahdi_close_pri_fd(dahdi_pri, i);
  13309. dahdi_pri->dchannels[i] = 0;
  13310. }
  13311. sig_pri_init_pri(pri);
  13312. ast_debug(1, "PRI span %d destroyed\n", pri->span);
  13313. }
  13314. static char *handle_pri_destroy_span(struct ast_cli_entry *e, int cmd,
  13315. struct ast_cli_args *a)
  13316. {
  13317. int span;
  13318. int res;
  13319. struct sig_pri_span *pri;
  13320. switch (cmd) {
  13321. case CLI_INIT:
  13322. e->command = "pri destroy span";
  13323. e->usage =
  13324. "Usage: pri destroy span <span>\n"
  13325. " Destorys D-channel of span and its B-channels.\n"
  13326. " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
  13327. return NULL;
  13328. case CLI_GENERATE:
  13329. return complete_span_4(a->line, a->word, a->pos, a->n);
  13330. }
  13331. if (a->argc < 4) {
  13332. return CLI_SHOWUSAGE;
  13333. }
  13334. res = sscanf(a->argv[3], "%30d", &span);
  13335. if ((res != 1) || span < 1 || span > NUM_SPANS) {
  13336. ast_cli(a->fd,
  13337. "Invalid span '%s'. Should be a number from %d to %d\n",
  13338. a->argv[3], 1, NUM_SPANS);
  13339. return CLI_SUCCESS;
  13340. }
  13341. pri = &pris[span - 1].pri;
  13342. if (!pri->pri) {
  13343. ast_cli(a->fd, "No PRI running on span %d\n", span);
  13344. return CLI_SUCCESS;
  13345. }
  13346. pri_destroy_span(pri);
  13347. return CLI_SUCCESS;
  13348. }
  13349. #endif /* defined(HAVE_PRI) */
  13350. #if defined(HAVE_PRI)
  13351. static char *handle_pri_show_span(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13352. {
  13353. int span;
  13354. switch (cmd) {
  13355. case CLI_INIT:
  13356. e->command = "pri show span";
  13357. e->usage =
  13358. "Usage: pri show span <span>\n"
  13359. " Displays PRI Information on a given PRI span\n";
  13360. return NULL;
  13361. case CLI_GENERATE:
  13362. return complete_span_4(a->line, a->word, a->pos, a->n);
  13363. }
  13364. if (a->argc < 4)
  13365. return CLI_SHOWUSAGE;
  13366. span = atoi(a->argv[3]);
  13367. if ((span < 1) || (span > NUM_SPANS)) {
  13368. ast_cli(a->fd, "Invalid span '%s'. Should be a number from %d to %d\n", a->argv[3], 1, NUM_SPANS);
  13369. return CLI_SUCCESS;
  13370. }
  13371. if (!pris[span-1].pri.pri) {
  13372. ast_cli(a->fd, "No PRI running on span %d\n", span);
  13373. return CLI_SUCCESS;
  13374. }
  13375. sig_pri_cli_show_span(a->fd, pris[span-1].dchannels, &pris[span-1].pri);
  13376. return CLI_SUCCESS;
  13377. }
  13378. #endif /* defined(HAVE_PRI) */
  13379. #if defined(HAVE_PRI)
  13380. static char *handle_pri_show_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13381. {
  13382. int x;
  13383. int span;
  13384. int count=0;
  13385. int debug;
  13386. switch (cmd) {
  13387. case CLI_INIT:
  13388. e->command = "pri show debug";
  13389. e->usage =
  13390. "Usage: pri show debug\n"
  13391. " Show the debug state of pri spans\n";
  13392. return NULL;
  13393. case CLI_GENERATE:
  13394. return NULL;
  13395. }
  13396. for (span = 0; span < NUM_SPANS; span++) {
  13397. if (pris[span].pri.pri) {
  13398. for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
  13399. if (pris[span].pri.dchans[x]) {
  13400. debug = pri_get_debug(pris[span].pri.dchans[x]);
  13401. ast_cli(a->fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
  13402. count++;
  13403. }
  13404. }
  13405. }
  13406. }
  13407. ast_mutex_lock(&pridebugfdlock);
  13408. if (pridebugfd >= 0)
  13409. ast_cli(a->fd, "Logging PRI debug to file %s\n", pridebugfilename);
  13410. ast_mutex_unlock(&pridebugfdlock);
  13411. if (!count)
  13412. ast_cli(a->fd, "No PRI running\n");
  13413. return CLI_SUCCESS;
  13414. }
  13415. #endif /* defined(HAVE_PRI) */
  13416. #if defined(HAVE_PRI)
  13417. static char *handle_pri_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13418. {
  13419. switch (cmd) {
  13420. case CLI_INIT:
  13421. e->command = "pri show version";
  13422. e->usage =
  13423. "Usage: pri show version\n"
  13424. "Show libpri version information\n";
  13425. return NULL;
  13426. case CLI_GENERATE:
  13427. return NULL;
  13428. }
  13429. ast_cli(a->fd, "libpri version: %s\n", pri_get_version());
  13430. return CLI_SUCCESS;
  13431. }
  13432. #endif /* defined(HAVE_PRI) */
  13433. #if defined(HAVE_PRI)
  13434. static struct ast_cli_entry dahdi_pri_cli[] = {
  13435. AST_CLI_DEFINE(handle_pri_debug, "Enables PRI debugging on a span"),
  13436. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  13437. AST_CLI_DEFINE(handle_pri_service_enable_channel, "Return a channel to service"),
  13438. AST_CLI_DEFINE(handle_pri_service_disable_channel, "Remove a channel from service"),
  13439. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  13440. AST_CLI_DEFINE(handle_pri_show_channels, "Displays PRI channel information"),
  13441. AST_CLI_DEFINE(handle_pri_show_spans, "Displays PRI span information"),
  13442. AST_CLI_DEFINE(handle_pri_show_span, "Displays PRI span information"),
  13443. AST_CLI_DEFINE(handle_pri_destroy_span, "Destroy a PRI span"),
  13444. AST_CLI_DEFINE(handle_pri_show_debug, "Displays current PRI debug settings"),
  13445. AST_CLI_DEFINE(handle_pri_set_debug_file, "Sends PRI debug output to the specified file"),
  13446. AST_CLI_DEFINE(handle_pri_version, "Displays libpri version"),
  13447. };
  13448. #endif /* defined(HAVE_PRI) */
  13449. #ifdef HAVE_OPENR2
  13450. static char *handle_mfcr2_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13451. {
  13452. switch (cmd) {
  13453. case CLI_INIT:
  13454. e->command = "mfcr2 show version";
  13455. e->usage =
  13456. "Usage: mfcr2 show version\n"
  13457. " Shows the version of the OpenR2 library being used.\n";
  13458. return NULL;
  13459. case CLI_GENERATE:
  13460. return NULL;
  13461. }
  13462. ast_cli(a->fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
  13463. return CLI_SUCCESS;
  13464. }
  13465. static char *handle_mfcr2_show_variants(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13466. {
  13467. #define FORMAT "%4s %40s\n"
  13468. int i = 0;
  13469. int numvariants = 0;
  13470. const openr2_variant_entry_t *variants;
  13471. switch (cmd) {
  13472. case CLI_INIT:
  13473. e->command = "mfcr2 show variants";
  13474. e->usage =
  13475. "Usage: mfcr2 show variants\n"
  13476. " Shows the list of MFC/R2 variants supported.\n";
  13477. return NULL;
  13478. case CLI_GENERATE:
  13479. return NULL;
  13480. }
  13481. if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
  13482. ast_cli(a->fd, "Failed to get list of variants.\n");
  13483. return CLI_FAILURE;
  13484. }
  13485. ast_cli(a->fd, FORMAT, "Variant Code", "Country");
  13486. for (i = 0; i < numvariants; i++) {
  13487. ast_cli(a->fd, FORMAT, variants[i].name, variants[i].country);
  13488. }
  13489. return CLI_SUCCESS;
  13490. #undef FORMAT
  13491. }
  13492. static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13493. {
  13494. #define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
  13495. int filtertype = 0;
  13496. int targetnum = 0;
  13497. char channo[5];
  13498. char anino[5];
  13499. char dnisno[5];
  13500. struct dahdi_pvt *p;
  13501. openr2_context_t *r2context;
  13502. openr2_variant_t r2variant;
  13503. switch (cmd) {
  13504. case CLI_INIT:
  13505. e->command = "mfcr2 show channels [group|context]";
  13506. e->usage =
  13507. "Usage: mfcr2 show channels [group <group> | context <context>]\n"
  13508. " Shows the DAHDI channels configured with MFC/R2 signaling.\n";
  13509. return NULL;
  13510. case CLI_GENERATE:
  13511. return NULL;
  13512. }
  13513. if (!((a->argc == 3) || (a->argc == 5))) {
  13514. return CLI_SHOWUSAGE;
  13515. }
  13516. if (a->argc == 5) {
  13517. if (!strcasecmp(a->argv[3], "group")) {
  13518. targetnum = atoi(a->argv[4]);
  13519. if ((targetnum < 0) || (targetnum > 63))
  13520. return CLI_SHOWUSAGE;
  13521. targetnum = 1 << targetnum;
  13522. filtertype = 1;
  13523. } else if (!strcasecmp(a->argv[3], "context")) {
  13524. filtertype = 2;
  13525. } else {
  13526. return CLI_SHOWUSAGE;
  13527. }
  13528. }
  13529. ast_cli(a->fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS");
  13530. ast_mutex_lock(&iflock);
  13531. for (p = iflist; p; p = p->next) {
  13532. if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
  13533. continue;
  13534. }
  13535. if (filtertype) {
  13536. switch(filtertype) {
  13537. case 1: /* mfcr2 show channels group <group> */
  13538. if (p->group != targetnum) {
  13539. continue;
  13540. }
  13541. break;
  13542. case 2: /* mfcr2 show channels context <context> */
  13543. if (strcasecmp(p->context, a->argv[4])) {
  13544. continue;
  13545. }
  13546. break;
  13547. default:
  13548. ;
  13549. }
  13550. }
  13551. r2context = openr2_chan_get_context(p->r2chan);
  13552. r2variant = openr2_context_get_variant(r2context);
  13553. snprintf(channo, sizeof(channo), "%d", p->channel);
  13554. snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context));
  13555. snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context));
  13556. ast_cli(a->fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant),
  13557. anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No",
  13558. openr2_context_get_immediate_accept(r2context) ? "Yes" : "No",
  13559. openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
  13560. }
  13561. ast_mutex_unlock(&iflock);
  13562. return CLI_SUCCESS;
  13563. #undef FORMAT
  13564. }
  13565. static char *handle_mfcr2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13566. {
  13567. struct dahdi_pvt *p = NULL;
  13568. int channo = 0;
  13569. char *toklevel = NULL;
  13570. char *saveptr = NULL;
  13571. char *logval = NULL;
  13572. openr2_log_level_t loglevel = OR2_LOG_NOTHING;
  13573. openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
  13574. switch (cmd) {
  13575. case CLI_INIT:
  13576. e->command = "mfcr2 set debug";
  13577. e->usage =
  13578. "Usage: mfcr2 set debug <loglevel> <channel>\n"
  13579. " Set a new logging level for the specified channel.\n"
  13580. " If no channel is specified the logging level will be applied to all channels.\n";
  13581. return NULL;
  13582. case CLI_GENERATE:
  13583. return NULL;
  13584. }
  13585. if (a->argc < 4) {
  13586. return CLI_SHOWUSAGE;
  13587. }
  13588. channo = (a->argc == 5) ? atoi(a->argv[4]) : -1;
  13589. logval = ast_strdupa(a->argv[3]);
  13590. toklevel = strtok_r(logval, ",", &saveptr);
  13591. if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
  13592. ast_cli(a->fd, "Invalid MFC/R2 logging level '%s'.\n", a->argv[3]);
  13593. return CLI_FAILURE;
  13594. } else if (OR2_LOG_NOTHING == tmplevel) {
  13595. loglevel = tmplevel;
  13596. } else {
  13597. loglevel |= tmplevel;
  13598. while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
  13599. if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
  13600. ast_cli(a->fd, "Ignoring invalid logging level: '%s'.\n", toklevel);
  13601. continue;
  13602. }
  13603. loglevel |= tmplevel;
  13604. }
  13605. }
  13606. ast_mutex_lock(&iflock);
  13607. for (p = iflist; p; p = p->next) {
  13608. if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
  13609. continue;
  13610. }
  13611. if ((channo != -1) && (p->channel != channo )) {
  13612. continue;
  13613. }
  13614. openr2_chan_set_log_level(p->r2chan, loglevel);
  13615. if (channo != -1) {
  13616. ast_cli(a->fd, "MFC/R2 debugging set to '%s' for channel %d.\n", a->argv[3], p->channel);
  13617. break;
  13618. }
  13619. }
  13620. if ((channo != -1) && !p) {
  13621. ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
  13622. }
  13623. if (channo == -1) {
  13624. ast_cli(a->fd, "MFC/R2 debugging set to '%s' for all channels.\n", a->argv[3]);
  13625. }
  13626. ast_mutex_unlock(&iflock);
  13627. return CLI_SUCCESS;
  13628. }
  13629. static char *handle_mfcr2_call_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13630. {
  13631. struct dahdi_pvt *p = NULL;
  13632. int channo = 0;
  13633. switch (cmd) {
  13634. case CLI_INIT:
  13635. e->command = "mfcr2 call files [on|off]";
  13636. e->usage =
  13637. "Usage: mfcr2 call files [on|off] <channel>\n"
  13638. " Enable call files creation on the specified channel.\n"
  13639. " If no channel is specified call files creation policy will be applied to all channels.\n";
  13640. return NULL;
  13641. case CLI_GENERATE:
  13642. return NULL;
  13643. }
  13644. if (a->argc < 4) {
  13645. return CLI_SHOWUSAGE;
  13646. }
  13647. channo = (a->argc == 5) ? atoi(a->argv[4]) : -1;
  13648. ast_mutex_lock(&iflock);
  13649. for (p = iflist; p; p = p->next) {
  13650. if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
  13651. continue;
  13652. }
  13653. if ((channo != -1) && (p->channel != channo )) {
  13654. continue;
  13655. }
  13656. if (ast_true(a->argv[3])) {
  13657. openr2_chan_enable_call_files(p->r2chan);
  13658. } else {
  13659. openr2_chan_disable_call_files(p->r2chan);
  13660. }
  13661. if (channo != -1) {
  13662. if (ast_true(a->argv[3])) {
  13663. ast_cli(a->fd, "MFC/R2 call files enabled for channel %d.\n", p->channel);
  13664. } else {
  13665. ast_cli(a->fd, "MFC/R2 call files disabled for channel %d.\n", p->channel);
  13666. }
  13667. break;
  13668. }
  13669. }
  13670. if ((channo != -1) && !p) {
  13671. ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
  13672. }
  13673. if (channo == -1) {
  13674. if (ast_true(a->argv[3])) {
  13675. ast_cli(a->fd, "MFC/R2 Call files enabled for all channels.\n");
  13676. } else {
  13677. ast_cli(a->fd, "MFC/R2 Call files disabled for all channels.\n");
  13678. }
  13679. }
  13680. ast_mutex_unlock(&iflock);
  13681. return CLI_SUCCESS;
  13682. }
  13683. static char *handle_mfcr2_set_idle(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13684. {
  13685. struct dahdi_pvt *p = NULL;
  13686. int channo = 0;
  13687. switch (cmd) {
  13688. case CLI_INIT:
  13689. e->command = "mfcr2 set idle";
  13690. e->usage =
  13691. "Usage: mfcr2 set idle <channel>\n"
  13692. " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
  13693. " Force the given channel into IDLE state.\n"
  13694. " If no channel is specified, all channels will be set to IDLE.\n";
  13695. return NULL;
  13696. case CLI_GENERATE:
  13697. return NULL;
  13698. }
  13699. channo = (a->argc == 4) ? atoi(a->argv[3]) : -1;
  13700. ast_mutex_lock(&iflock);
  13701. for (p = iflist; p; p = p->next) {
  13702. if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
  13703. continue;
  13704. }
  13705. if ((channo != -1) && (p->channel != channo )) {
  13706. continue;
  13707. }
  13708. openr2_chan_set_idle(p->r2chan);
  13709. ast_mutex_lock(&p->lock);
  13710. p->locallyblocked = 0;
  13711. p->mfcr2call = 0;
  13712. ast_mutex_unlock(&p->lock);
  13713. if (channo != -1) {
  13714. break;
  13715. }
  13716. }
  13717. if ((channo != -1) && !p) {
  13718. ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
  13719. }
  13720. ast_mutex_unlock(&iflock);
  13721. return CLI_SUCCESS;
  13722. }
  13723. static char *handle_mfcr2_set_blocked(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13724. {
  13725. struct dahdi_pvt *p = NULL;
  13726. int channo = 0;
  13727. switch (cmd) {
  13728. case CLI_INIT:
  13729. e->command = "mfcr2 set blocked";
  13730. e->usage =
  13731. "Usage: mfcr2 set blocked <channel>\n"
  13732. " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
  13733. " Force the given channel into BLOCKED state.\n"
  13734. " If no channel is specified, all channels will be set to BLOCKED.\n";
  13735. return NULL;
  13736. case CLI_GENERATE:
  13737. return NULL;
  13738. }
  13739. channo = (a->argc == 4) ? atoi(a->argv[3]) : -1;
  13740. ast_mutex_lock(&iflock);
  13741. for (p = iflist; p; p = p->next) {
  13742. if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
  13743. continue;
  13744. }
  13745. if ((channo != -1) && (p->channel != channo )) {
  13746. continue;
  13747. }
  13748. openr2_chan_set_blocked(p->r2chan);
  13749. ast_mutex_lock(&p->lock);
  13750. p->locallyblocked = 1;
  13751. ast_mutex_unlock(&p->lock);
  13752. if (channo != -1) {
  13753. break;
  13754. }
  13755. }
  13756. if ((channo != -1) && !p) {
  13757. ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
  13758. }
  13759. ast_mutex_unlock(&iflock);
  13760. return CLI_SUCCESS;
  13761. }
  13762. static struct ast_cli_entry dahdi_mfcr2_cli[] = {
  13763. AST_CLI_DEFINE(handle_mfcr2_version, "Show OpenR2 library version"),
  13764. AST_CLI_DEFINE(handle_mfcr2_show_variants, "Show supported MFC/R2 variants"),
  13765. AST_CLI_DEFINE(handle_mfcr2_show_channels, "Show MFC/R2 channels"),
  13766. AST_CLI_DEFINE(handle_mfcr2_set_debug, "Set MFC/R2 channel logging level"),
  13767. AST_CLI_DEFINE(handle_mfcr2_call_files, "Enable/Disable MFC/R2 call files"),
  13768. AST_CLI_DEFINE(handle_mfcr2_set_idle, "Reset MFC/R2 channel forcing it to IDLE"),
  13769. AST_CLI_DEFINE(handle_mfcr2_set_blocked, "Reset MFC/R2 channel forcing it to BLOCKED"),
  13770. };
  13771. #endif /* HAVE_OPENR2 */
  13772. static char *dahdi_destroy_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13773. {
  13774. int start;
  13775. int end;
  13776. switch (cmd) {
  13777. case CLI_INIT:
  13778. e->command = "dahdi destroy channels";
  13779. e->usage =
  13780. "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
  13781. " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
  13782. return NULL;
  13783. case CLI_GENERATE:
  13784. return NULL;
  13785. }
  13786. if ((a->argc < 4) || a->argc > 5) {
  13787. return CLI_SHOWUSAGE;
  13788. }
  13789. start = atoi(a->argv[3]);
  13790. if (start < 1) {
  13791. ast_cli(a->fd, "Invalid starting channel number %s.\n",
  13792. a->argv[4]);
  13793. return CLI_FAILURE;
  13794. }
  13795. if (a->argc == 5) {
  13796. end = atoi(a->argv[4]);
  13797. if (end < 1) {
  13798. ast_cli(a->fd, "Invalid ending channel number %s.\n",
  13799. a->argv[4]);
  13800. return CLI_FAILURE;
  13801. }
  13802. } else {
  13803. end = start;
  13804. }
  13805. if (end < start) {
  13806. ast_cli(a->fd,
  13807. "range end (%d) is smaller than range start (%d)\n",
  13808. end, start);
  13809. return CLI_FAILURE;
  13810. }
  13811. dahdi_destroy_channel_range(start, end);
  13812. return CLI_SUCCESS;
  13813. }
  13814. static char *dahdi_create_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13815. {
  13816. int start;
  13817. int end;
  13818. int ret;
  13819. switch (cmd) {
  13820. case CLI_INIT:
  13821. e->command = "dahdi create channels";
  13822. e->usage = "Usage: dahdi create channels <from> [<to>] - a range of channels\n"
  13823. " dahdi create channels new - add channels not yet created\n"
  13824. "For ISDN and SS7 the range should include complete spans.\n";
  13825. return NULL;
  13826. case CLI_GENERATE:
  13827. return NULL;
  13828. }
  13829. if ((a->argc < 4) || a->argc > 5) {
  13830. return CLI_SHOWUSAGE;
  13831. }
  13832. if (a->argc == 4 && !strcmp(a->argv[3], "new")) {
  13833. ret = dahdi_create_channel_range(0, 0);
  13834. return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
  13835. }
  13836. start = atoi(a->argv[3]);
  13837. if (start <= 0) {
  13838. ast_cli(a->fd, "Invalid starting channel number '%s'.\n",
  13839. a->argv[3]);
  13840. return CLI_FAILURE;
  13841. }
  13842. if (a->argc == 5) {
  13843. end = atoi(a->argv[4]);
  13844. if (end <= 0) {
  13845. ast_cli(a->fd, "Invalid ending channel number '%s'.\n",
  13846. a->argv[4]);
  13847. return CLI_FAILURE;
  13848. }
  13849. } else {
  13850. end = start;
  13851. }
  13852. if (end < start) {
  13853. ast_cli(a->fd,
  13854. "range end (%d) is smaller than range start (%d)\n",
  13855. end, start);
  13856. return CLI_FAILURE;
  13857. }
  13858. ret = dahdi_create_channel_range(start, end);
  13859. return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
  13860. }
  13861. static void dahdi_softhangup_all(void)
  13862. {
  13863. struct dahdi_pvt *p;
  13864. retry:
  13865. ast_mutex_lock(&iflock);
  13866. for (p = iflist; p; p = p->next) {
  13867. ast_mutex_lock(&p->lock);
  13868. if (p->owner && !p->restartpending) {
  13869. if (ast_channel_trylock(p->owner)) {
  13870. if (option_debug > 2)
  13871. ast_verbose("Avoiding deadlock\n");
  13872. /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
  13873. ast_mutex_unlock(&p->lock);
  13874. ast_mutex_unlock(&iflock);
  13875. goto retry;
  13876. }
  13877. if (option_debug > 2)
  13878. ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner));
  13879. ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
  13880. p->restartpending = 1;
  13881. num_restart_pending++;
  13882. ast_channel_unlock(p->owner);
  13883. }
  13884. ast_mutex_unlock(&p->lock);
  13885. }
  13886. ast_mutex_unlock(&iflock);
  13887. }
  13888. static int dahdi_restart(void)
  13889. {
  13890. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  13891. int i, j;
  13892. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  13893. int cancel_code;
  13894. struct dahdi_pvt *p;
  13895. ast_mutex_lock(&restart_lock);
  13896. ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
  13897. dahdi_softhangup_all();
  13898. ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n");
  13899. #ifdef HAVE_OPENR2
  13900. dahdi_r2_destroy_links();
  13901. #endif
  13902. #if defined(HAVE_PRI)
  13903. for (i = 0; i < NUM_SPANS; i++) {
  13904. if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
  13905. cancel_code = pthread_cancel(pris[i].pri.master);
  13906. pthread_kill(pris[i].pri.master, SIGURG);
  13907. ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].pri.master, cancel_code);
  13908. pthread_join(pris[i].pri.master, NULL);
  13909. ast_debug(4, "Joined thread of span %d\n", i);
  13910. }
  13911. }
  13912. #endif
  13913. #if defined(HAVE_SS7)
  13914. for (i = 0; i < NUM_SPANS; i++) {
  13915. if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
  13916. cancel_code = pthread_cancel(linksets[i].ss7.master);
  13917. pthread_kill(linksets[i].ss7.master, SIGURG);
  13918. ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) linksets[i].ss7.master, cancel_code);
  13919. pthread_join(linksets[i].ss7.master, NULL);
  13920. ast_debug(4, "Joined thread of span %d\n", i);
  13921. }
  13922. }
  13923. #endif /* defined(HAVE_SS7) */
  13924. ast_mutex_lock(&monlock);
  13925. if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
  13926. cancel_code = pthread_cancel(monitor_thread);
  13927. pthread_kill(monitor_thread, SIGURG);
  13928. ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
  13929. pthread_join(monitor_thread, NULL);
  13930. ast_debug(4, "Joined monitor thread\n");
  13931. }
  13932. monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
  13933. ast_mutex_lock(&ss_thread_lock);
  13934. while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
  13935. int x = DAHDI_FLASH;
  13936. ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count);
  13937. ast_mutex_lock(&iflock);
  13938. for (p = iflist; p; p = p->next) {
  13939. if (p->owner) {
  13940. /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
  13941. ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
  13942. }
  13943. }
  13944. ast_mutex_unlock(&iflock);
  13945. ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
  13946. }
  13947. /* ensure any created channels before monitor threads were stopped are hungup */
  13948. dahdi_softhangup_all();
  13949. ast_verb(4, "Final softhangup of all DAHDI channels complete.\n");
  13950. destroy_all_channels();
  13951. memset(round_robin, 0, sizeof(round_robin));
  13952. ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
  13953. ast_mutex_unlock(&monlock);
  13954. #ifdef HAVE_PRI
  13955. for (i = 0; i < NUM_SPANS; i++) {
  13956. for (j = 0; j < SIG_PRI_NUM_DCHANS; j++)
  13957. dahdi_close_pri_fd(&(pris[i]), j);
  13958. }
  13959. memset(pris, 0, sizeof(pris));
  13960. for (i = 0; i < NUM_SPANS; i++) {
  13961. sig_pri_init_pri(&pris[i].pri);
  13962. }
  13963. pri_set_error(dahdi_pri_error);
  13964. pri_set_message(dahdi_pri_message);
  13965. #endif
  13966. #if defined(HAVE_SS7)
  13967. for (i = 0; i < NUM_SPANS; i++) {
  13968. for (j = 0; j < SIG_SS7_NUM_DCHANS; j++)
  13969. dahdi_close_ss7_fd(&(linksets[i]), j);
  13970. }
  13971. memset(linksets, 0, sizeof(linksets));
  13972. for (i = 0; i < NUM_SPANS; i++) {
  13973. sig_ss7_init_linkset(&linksets[i].ss7);
  13974. }
  13975. ss7_set_error(dahdi_ss7_error);
  13976. ss7_set_message(dahdi_ss7_message);
  13977. ss7_set_hangup(sig_ss7_cb_hangup);
  13978. ss7_set_notinservice(sig_ss7_cb_notinservice);
  13979. ss7_set_call_null(sig_ss7_cb_call_null);
  13980. #endif /* defined(HAVE_SS7) */
  13981. if (setup_dahdi(2) != 0) {
  13982. ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
  13983. ast_mutex_unlock(&ss_thread_lock);
  13984. return 1;
  13985. }
  13986. ast_mutex_unlock(&ss_thread_lock);
  13987. ast_mutex_unlock(&restart_lock);
  13988. return 0;
  13989. }
  13990. static char *dahdi_restart_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  13991. {
  13992. switch (cmd) {
  13993. case CLI_INIT:
  13994. e->command = "dahdi restart";
  13995. e->usage =
  13996. "Usage: dahdi restart\n"
  13997. " Restarts the DAHDI channels: destroys them all and then\n"
  13998. " re-reads them from chan_dahdi.conf.\n"
  13999. " Note that this will STOP any running CALL on DAHDI channels.\n"
  14000. "";
  14001. return NULL;
  14002. case CLI_GENERATE:
  14003. return NULL;
  14004. }
  14005. if (a->argc != 2)
  14006. return CLI_SHOWUSAGE;
  14007. if (dahdi_restart() != 0)
  14008. return CLI_FAILURE;
  14009. return CLI_SUCCESS;
  14010. }
  14011. static int action_dahdirestart(struct mansession *s, const struct message *m)
  14012. {
  14013. if (dahdi_restart() != 0) {
  14014. astman_send_error(s, m, "Failed rereading DAHDI configuration");
  14015. return 1;
  14016. }
  14017. astman_send_ack(s, m, "DAHDIRestart: Success");
  14018. return 0;
  14019. }
  14020. static char *dahdi_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14021. {
  14022. #define FORMAT "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
  14023. #define FORMAT2 "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
  14024. ast_group_t targetnum = 0;
  14025. int filtertype = 0;
  14026. struct dahdi_pvt *tmp = NULL;
  14027. char tmps[20];
  14028. char blockstr[20];
  14029. switch (cmd) {
  14030. case CLI_INIT:
  14031. e->command = "dahdi show channels [group|context]";
  14032. e->usage =
  14033. "Usage: dahdi show channels [ group <group> | context <context> ]\n"
  14034. " Shows a list of available channels with optional filtering\n"
  14035. " <group> must be a number between 0 and 63\n";
  14036. return NULL;
  14037. case CLI_GENERATE:
  14038. return NULL;
  14039. }
  14040. /* syntax: dahdi show channels [ group <group> | context <context> ] */
  14041. if (!((a->argc == 3) || (a->argc == 5))) {
  14042. return CLI_SHOWUSAGE;
  14043. }
  14044. if (a->argc == 5) {
  14045. if (!strcasecmp(a->argv[3], "group")) {
  14046. targetnum = atoi(a->argv[4]);
  14047. if (63 < targetnum) {
  14048. return CLI_SHOWUSAGE;
  14049. }
  14050. targetnum = ((ast_group_t) 1) << targetnum;
  14051. filtertype = 1;
  14052. } else if (!strcasecmp(a->argv[3], "context")) {
  14053. filtertype = 2;
  14054. }
  14055. }
  14056. ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "In Service", "Description");
  14057. ast_mutex_lock(&iflock);
  14058. for (tmp = iflist; tmp; tmp = tmp->next) {
  14059. if (filtertype) {
  14060. switch(filtertype) {
  14061. case 1: /* dahdi show channels group <group> */
  14062. if (!(tmp->group & targetnum)) {
  14063. continue;
  14064. }
  14065. break;
  14066. case 2: /* dahdi show channels context <context> */
  14067. if (strcasecmp(tmp->context, a->argv[4])) {
  14068. continue;
  14069. }
  14070. break;
  14071. default:
  14072. break;
  14073. }
  14074. }
  14075. if (tmp->channel > 0) {
  14076. snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
  14077. } else {
  14078. ast_copy_string(tmps, "pseudo", sizeof(tmps));
  14079. }
  14080. blockstr[0] = tmp->locallyblocked ? 'L' : ' ';
  14081. blockstr[1] = tmp->remotelyblocked ? 'R' : ' ';
  14082. blockstr[2] = '\0';
  14083. ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, tmp->inservice ? "Yes" : "No", tmp->description);
  14084. }
  14085. ast_mutex_unlock(&iflock);
  14086. return CLI_SUCCESS;
  14087. #undef FORMAT
  14088. #undef FORMAT2
  14089. }
  14090. static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14091. {
  14092. int channel;
  14093. struct dahdi_pvt *tmp = NULL;
  14094. struct dahdi_confinfo ci;
  14095. struct dahdi_params ps;
  14096. int x;
  14097. char hwrxgain[15];
  14098. char hwtxgain[15];
  14099. switch (cmd) {
  14100. case CLI_INIT:
  14101. e->command = "dahdi show channel";
  14102. e->usage =
  14103. "Usage: dahdi show channel <chan num>\n"
  14104. " Detailed information about a given channel\n";
  14105. return NULL;
  14106. case CLI_GENERATE:
  14107. return NULL;
  14108. }
  14109. if (a->argc != 4)
  14110. return CLI_SHOWUSAGE;
  14111. channel = atoi(a->argv[3]);
  14112. ast_mutex_lock(&iflock);
  14113. for (tmp = iflist; tmp; tmp = tmp->next) {
  14114. if (tmp->channel == channel) {
  14115. ast_cli(a->fd, "Channel: %d\n", tmp->channel);
  14116. ast_cli(a->fd, "Description: %s\n", tmp->description);
  14117. ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
  14118. ast_cli(a->fd, "Span: %d\n", tmp->span);
  14119. ast_cli(a->fd, "Extension: %s\n", tmp->exten);
  14120. ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
  14121. ast_cli(a->fd, "Context: %s\n", tmp->context);
  14122. ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num);
  14123. ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton);
  14124. #if defined(HAVE_PRI)
  14125. #if defined(HAVE_PRI_SUBADDR)
  14126. ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr);
  14127. #endif /* defined(HAVE_PRI_SUBADDR) */
  14128. #endif /* defined(HAVE_PRI) */
  14129. ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name);
  14130. ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none"));
  14131. if (tmp->vars) {
  14132. struct ast_variable *v;
  14133. ast_cli(a->fd, "Variables:\n");
  14134. for (v = tmp->vars ; v ; v = v->next)
  14135. ast_cli(a->fd, " %s = %s\n", v->name, v->value);
  14136. }
  14137. ast_cli(a->fd, "Destroy: %d\n", tmp->destroy);
  14138. ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm);
  14139. ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig));
  14140. ast_cli(a->fd, "Radio: %d\n", tmp->radio);
  14141. ast_cli(a->fd, "Owner: %s\n", tmp->owner ? ast_channel_name(tmp->owner) : "<None>");
  14142. ast_cli(a->fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? ast_channel_name(tmp->subs[SUB_REAL].owner) : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
  14143. ast_cli(a->fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? ast_channel_name(tmp->subs[SUB_CALLWAIT].owner) : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
  14144. ast_cli(a->fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? ast_channel_name(tmp->subs[SUB_THREEWAY].owner) : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
  14145. ast_cli(a->fd, "Confno: %d\n", tmp->confno);
  14146. ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno);
  14147. ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference);
  14148. ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
  14149. ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no");
  14150. if (tmp->busydetect) {
  14151. #if defined(BUSYDETECT_TONEONLY)
  14152. ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n");
  14153. #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
  14154. ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
  14155. #endif
  14156. #ifdef BUSYDETECT_DEBUG
  14157. ast_cli(a->fd, " Busy Detector Debug: Enabled\n");
  14158. #endif
  14159. ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount);
  14160. ast_cli(a->fd, " Busy Pattern: %d,%d,%d,%d\n", tmp->busy_cadence.pattern[0], tmp->busy_cadence.pattern[1], (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[2] : 0, (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[3] : 0);
  14161. }
  14162. ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
  14163. ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
  14164. ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
  14165. ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown");
  14166. ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
  14167. ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
  14168. if (tmp->hwrxgain_enabled) {
  14169. snprintf(hwrxgain, sizeof(hwrxgain), "%.1f", tmp->hwrxgain);
  14170. } else {
  14171. ast_copy_string(hwrxgain, "Disabled", sizeof(hwrxgain));
  14172. }
  14173. if (tmp->hwtxgain_enabled) {
  14174. snprintf(hwtxgain, sizeof(hwtxgain), "%.1f", tmp->hwtxgain);
  14175. } else {
  14176. ast_copy_string(hwtxgain, "Disabled", sizeof(hwtxgain));
  14177. }
  14178. ast_cli(a->fd, "HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
  14179. ast_cli(a->fd, "SW Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain);
  14180. ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc);
  14181. ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no");
  14182. ast_cli(a->fd, "Echo Cancellation:\n");
  14183. if (tmp->echocancel.head.tap_length) {
  14184. ast_cli(a->fd, "\t%u taps\n", tmp->echocancel.head.tap_length);
  14185. for (x = 0; x < tmp->echocancel.head.param_count; x++) {
  14186. ast_cli(a->fd, "\t\t%s: %dd\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value);
  14187. }
  14188. ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF");
  14189. } else {
  14190. ast_cli(a->fd, "\tnone\n");
  14191. }
  14192. ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone);
  14193. if (tmp->master)
  14194. ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel);
  14195. for (x = 0; x < MAX_SLAVES; x++) {
  14196. if (tmp->slaves[x])
  14197. ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
  14198. }
  14199. #ifdef HAVE_OPENR2
  14200. if (tmp->mfcr2) {
  14201. char calldir[OR2_MAX_PATH];
  14202. openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
  14203. openr2_variant_t r2variant = openr2_context_get_variant(r2context);
  14204. ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
  14205. ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
  14206. ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
  14207. ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
  14208. ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
  14209. ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
  14210. ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
  14211. ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
  14212. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  14213. ast_cli(a->fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No");
  14214. ast_cli(a->fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No");
  14215. #endif
  14216. ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
  14217. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  14218. ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
  14219. #endif
  14220. ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
  14221. ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
  14222. ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
  14223. ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
  14224. ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
  14225. ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
  14226. ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
  14227. ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
  14228. ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
  14229. ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
  14230. ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
  14231. ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
  14232. }
  14233. #endif
  14234. #if defined(HAVE_SS7)
  14235. if (tmp->ss7) {
  14236. struct sig_ss7_chan *chan = tmp->sig_pvt;
  14237. ast_cli(a->fd, "CIC: %d\n", chan->cic);
  14238. }
  14239. #endif /* defined(HAVE_SS7) */
  14240. #ifdef HAVE_PRI
  14241. if (tmp->pri) {
  14242. struct sig_pri_chan *chan = tmp->sig_pvt;
  14243. ast_cli(a->fd, "PRI Flags: ");
  14244. if (chan->resetting != SIG_PRI_RESET_IDLE) {
  14245. ast_cli(a->fd, "Resetting=%u ", chan->resetting);
  14246. }
  14247. if (chan->call)
  14248. ast_cli(a->fd, "Call ");
  14249. if (chan->allocated) {
  14250. ast_cli(a->fd, "Allocated ");
  14251. }
  14252. ast_cli(a->fd, "\n");
  14253. if (tmp->logicalspan)
  14254. ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan);
  14255. else
  14256. ast_cli(a->fd, "PRI Logical Span: Implicit\n");
  14257. }
  14258. #endif
  14259. memset(&ci, 0, sizeof(ci));
  14260. ps.channo = tmp->channel;
  14261. if (tmp->subs[SUB_REAL].dfd > -1) {
  14262. memset(&ci, 0, sizeof(ci));
  14263. if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
  14264. ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (unsigned)ci.confmode);
  14265. }
  14266. if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
  14267. ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
  14268. }
  14269. memset(&ps, 0, sizeof(ps));
  14270. if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
  14271. ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
  14272. } else {
  14273. ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
  14274. }
  14275. }
  14276. ast_mutex_unlock(&iflock);
  14277. return CLI_SUCCESS;
  14278. }
  14279. }
  14280. ast_mutex_unlock(&iflock);
  14281. ast_cli(a->fd, "Unable to find given channel %d\n", channel);
  14282. return CLI_FAILURE;
  14283. }
  14284. static char *handle_dahdi_show_cadences(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14285. {
  14286. int i, j;
  14287. switch (cmd) {
  14288. case CLI_INIT:
  14289. e->command = "dahdi show cadences";
  14290. e->usage =
  14291. "Usage: dahdi show cadences\n"
  14292. " Shows all cadences currently defined\n";
  14293. return NULL;
  14294. case CLI_GENERATE:
  14295. return NULL;
  14296. }
  14297. for (i = 0; i < num_cadence; i++) {
  14298. char output[1024];
  14299. char tmp[16], tmp2[64];
  14300. snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
  14301. term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
  14302. for (j = 0; j < 16; j++) {
  14303. if (cadences[i].ringcadence[j] == 0)
  14304. break;
  14305. snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
  14306. if (cidrings[i] * 2 - 1 == j)
  14307. term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
  14308. else
  14309. term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
  14310. if (j != 0)
  14311. strncat(output, ",", sizeof(output) - strlen(output) - 1);
  14312. strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
  14313. }
  14314. ast_cli(a->fd,"%s\n",output);
  14315. }
  14316. return CLI_SUCCESS;
  14317. }
  14318. /* Based on irqmiss.c */
  14319. static char *dahdi_show_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14320. {
  14321. #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
  14322. #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
  14323. int span;
  14324. int res;
  14325. char alarmstr[50];
  14326. int ctl;
  14327. struct dahdi_spaninfo s;
  14328. switch (cmd) {
  14329. case CLI_INIT:
  14330. e->command = "dahdi show status";
  14331. e->usage =
  14332. "Usage: dahdi show status\n"
  14333. " Shows a list of DAHDI cards with status\n";
  14334. return NULL;
  14335. case CLI_GENERATE:
  14336. return NULL;
  14337. }
  14338. ctl = open("/dev/dahdi/ctl", O_RDWR);
  14339. if (ctl < 0) {
  14340. ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
  14341. return CLI_FAILURE;
  14342. }
  14343. ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO");
  14344. for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
  14345. s.spanno = span;
  14346. res = ioctl(ctl, DAHDI_SPANSTAT, &s);
  14347. if (res) {
  14348. continue;
  14349. }
  14350. alarmstr[0] = '\0';
  14351. if (s.alarms > 0) {
  14352. if (s.alarms & DAHDI_ALARM_BLUE)
  14353. strcat(alarmstr, "BLU/");
  14354. if (s.alarms & DAHDI_ALARM_YELLOW)
  14355. strcat(alarmstr, "YEL/");
  14356. if (s.alarms & DAHDI_ALARM_RED)
  14357. strcat(alarmstr, "RED/");
  14358. if (s.alarms & DAHDI_ALARM_LOOPBACK)
  14359. strcat(alarmstr, "LB/");
  14360. if (s.alarms & DAHDI_ALARM_RECOVER)
  14361. strcat(alarmstr, "REC/");
  14362. if (s.alarms & DAHDI_ALARM_NOTOPEN)
  14363. strcat(alarmstr, "NOP/");
  14364. if (!strlen(alarmstr))
  14365. strcat(alarmstr, "UUU/");
  14366. if (strlen(alarmstr)) {
  14367. /* Strip trailing / */
  14368. alarmstr[strlen(alarmstr) - 1] = '\0';
  14369. }
  14370. } else {
  14371. if (s.numchans)
  14372. strcpy(alarmstr, "OK");
  14373. else
  14374. strcpy(alarmstr, "UNCONFIGURED");
  14375. }
  14376. ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
  14377. s.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
  14378. s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
  14379. s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
  14380. "CAS",
  14381. s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
  14382. s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
  14383. s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
  14384. "Unk",
  14385. s.lineconfig & DAHDI_CONFIG_CRC4 ?
  14386. s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" :
  14387. s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "",
  14388. lbostr[s.lbo]
  14389. );
  14390. }
  14391. close(ctl);
  14392. return CLI_SUCCESS;
  14393. #undef FORMAT
  14394. #undef FORMAT2
  14395. }
  14396. static char *dahdi_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14397. {
  14398. int pseudo_fd = -1;
  14399. struct dahdi_versioninfo vi;
  14400. switch (cmd) {
  14401. case CLI_INIT:
  14402. e->command = "dahdi show version";
  14403. e->usage =
  14404. "Usage: dahdi show version\n"
  14405. " Shows the DAHDI version in use\n";
  14406. return NULL;
  14407. case CLI_GENERATE:
  14408. return NULL;
  14409. }
  14410. if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) {
  14411. ast_cli(a->fd, "Failed to open control file to get version.\n");
  14412. return CLI_SUCCESS;
  14413. }
  14414. strcpy(vi.version, "Unknown");
  14415. strcpy(vi.echo_canceller, "Unknown");
  14416. if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
  14417. ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno));
  14418. else
  14419. ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
  14420. close(pseudo_fd);
  14421. return CLI_SUCCESS;
  14422. }
  14423. static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14424. {
  14425. int channel;
  14426. float gain;
  14427. int tx;
  14428. struct dahdi_pvt *tmp = NULL;
  14429. switch (cmd) {
  14430. case CLI_INIT:
  14431. e->command = "dahdi set hwgain {rx|tx}";
  14432. e->usage =
  14433. "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
  14434. " Sets the hardware gain on a given channel and overrides the\n"
  14435. " value provided at module loadtime. Changes take effect\n"
  14436. " immediately whether the channel is in use or not.\n"
  14437. "\n"
  14438. " <rx|tx> which direction do you want to change (relative to our module)\n"
  14439. " <chan num> is the channel number relative to the device\n"
  14440. " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
  14441. "\n"
  14442. " Please note:\n"
  14443. " * hwgain is only supportable by hardware with analog ports because\n"
  14444. " hwgain works on the analog side of an analog-digital conversion.\n";
  14445. return NULL;
  14446. case CLI_GENERATE:
  14447. return NULL;
  14448. }
  14449. if (a->argc != 6)
  14450. return CLI_SHOWUSAGE;
  14451. if (!strcasecmp("rx", a->argv[3]))
  14452. tx = 0; /* rx */
  14453. else if (!strcasecmp("tx", a->argv[3]))
  14454. tx = 1; /* tx */
  14455. else
  14456. return CLI_SHOWUSAGE;
  14457. channel = atoi(a->argv[4]);
  14458. gain = atof(a->argv[5]);
  14459. ast_mutex_lock(&iflock);
  14460. for (tmp = iflist; tmp; tmp = tmp->next) {
  14461. if (tmp->channel != channel)
  14462. continue;
  14463. if (tmp->subs[SUB_REAL].dfd == -1)
  14464. break;
  14465. if (set_hwgain(tmp->subs[SUB_REAL].dfd, gain, tx)) {
  14466. ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno));
  14467. ast_mutex_unlock(&iflock);
  14468. return CLI_FAILURE;
  14469. }
  14470. ast_cli(a->fd, "Hardware %s gain set to %.1f dB on channel %d.\n",
  14471. tx ? "tx" : "rx", gain, channel);
  14472. if (tx) {
  14473. tmp->hwtxgain_enabled = 1;
  14474. tmp->hwtxgain = gain;
  14475. } else {
  14476. tmp->hwrxgain_enabled = 1;
  14477. tmp->hwrxgain = gain;
  14478. }
  14479. break;
  14480. }
  14481. ast_mutex_unlock(&iflock);
  14482. if (tmp)
  14483. return CLI_SUCCESS;
  14484. ast_cli(a->fd, "Unable to find given channel %d\n", channel);
  14485. return CLI_FAILURE;
  14486. }
  14487. static char *dahdi_set_swgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14488. {
  14489. int channel;
  14490. float gain;
  14491. int tx;
  14492. int res;
  14493. struct dahdi_pvt *tmp = NULL;
  14494. switch (cmd) {
  14495. case CLI_INIT:
  14496. e->command = "dahdi set swgain {rx|tx}";
  14497. e->usage =
  14498. "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
  14499. " Sets the software gain on a given channel and overrides the\n"
  14500. " value provided at module loadtime. Changes take effect\n"
  14501. " immediately whether the channel is in use or not.\n"
  14502. "\n"
  14503. " <rx|tx> which direction do you want to change (relative to our module)\n"
  14504. " <chan num> is the channel number relative to the device\n"
  14505. " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
  14506. return NULL;
  14507. case CLI_GENERATE:
  14508. return NULL;
  14509. }
  14510. if (a->argc != 6)
  14511. return CLI_SHOWUSAGE;
  14512. if (!strcasecmp("rx", a->argv[3]))
  14513. tx = 0; /* rx */
  14514. else if (!strcasecmp("tx", a->argv[3]))
  14515. tx = 1; /* tx */
  14516. else
  14517. return CLI_SHOWUSAGE;
  14518. channel = atoi(a->argv[4]);
  14519. gain = atof(a->argv[5]);
  14520. ast_mutex_lock(&iflock);
  14521. for (tmp = iflist; tmp; tmp = tmp->next) {
  14522. if (tmp->channel != channel)
  14523. continue;
  14524. if (tmp->subs[SUB_REAL].dfd == -1)
  14525. break;
  14526. if (tx)
  14527. res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law);
  14528. else
  14529. res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law);
  14530. if (res) {
  14531. ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel);
  14532. ast_mutex_unlock(&iflock);
  14533. return CLI_FAILURE;
  14534. }
  14535. ast_cli(a->fd, "Software %s gain set to %.2f dB on channel %d.\n",
  14536. tx ? "tx" : "rx", gain, channel);
  14537. if (tx) {
  14538. tmp->txgain = gain;
  14539. } else {
  14540. tmp->rxgain = gain;
  14541. }
  14542. break;
  14543. }
  14544. ast_mutex_unlock(&iflock);
  14545. if (tmp)
  14546. return CLI_SUCCESS;
  14547. ast_cli(a->fd, "Unable to find given channel %d\n", channel);
  14548. return CLI_FAILURE;
  14549. }
  14550. static char *dahdi_set_dnd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14551. {
  14552. int channel;
  14553. int on;
  14554. struct dahdi_pvt *dahdi_chan = NULL;
  14555. switch (cmd) {
  14556. case CLI_INIT:
  14557. e->command = "dahdi set dnd";
  14558. e->usage =
  14559. "Usage: dahdi set dnd <chan#> <on|off>\n"
  14560. " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
  14561. " Changes take effect immediately.\n"
  14562. " <chan num> is the channel number\n"
  14563. " <on|off> Enable or disable DND mode?\n"
  14564. ;
  14565. return NULL;
  14566. case CLI_GENERATE:
  14567. return NULL;
  14568. }
  14569. if (a->argc != 5)
  14570. return CLI_SHOWUSAGE;
  14571. if ((channel = atoi(a->argv[3])) <= 0) {
  14572. ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
  14573. return CLI_SHOWUSAGE;
  14574. }
  14575. if (ast_true(a->argv[4]))
  14576. on = 1;
  14577. else if (ast_false(a->argv[4]))
  14578. on = 0;
  14579. else {
  14580. ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]);
  14581. return CLI_SHOWUSAGE;
  14582. }
  14583. ast_mutex_lock(&iflock);
  14584. for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
  14585. if (dahdi_chan->channel != channel)
  14586. continue;
  14587. /* Found the channel. Actually set it */
  14588. dahdi_dnd(dahdi_chan, on);
  14589. break;
  14590. }
  14591. ast_mutex_unlock(&iflock);
  14592. if (!dahdi_chan) {
  14593. ast_cli(a->fd, "Unable to find given channel %d\n", channel);
  14594. return CLI_FAILURE;
  14595. }
  14596. return CLI_SUCCESS;
  14597. }
  14598. static struct ast_cli_entry dahdi_cli[] = {
  14599. AST_CLI_DEFINE(handle_dahdi_show_cadences, "List cadences"),
  14600. AST_CLI_DEFINE(dahdi_show_channels, "Show active DAHDI channels"),
  14601. AST_CLI_DEFINE(dahdi_show_channel, "Show information on a channel"),
  14602. AST_CLI_DEFINE(dahdi_destroy_channels, "Destroy channels"),
  14603. AST_CLI_DEFINE(dahdi_create_channels, "Create channels"),
  14604. AST_CLI_DEFINE(dahdi_restart_cmd, "Fully restart DAHDI channels"),
  14605. AST_CLI_DEFINE(dahdi_show_status, "Show all DAHDI cards status"),
  14606. AST_CLI_DEFINE(dahdi_show_version, "Show the DAHDI version in use"),
  14607. AST_CLI_DEFINE(dahdi_set_hwgain, "Set hardware gain on a channel"),
  14608. AST_CLI_DEFINE(dahdi_set_swgain, "Set software gain on a channel"),
  14609. AST_CLI_DEFINE(dahdi_set_dnd, "Sets/resets DND (Do Not Disturb) mode on a channel"),
  14610. };
  14611. #define TRANSFER 0
  14612. #define HANGUP 1
  14613. static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
  14614. {
  14615. if (p) {
  14616. switch (mode) {
  14617. case TRANSFER:
  14618. p->fake_event = DAHDI_EVENT_WINKFLASH;
  14619. break;
  14620. case HANGUP:
  14621. p->fake_event = DAHDI_EVENT_ONHOOK;
  14622. break;
  14623. default:
  14624. ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, ast_channel_name(p->owner));
  14625. }
  14626. }
  14627. return 0;
  14628. }
  14629. static struct dahdi_pvt *find_channel(int channel)
  14630. {
  14631. struct dahdi_pvt *p;
  14632. ast_mutex_lock(&iflock);
  14633. for (p = iflist; p; p = p->next) {
  14634. if (p->channel == channel) {
  14635. break;
  14636. }
  14637. }
  14638. ast_mutex_unlock(&iflock);
  14639. return p;
  14640. }
  14641. /*!
  14642. * \internal
  14643. * \brief Get private struct using given numeric channel string.
  14644. *
  14645. * \param channel Numeric channel number string get private struct.
  14646. *
  14647. * \retval pvt on success.
  14648. * \retval NULL on error.
  14649. */
  14650. static struct dahdi_pvt *find_channel_from_str(const char *channel)
  14651. {
  14652. int chan_num;
  14653. if (sscanf(channel, "%30d", &chan_num) != 1) {
  14654. /* Not numeric string. */
  14655. return NULL;
  14656. }
  14657. return find_channel(chan_num);
  14658. }
  14659. static int action_dahdidndon(struct mansession *s, const struct message *m)
  14660. {
  14661. struct dahdi_pvt *p;
  14662. const char *channel = astman_get_header(m, "DAHDIChannel");
  14663. if (ast_strlen_zero(channel)) {
  14664. astman_send_error(s, m, "No channel specified");
  14665. return 0;
  14666. }
  14667. p = find_channel_from_str(channel);
  14668. if (!p) {
  14669. astman_send_error(s, m, "No such channel");
  14670. return 0;
  14671. }
  14672. dahdi_dnd(p, 1);
  14673. astman_send_ack(s, m, "DND Enabled");
  14674. return 0;
  14675. }
  14676. static int action_dahdidndoff(struct mansession *s, const struct message *m)
  14677. {
  14678. struct dahdi_pvt *p;
  14679. const char *channel = astman_get_header(m, "DAHDIChannel");
  14680. if (ast_strlen_zero(channel)) {
  14681. astman_send_error(s, m, "No channel specified");
  14682. return 0;
  14683. }
  14684. p = find_channel_from_str(channel);
  14685. if (!p) {
  14686. astman_send_error(s, m, "No such channel");
  14687. return 0;
  14688. }
  14689. dahdi_dnd(p, 0);
  14690. astman_send_ack(s, m, "DND Disabled");
  14691. return 0;
  14692. }
  14693. static int action_transfer(struct mansession *s, const struct message *m)
  14694. {
  14695. struct dahdi_pvt *p;
  14696. const char *channel = astman_get_header(m, "DAHDIChannel");
  14697. if (ast_strlen_zero(channel)) {
  14698. astman_send_error(s, m, "No channel specified");
  14699. return 0;
  14700. }
  14701. p = find_channel_from_str(channel);
  14702. if (!p) {
  14703. astman_send_error(s, m, "No such channel");
  14704. return 0;
  14705. }
  14706. if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
  14707. astman_send_error(s, m, "Channel signaling is not analog");
  14708. return 0;
  14709. }
  14710. dahdi_fake_event(p,TRANSFER);
  14711. astman_send_ack(s, m, "DAHDITransfer");
  14712. return 0;
  14713. }
  14714. static int action_transferhangup(struct mansession *s, const struct message *m)
  14715. {
  14716. struct dahdi_pvt *p;
  14717. const char *channel = astman_get_header(m, "DAHDIChannel");
  14718. if (ast_strlen_zero(channel)) {
  14719. astman_send_error(s, m, "No channel specified");
  14720. return 0;
  14721. }
  14722. p = find_channel_from_str(channel);
  14723. if (!p) {
  14724. astman_send_error(s, m, "No such channel");
  14725. return 0;
  14726. }
  14727. if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
  14728. astman_send_error(s, m, "Channel signaling is not analog");
  14729. return 0;
  14730. }
  14731. dahdi_fake_event(p,HANGUP);
  14732. astman_send_ack(s, m, "DAHDIHangup");
  14733. return 0;
  14734. }
  14735. static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
  14736. {
  14737. struct dahdi_pvt *p;
  14738. const char *channel = astman_get_header(m, "DAHDIChannel");
  14739. const char *number = astman_get_header(m, "Number");
  14740. int i;
  14741. if (ast_strlen_zero(channel)) {
  14742. astman_send_error(s, m, "No channel specified");
  14743. return 0;
  14744. }
  14745. if (ast_strlen_zero(number)) {
  14746. astman_send_error(s, m, "No number specified");
  14747. return 0;
  14748. }
  14749. p = find_channel_from_str(channel);
  14750. if (!p) {
  14751. astman_send_error(s, m, "No such channel");
  14752. return 0;
  14753. }
  14754. if (!p->owner) {
  14755. astman_send_error(s, m, "Channel does not have it's owner");
  14756. return 0;
  14757. }
  14758. for (i = 0; i < strlen(number); i++) {
  14759. struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] };
  14760. dahdi_queue_frame(p, &f);
  14761. }
  14762. astman_send_ack(s, m, "DAHDIDialOffhook");
  14763. return 0;
  14764. }
  14765. static int action_dahdishowchannels(struct mansession *s, const struct message *m)
  14766. {
  14767. struct dahdi_pvt *tmp = NULL;
  14768. const char *id = astman_get_header(m, "ActionID");
  14769. const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
  14770. char idText[256] = "";
  14771. int channels = 0;
  14772. int dahdichanquery;
  14773. if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) {
  14774. /* Not numeric string. */
  14775. dahdichanquery = -1;
  14776. }
  14777. astman_send_ack(s, m, "DAHDI channel status will follow");
  14778. if (!ast_strlen_zero(id))
  14779. snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
  14780. ast_mutex_lock(&iflock);
  14781. for (tmp = iflist; tmp; tmp = tmp->next) {
  14782. if (tmp->channel > 0) {
  14783. int alm;
  14784. /* If a specific channel is queried for, only deliver status for that channel */
  14785. if (dahdichanquery > 0 && tmp->channel != dahdichanquery)
  14786. continue;
  14787. alm = get_alarms(tmp);
  14788. channels++;
  14789. if (tmp->owner) {
  14790. /* Add data if we have a current call */
  14791. astman_append(s,
  14792. "Event: DAHDIShowChannels\r\n"
  14793. "DAHDIChannel: %d\r\n"
  14794. "Channel: %s\r\n"
  14795. "Uniqueid: %s\r\n"
  14796. "AccountCode: %s\r\n"
  14797. "Signalling: %s\r\n"
  14798. "SignallingCode: %d\r\n"
  14799. "Context: %s\r\n"
  14800. "DND: %s\r\n"
  14801. "Alarm: %s\r\n"
  14802. "Description: %s\r\n"
  14803. "%s"
  14804. "\r\n",
  14805. tmp->channel,
  14806. ast_channel_name(tmp->owner),
  14807. ast_channel_uniqueid(tmp->owner),
  14808. ast_channel_accountcode(tmp->owner),
  14809. sig2str(tmp->sig),
  14810. tmp->sig,
  14811. tmp->context,
  14812. dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
  14813. alarm2str(alm),
  14814. tmp->description, idText);
  14815. } else {
  14816. astman_append(s,
  14817. "Event: DAHDIShowChannels\r\n"
  14818. "DAHDIChannel: %d\r\n"
  14819. "Signalling: %s\r\n"
  14820. "SignallingCode: %d\r\n"
  14821. "Context: %s\r\n"
  14822. "DND: %s\r\n"
  14823. "Alarm: %s\r\n"
  14824. "Description: %s\r\n"
  14825. "%s"
  14826. "\r\n",
  14827. tmp->channel, sig2str(tmp->sig), tmp->sig,
  14828. tmp->context,
  14829. dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
  14830. alarm2str(alm),
  14831. tmp->description, idText);
  14832. }
  14833. }
  14834. }
  14835. ast_mutex_unlock(&iflock);
  14836. astman_append(s,
  14837. "Event: DAHDIShowChannelsComplete\r\n"
  14838. "%s"
  14839. "Items: %d\r\n"
  14840. "\r\n",
  14841. idText,
  14842. channels);
  14843. return 0;
  14844. }
  14845. #if defined(HAVE_PRI)
  14846. static int action_prishowspans(struct mansession *s, const struct message *m)
  14847. {
  14848. int count;
  14849. int idx;
  14850. int span_query;
  14851. struct dahdi_pri *dspan;
  14852. const char *id = astman_get_header(m, "ActionID");
  14853. const char *span_str = astman_get_header(m, "Span");
  14854. char action_id[256];
  14855. const char *show_cmd = "PRIShowSpans";
  14856. /* NOTE: Asking for span 0 gets all spans. */
  14857. if (!ast_strlen_zero(span_str)) {
  14858. span_query = atoi(span_str);
  14859. } else {
  14860. span_query = 0;
  14861. }
  14862. if (!ast_strlen_zero(id)) {
  14863. snprintf(action_id, sizeof(action_id), "ActionID: %s\r\n", id);
  14864. } else {
  14865. action_id[0] = '\0';
  14866. }
  14867. astman_send_ack(s, m, "Span status will follow");
  14868. count = 0;
  14869. for (idx = 0; idx < ARRAY_LEN(pris); ++idx) {
  14870. dspan = &pris[idx];
  14871. /* If a specific span is asked for, only deliver status for that span. */
  14872. if (0 < span_query && dspan->pri.span != span_query) {
  14873. continue;
  14874. }
  14875. if (dspan->pri.pri) {
  14876. count += sig_pri_ami_show_spans(s, show_cmd, &dspan->pri, dspan->dchannels,
  14877. action_id);
  14878. }
  14879. }
  14880. astman_append(s,
  14881. "Event: %sComplete\r\n"
  14882. "Items: %d\r\n"
  14883. "%s"
  14884. "\r\n",
  14885. show_cmd,
  14886. count,
  14887. action_id);
  14888. return 0;
  14889. }
  14890. #endif /* defined(HAVE_PRI) */
  14891. #if defined(HAVE_SS7)
  14892. static int linkset_addsigchan(int sigchan)
  14893. {
  14894. struct dahdi_ss7 *link;
  14895. int res;
  14896. int curfd;
  14897. struct dahdi_params params;
  14898. struct dahdi_bufferinfo bi;
  14899. struct dahdi_spaninfo si;
  14900. if (sigchan < 0) {
  14901. ast_log(LOG_ERROR, "Invalid sigchan!\n");
  14902. return -1;
  14903. }
  14904. if (cur_ss7type < 0) {
  14905. ast_log(LOG_ERROR, "Unspecified or invalid ss7type\n");
  14906. return -1;
  14907. }
  14908. if (cur_pointcode < 0) {
  14909. ast_log(LOG_ERROR, "Unspecified pointcode!\n");
  14910. return -1;
  14911. }
  14912. if (cur_adjpointcode < 0) {
  14913. ast_log(LOG_ERROR, "Unspecified adjpointcode!\n");
  14914. return -1;
  14915. }
  14916. if (cur_defaultdpc < 0) {
  14917. ast_log(LOG_ERROR, "Unspecified defaultdpc!\n");
  14918. return -1;
  14919. }
  14920. if (cur_networkindicator < 0) {
  14921. ast_log(LOG_ERROR, "Invalid networkindicator!\n");
  14922. return -1;
  14923. }
  14924. link = ss7_resolve_linkset(cur_linkset);
  14925. if (!link) {
  14926. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  14927. return -1;
  14928. }
  14929. if (link->ss7.numsigchans >= SIG_SS7_NUM_DCHANS) {
  14930. ast_log(LOG_ERROR, "Too many sigchans on linkset %d\n", cur_linkset);
  14931. return -1;
  14932. }
  14933. curfd = link->ss7.numsigchans;
  14934. /* Open signaling channel */
  14935. link->ss7.fds[curfd] = open("/dev/dahdi/channel", O_RDWR, 0600);
  14936. if (link->ss7.fds[curfd] < 0) {
  14937. ast_log(LOG_ERROR, "Unable to open SS7 sigchan %d (%s)\n", sigchan,
  14938. strerror(errno));
  14939. return -1;
  14940. }
  14941. if (ioctl(link->ss7.fds[curfd], DAHDI_SPECIFY, &sigchan) == -1) {
  14942. dahdi_close_ss7_fd(link, curfd);
  14943. ast_log(LOG_ERROR, "Unable to specify SS7 sigchan %d (%s)\n", sigchan,
  14944. strerror(errno));
  14945. return -1;
  14946. }
  14947. /* Get signaling channel parameters */
  14948. memset(&params, 0, sizeof(params));
  14949. res = ioctl(link->ss7.fds[curfd], DAHDI_GET_PARAMS, &params);
  14950. if (res) {
  14951. dahdi_close_ss7_fd(link, curfd);
  14952. ast_log(LOG_ERROR, "Unable to get parameters for sigchan %d (%s)\n", sigchan,
  14953. strerror(errno));
  14954. return -1;
  14955. }
  14956. if (params.sigtype != DAHDI_SIG_HDLCFCS
  14957. && params.sigtype != DAHDI_SIG_HARDHDLC
  14958. && params.sigtype != DAHDI_SIG_MTP2) {
  14959. dahdi_close_ss7_fd(link, curfd);
  14960. ast_log(LOG_ERROR, "sigchan %d is not in HDLC/FCS mode.\n", sigchan);
  14961. return -1;
  14962. }
  14963. /* Set signaling channel buffer policy. */
  14964. memset(&bi, 0, sizeof(bi));
  14965. bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
  14966. bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
  14967. bi.numbufs = 32;
  14968. bi.bufsize = 512;
  14969. if (ioctl(link->ss7.fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
  14970. ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n",
  14971. sigchan, strerror(errno));
  14972. dahdi_close_ss7_fd(link, curfd);
  14973. return -1;
  14974. }
  14975. /* Get current signaling channel alarm status. */
  14976. memset(&si, 0, sizeof(si));
  14977. res = ioctl(link->ss7.fds[curfd], DAHDI_SPANSTAT, &si);
  14978. if (res) {
  14979. dahdi_close_ss7_fd(link, curfd);
  14980. ast_log(LOG_ERROR, "Unable to get span state for sigchan %d (%s)\n", sigchan,
  14981. strerror(errno));
  14982. }
  14983. res = sig_ss7_add_sigchan(&link->ss7, curfd, cur_ss7type,
  14984. (params.sigtype == DAHDI_SIG_MTP2)
  14985. ? SS7_TRANSPORT_DAHDIMTP2
  14986. : SS7_TRANSPORT_DAHDIDCHAN,
  14987. si.alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode, cur_slc);
  14988. if (res) {
  14989. dahdi_close_ss7_fd(link, curfd);
  14990. return -1;
  14991. }
  14992. ++link->ss7.numsigchans;
  14993. return 0;
  14994. }
  14995. #endif /* defined(HAVE_SS7) */
  14996. #if defined(HAVE_SS7)
  14997. static char *handle_ss7_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  14998. {
  14999. int span;
  15000. switch (cmd) {
  15001. case CLI_INIT:
  15002. e->command = "ss7 set debug {on|off} linkset";
  15003. e->usage =
  15004. "Usage: ss7 set debug {on|off} linkset <linkset>\n"
  15005. " Enables debugging on a given SS7 linkset\n";
  15006. return NULL;
  15007. case CLI_GENERATE:
  15008. return NULL;
  15009. }
  15010. if (a->argc < 6) {
  15011. return CLI_SHOWUSAGE;
  15012. }
  15013. span = atoi(a->argv[5]);
  15014. if ((span < 1) || (span > NUM_SPANS)) {
  15015. ast_cli(a->fd, "Invalid linkset %s. Should be a number from %d to %d\n", a->argv[5], 1, NUM_SPANS);
  15016. return CLI_SUCCESS;
  15017. }
  15018. if (!linksets[span-1].ss7.ss7) {
  15019. ast_cli(a->fd, "No SS7 running on linkset %d\n", span);
  15020. } else {
  15021. if (!strcasecmp(a->argv[3], "on")) {
  15022. linksets[span - 1].ss7.debug = 1;
  15023. ss7_set_debug(linksets[span-1].ss7.ss7, SIG_SS7_DEBUG);
  15024. ast_cli(a->fd, "Enabled debugging on linkset %d\n", span);
  15025. } else {
  15026. linksets[span - 1].ss7.debug = 0;
  15027. ss7_set_debug(linksets[span-1].ss7.ss7, 0);
  15028. ast_cli(a->fd, "Disabled debugging on linkset %d\n", span);
  15029. }
  15030. }
  15031. return CLI_SUCCESS;
  15032. }
  15033. #endif /* defined(HAVE_SS7) */
  15034. #if defined(HAVE_SS7)
  15035. static char *handle_ss7_cic_blocking(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15036. {
  15037. int linkset, cic;
  15038. int blocked, i;
  15039. int do_block = 0;
  15040. unsigned int dpc;
  15041. switch (cmd) {
  15042. case CLI_INIT:
  15043. e->command = "ss7 {block|unblock} cic";
  15044. e->usage =
  15045. "Usage: ss7 {block|unblock} cic <linkset> <dpc> <CIC>\n"
  15046. " Sends a remote {blocking|unblocking} request for the given CIC on the specified linkset\n";
  15047. return NULL;
  15048. case CLI_GENERATE:
  15049. return NULL;
  15050. }
  15051. if (a->argc == 6) {
  15052. linkset = atoi(a->argv[3]);
  15053. } else {
  15054. return CLI_SHOWUSAGE;
  15055. }
  15056. if (!strcasecmp(a->argv[1], "block")) {
  15057. do_block = 1;
  15058. } else if (strcasecmp(a->argv[1], "unblock")) {
  15059. return CLI_SHOWUSAGE;
  15060. }
  15061. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15062. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15063. return CLI_SUCCESS;
  15064. }
  15065. if (!linksets[linkset-1].ss7.ss7) {
  15066. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15067. return CLI_SUCCESS;
  15068. }
  15069. cic = atoi(a->argv[5]);
  15070. if (cic < 1) {
  15071. ast_cli(a->fd, "Invalid CIC specified!\n");
  15072. return CLI_SUCCESS;
  15073. }
  15074. dpc = atoi(a->argv[4]);
  15075. if (dpc < 1) {
  15076. ast_cli(a->fd, "Invalid DPC specified!\n");
  15077. return CLI_SUCCESS;
  15078. }
  15079. for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
  15080. if (linksets[linkset-1].ss7.pvts[i] && linksets[linkset-1].ss7.pvts[i]->cic == cic && linksets[linkset-1].ss7.pvts[i]->dpc == dpc) {
  15081. blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
  15082. if (!do_block ^ !(blocked & SS7_BLOCKED_MAINTENANCE)) {
  15083. if (sig_ss7_cic_blocking(&linksets[linkset-1].ss7, do_block, i) < 0) {
  15084. ast_cli(a->fd, "Unable to allocate new ss7call\n");
  15085. } else {
  15086. ast_cli(a->fd, "Sent %sblocking request for linkset %d on CIC %d DPC %d\n", (do_block) ? "" : "un", linkset, cic, dpc);
  15087. }
  15088. } else if (!do_block && blocked) {
  15089. ast_cli(a->fd, "CIC %d is hardware locally blocked!\n", cic);
  15090. } else {
  15091. ast_cli(a->fd, "CIC %d %s locally blocked\n", cic, do_block ? "already" : "is not");
  15092. }
  15093. return CLI_SUCCESS;
  15094. }
  15095. }
  15096. ast_cli(a->fd, "Invalid CIC specified!\n");
  15097. return CLI_SUCCESS;
  15098. }
  15099. #endif /* defined(HAVE_SS7) */
  15100. #if defined(HAVE_SS7)
  15101. static char *handle_ss7_linkset_mng(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15102. {
  15103. int linkset, i;
  15104. enum {
  15105. DO_BLOCK,
  15106. DO_UNBLOCK,
  15107. DO_RESET,
  15108. } do_what;
  15109. switch (cmd) {
  15110. case CLI_INIT:
  15111. e->command = "ss7 {reset|block|unblock} linkset";
  15112. e->usage =
  15113. "Usage: ss7 {reset|block|unblock} linkset <linkset number>\n"
  15114. " Sends a remote {reset|blocking|unblocking} request for all CICs on the given linkset\n";
  15115. return NULL;
  15116. case CLI_GENERATE:
  15117. return NULL;
  15118. }
  15119. if (a->argc == 4) {
  15120. linkset = atoi(a->argv[3]);
  15121. } else {
  15122. return CLI_SHOWUSAGE;
  15123. }
  15124. if (!strcasecmp(a->argv[1], "block")) {
  15125. do_what = DO_BLOCK;
  15126. } else if (!strcasecmp(a->argv[1], "unblock")) {
  15127. do_what = DO_UNBLOCK;
  15128. } else if (!strcasecmp(a->argv[1], "reset")) {
  15129. do_what = DO_RESET;
  15130. } else {
  15131. return CLI_SHOWUSAGE;
  15132. }
  15133. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15134. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15135. return CLI_SUCCESS;
  15136. }
  15137. if (!linksets[linkset - 1].ss7.ss7) {
  15138. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15139. return CLI_SUCCESS;
  15140. }
  15141. for (i = 0; i < linksets[linkset - 1].ss7.numchans; i++) {
  15142. /* XXX Should be done with GRS/CGB/CGU instead - see ss7_reset_linkset() */
  15143. if (linksets[linkset - 1].ss7.pvts[i]) {
  15144. switch (do_what) {
  15145. case DO_BLOCK:
  15146. case DO_UNBLOCK:
  15147. if (sig_ss7_cic_blocking(&linksets[linkset - 1].ss7, do_what == DO_BLOCK, i)) {
  15148. ast_cli(a->fd, "Sent remote %s request on CIC %d\n",
  15149. (do_what == DO_BLOCK) ? "blocking" : "unblocking",
  15150. linksets[linkset - 1].ss7.pvts[i]->cic);
  15151. }
  15152. break;
  15153. case DO_RESET:
  15154. if (sig_ss7_reset_cic(&linksets[linkset - 1].ss7,
  15155. linksets[linkset - 1].ss7.pvts[i]->cic,
  15156. linksets[linkset - 1].ss7.pvts[i]->dpc)) {
  15157. ast_cli(a->fd, "Sent reset request on CIC %d\n",
  15158. linksets[linkset - 1].ss7.pvts[i]->cic);
  15159. }
  15160. break;
  15161. }
  15162. }
  15163. }
  15164. return CLI_SUCCESS;
  15165. }
  15166. #endif /* defined(HAVE_SS7) */
  15167. #if defined(HAVE_SS7)
  15168. static char *handle_ss7_group_blocking(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15169. {
  15170. int linkset, cic, range, chanpos;
  15171. int i, dpc, orient = 0;
  15172. int do_block = 0;
  15173. unsigned char state[255];
  15174. switch (cmd) {
  15175. case CLI_INIT:
  15176. e->command = "ss7 {block|unblock} group";
  15177. e->usage =
  15178. "Usage: ss7 {block|unblock} group <linkset> <dpc> <1st. CIC> <range> [H]\n"
  15179. " Sends a remote {blocking|unblocking} request for CIC range on the specified linkset\n";
  15180. return NULL;
  15181. case CLI_GENERATE:
  15182. return NULL;
  15183. }
  15184. if (a->argc == 7 || a->argc == 8) {
  15185. linkset = atoi(a->argv[3]);
  15186. } else {
  15187. return CLI_SHOWUSAGE;
  15188. }
  15189. if (!strcasecmp(a->argv[1], "block")) {
  15190. do_block = 1;
  15191. } else if (strcasecmp(a->argv[1], "unblock")) {
  15192. return CLI_SHOWUSAGE;
  15193. }
  15194. if (a->argc == 8) {
  15195. if (!strcasecmp(a->argv[7], "H")) {
  15196. orient = 1;
  15197. } else {
  15198. return CLI_SHOWUSAGE;
  15199. }
  15200. }
  15201. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15202. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[4], 1, NUM_SPANS);
  15203. return CLI_SUCCESS;
  15204. }
  15205. if (!linksets[linkset-1].ss7.ss7) {
  15206. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15207. return CLI_SUCCESS;
  15208. }
  15209. cic = atoi(a->argv[5]);
  15210. if (cic < 1) {
  15211. ast_cli(a->fd, "Invalid CIC specified!\n");
  15212. return CLI_SUCCESS;
  15213. }
  15214. range = atoi(a->argv[6]);
  15215. /* ITU-T Q.763 3.43 - range 0 is reserved, which makes a range of 2 CICs a minimum group */
  15216. if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
  15217. ast_cli(a->fd, "Invalid range specified!\n");
  15218. return CLI_SUCCESS;
  15219. }
  15220. dpc = atoi(a->argv[4]);
  15221. if (dpc < 1) {
  15222. ast_cli(a->fd, "Invalid DPC specified!\n");
  15223. return CLI_SUCCESS;
  15224. }
  15225. ast_mutex_lock(&linksets[linkset-1].ss7.lock);
  15226. if (!sig_ss7_find_cic_range(&linksets[linkset-1].ss7, cic, cic + range, dpc)) {
  15227. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15228. ast_cli(a->fd, "Invalid CIC/RANGE\n");
  15229. return CLI_SHOWUSAGE;
  15230. }
  15231. memset(state, 0, sizeof(state));
  15232. for (i = 0; i <= range; ++i) {
  15233. state[i] = 1;
  15234. }
  15235. /* We are guaranteed to find chanpos because of sig_ss7_find_cic_range() includes it. */
  15236. chanpos = sig_ss7_find_cic(&linksets[linkset-1].ss7, cic, dpc);
  15237. if (sig_ss7_group_blocking(&linksets[linkset-1].ss7, do_block, chanpos, cic + range, state, orient)) {
  15238. ast_cli(a->fd, "Unable allocate new ss7call\n");
  15239. } else {
  15240. ast_cli(a->fd, "Sending remote%s %sblocking request linkset %d on CIC %d range %d\n",
  15241. orient ? " hardware" : "", do_block ? "" : "un", linkset, cic, range);
  15242. }
  15243. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15244. /* Break poll on the linkset so it sends our messages */
  15245. if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
  15246. pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
  15247. }
  15248. return CLI_SUCCESS;
  15249. }
  15250. #endif /* defined(HAVE_SS7) */
  15251. #if defined(HAVE_SS7)
  15252. static char *handle_ss7_group_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15253. {
  15254. int linkset, cic, range;
  15255. unsigned int dpc;
  15256. switch (cmd) {
  15257. case CLI_INIT:
  15258. e->command = "ss7 reset group";
  15259. e->usage =
  15260. "Usage: ss7 reset group <linkset> <dpc> <1st CIC> <range>\n"
  15261. " Send a GRS for the given CIC range on the specified linkset\n";
  15262. return NULL;
  15263. case CLI_GENERATE:
  15264. return NULL;
  15265. }
  15266. if (a->argc == 7) {
  15267. linkset = atoi(a->argv[3]);
  15268. } else {
  15269. return CLI_SHOWUSAGE;
  15270. }
  15271. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15272. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[4], 1, NUM_SPANS);
  15273. return CLI_SUCCESS;
  15274. }
  15275. if (!linksets[linkset-1].ss7.ss7) {
  15276. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15277. return CLI_SUCCESS;
  15278. }
  15279. cic = atoi(a->argv[5]);
  15280. if (cic < 1) {
  15281. ast_cli(a->fd, "Invalid CIC specified!\n");
  15282. return CLI_SUCCESS;
  15283. }
  15284. range = atoi(a->argv[6]);
  15285. if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
  15286. ast_cli(a->fd, "Invalid range specified!\n");
  15287. return CLI_SUCCESS;
  15288. }
  15289. dpc = atoi(a->argv[4]);
  15290. if (dpc < 1) {
  15291. ast_cli(a->fd, "Invalid DPC specified!\n");
  15292. return CLI_SUCCESS;
  15293. }
  15294. ast_mutex_lock(&linksets[linkset-1].ss7.lock);
  15295. if (!sig_ss7_find_cic_range(&linksets[linkset-1].ss7, cic, cic + range, dpc)) {
  15296. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15297. ast_cli(a->fd, "Invalid CIC/RANGE\n");
  15298. return CLI_SHOWUSAGE;
  15299. }
  15300. if (sig_ss7_reset_group(&linksets[linkset-1].ss7, cic, dpc, range)) {
  15301. ast_cli(a->fd, "Unable to allocate new ss7call\n");
  15302. } else {
  15303. ast_cli(a->fd, "GRS sent ... \n");
  15304. }
  15305. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15306. /* Break poll on the linkset so it sends our messages */
  15307. if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
  15308. pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
  15309. }
  15310. return CLI_SUCCESS;
  15311. }
  15312. #endif /* defined(HAVE_SS7) */
  15313. #if defined(HAVE_SS7)
  15314. static char *handle_ss7_show_calls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15315. {
  15316. int linkset;
  15317. switch (cmd) {
  15318. case CLI_INIT:
  15319. e->command = "ss7 show calls";
  15320. e->usage =
  15321. "Usage: ss7 show calls <linkset>\n"
  15322. " Show SS7 calls on the specified linkset\n";
  15323. return NULL;
  15324. case CLI_GENERATE:
  15325. return NULL;
  15326. }
  15327. if (a->argc == 4) {
  15328. linkset = atoi(a->argv[3]);
  15329. } else {
  15330. return CLI_SHOWUSAGE;
  15331. }
  15332. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15333. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15334. return CLI_SUCCESS;
  15335. }
  15336. if (!linksets[linkset-1].ss7.ss7) {
  15337. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15338. return CLI_SUCCESS;
  15339. }
  15340. ast_mutex_lock(&linksets[linkset-1].ss7.lock);
  15341. isup_show_calls(linksets[linkset-1].ss7.ss7, &ast_cli, a->fd);
  15342. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15343. return CLI_SUCCESS;
  15344. }
  15345. #endif /* defined(HAVE_SS7) */
  15346. #if defined(HAVE_SS7)
  15347. static char *handle_ss7_reset_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15348. {
  15349. int linkset, cic, res;
  15350. unsigned int dpc;
  15351. switch (cmd) {
  15352. case CLI_INIT:
  15353. e->command = "ss7 reset cic";
  15354. e->usage =
  15355. "Usage: ss7 reset cic <linkset> <dpc> <CIC>\n"
  15356. " Send a RSC for the given CIC on the specified linkset\n";
  15357. return NULL;
  15358. case CLI_GENERATE:
  15359. return NULL;
  15360. }
  15361. if (a->argc == 6) {
  15362. linkset = atoi(a->argv[3]);
  15363. } else {
  15364. return CLI_SHOWUSAGE;
  15365. }
  15366. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15367. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15368. return CLI_SUCCESS;
  15369. }
  15370. if (!linksets[linkset-1].ss7.ss7) {
  15371. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15372. return CLI_SUCCESS;
  15373. }
  15374. cic = atoi(a->argv[5]);
  15375. if (cic < 1) {
  15376. ast_cli(a->fd, "Invalid CIC specified!\n");
  15377. return CLI_SUCCESS;
  15378. }
  15379. dpc = atoi(a->argv[4]);
  15380. if (dpc < 1) {
  15381. ast_cli(a->fd, "Invalid DPC specified!\n");
  15382. return CLI_SUCCESS;
  15383. }
  15384. res = sig_ss7_reset_cic(&linksets[linkset-1].ss7, cic, dpc);
  15385. ast_cli(a->fd, "%s RSC for linkset %d on CIC %d DPC %d\n", res ? "Sent" : "Failed", linkset, cic, dpc);
  15386. return CLI_SUCCESS;
  15387. }
  15388. #endif /* defined(HAVE_SS7) */
  15389. #if defined(HAVE_SS7)
  15390. static char *handle_ss7_net_mng(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15391. {
  15392. int linkset;
  15393. unsigned int slc;
  15394. unsigned int arg = 0;
  15395. const char *res;
  15396. switch (cmd) {
  15397. case CLI_INIT:
  15398. e->command = "ss7 mtp3";
  15399. e->usage =
  15400. "Usage: ss7 mtp3 <linkset> <slc> coo|coa|cbd|cba|eco|eca|tfp|tfa|lin|lun|lia|lua|lid|lfu <arg>\n"
  15401. " Send a NET MNG message\n"
  15402. " WARNING!!! WARNING!!! We are not a STP, just for testing/development purposes\n";
  15403. return NULL;
  15404. case CLI_GENERATE:
  15405. return NULL;
  15406. }
  15407. if (a->argc < 5) {
  15408. return CLI_SHOWUSAGE;
  15409. }
  15410. linkset = atoi(a->argv[2]);
  15411. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15412. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[2], 1, NUM_SPANS);
  15413. return CLI_SUCCESS;
  15414. }
  15415. if (!linksets[linkset-1].ss7.ss7) {
  15416. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15417. return CLI_SUCCESS;
  15418. }
  15419. slc = atoi(a->argv[3]);
  15420. if (a->argc == 6) {
  15421. arg = atoi(a->argv[5]);
  15422. }
  15423. ast_mutex_lock(&linksets[linkset-1].ss7.lock);
  15424. res = mtp3_net_mng(linksets[linkset-1].ss7.ss7, slc, a->argv[4], arg);
  15425. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15426. /* Break poll on the linkset so it sends our messages */
  15427. if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
  15428. pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
  15429. }
  15430. ast_cli(a->fd, "%s", res);
  15431. return CLI_SUCCESS;
  15432. }
  15433. #endif /* defined(HAVE_SS7) */
  15434. #if defined(HAVE_SS7)
  15435. static char *handle_ss7_mtp3_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15436. {
  15437. int linkset;
  15438. unsigned int slc = 0;
  15439. switch (cmd) {
  15440. case CLI_INIT:
  15441. e->command = "ss7 restart mtp3";
  15442. e->usage =
  15443. "Usage: ss7 restart mtp3 <linkset> <slc>\n"
  15444. " Restart link\n";
  15445. return NULL;
  15446. case CLI_GENERATE:
  15447. return NULL;
  15448. }
  15449. if (a->argc < 5) {
  15450. return CLI_SHOWUSAGE;
  15451. }
  15452. linkset = atoi(a->argv[3]);
  15453. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15454. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[2], 1, NUM_SPANS);
  15455. return CLI_SUCCESS;
  15456. }
  15457. if (!linksets[linkset-1].ss7.ss7) {
  15458. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15459. return CLI_SUCCESS;
  15460. }
  15461. slc = atoi(a->argv[4]);
  15462. ast_mutex_lock(&linksets[linkset-1].ss7.lock);
  15463. mtp3_init_restart(linksets[linkset-1].ss7.ss7, slc);
  15464. ast_mutex_unlock(&linksets[linkset-1].ss7.lock);
  15465. /* Break poll on the linkset so it sends our messages */
  15466. if (linksets[linkset-1].ss7.master != AST_PTHREADT_NULL) {
  15467. pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
  15468. }
  15469. return CLI_SUCCESS;
  15470. }
  15471. #endif /* defined(HAVE_SS7) */
  15472. #if defined(HAVE_SS7)
  15473. static char *handle_ss7_show_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15474. {
  15475. int linkset;
  15476. struct sig_ss7_linkset *ss7;
  15477. switch (cmd) {
  15478. case CLI_INIT:
  15479. e->command = "ss7 show linkset";
  15480. e->usage =
  15481. "Usage: ss7 show linkset <span>\n"
  15482. " Shows the status of an SS7 linkset.\n";
  15483. return NULL;
  15484. case CLI_GENERATE:
  15485. return NULL;
  15486. }
  15487. if (a->argc < 4) {
  15488. return CLI_SHOWUSAGE;
  15489. }
  15490. linkset = atoi(a->argv[3]);
  15491. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15492. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15493. return CLI_SUCCESS;
  15494. }
  15495. ss7 = &linksets[linkset - 1].ss7;
  15496. if (!ss7->ss7) {
  15497. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15498. return CLI_SUCCESS;
  15499. }
  15500. ast_cli(a->fd, "SS7 flags: 0x%x\n", ss7->flags);
  15501. ast_cli(a->fd, "SS7 linkset %d status: %s\n", linkset, (ss7->state == LINKSET_STATE_UP) ? "Up" : "Down");
  15502. ast_cli(a->fd, "SS7 calling nai: %i\n", ss7->calling_nai);
  15503. ast_cli(a->fd, "SS7 called nai: %i\n", ss7->called_nai);
  15504. ast_cli(a->fd, "SS7 nationalprefix: %s\n", ss7->nationalprefix);
  15505. ast_cli(a->fd, "SS7 internationalprefix: %s\n", ss7->internationalprefix);
  15506. ast_cli(a->fd, "SS7 unknownprefix: %s\n", ss7->unknownprefix);
  15507. ast_cli(a->fd, "SS7 networkroutedprefix: %s\n", ss7->networkroutedprefix);
  15508. ast_cli(a->fd, "SS7 subscriberprefix: %s\n", ss7->subscriberprefix);
  15509. ss7_show_linkset(ss7->ss7, &ast_cli, a->fd);
  15510. return CLI_SUCCESS;
  15511. }
  15512. #endif /* defined(HAVE_SS7) */
  15513. #if defined(HAVE_SS7)
  15514. static char *handle_ss7_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15515. {
  15516. int linkset;
  15517. switch (cmd) {
  15518. case CLI_INIT:
  15519. e->command = "ss7 show channels";
  15520. e->usage =
  15521. "Usage: ss7 show channels\n"
  15522. " Displays SS7 channel information at a glance.\n";
  15523. return NULL;
  15524. case CLI_GENERATE:
  15525. return NULL;
  15526. }
  15527. if (a->argc != 3) {
  15528. return CLI_SHOWUSAGE;
  15529. }
  15530. sig_ss7_cli_show_channels_header(a->fd);
  15531. for (linkset = 0; linkset < NUM_SPANS; ++linkset) {
  15532. if (linksets[linkset].ss7.ss7) {
  15533. sig_ss7_cli_show_channels(a->fd, &linksets[linkset].ss7);
  15534. }
  15535. }
  15536. return CLI_SUCCESS;
  15537. }
  15538. #endif /* defined(HAVE_SS7) */
  15539. #if defined(HAVE_SS7)
  15540. static char *handle_ss7_show_cics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15541. {
  15542. #define FORMAT "%5s %5s %6s %12s %-12s\n"
  15543. #define FORMAT2 "%5i %5i %6i %12s %-12s\n"
  15544. int i, linkset, dpc = 0;
  15545. struct sig_ss7_linkset *ss7;
  15546. char *state;
  15547. char blocking[12];
  15548. switch (cmd) {
  15549. case CLI_INIT:
  15550. e->command = "ss7 show cics";
  15551. e->usage =
  15552. "Usage: ss7 show cics <linkset> [dpc]\n"
  15553. " Shows the cics of an SS7 linkset.\n";
  15554. return NULL;
  15555. case CLI_GENERATE:
  15556. return NULL;
  15557. }
  15558. if (a->argc < 4 || a->argc > 5) {
  15559. return CLI_SHOWUSAGE;
  15560. }
  15561. linkset = atoi(a->argv[3]);
  15562. if ((linkset < 1) || (linkset > NUM_SPANS)) {
  15563. ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
  15564. return CLI_SUCCESS;
  15565. }
  15566. if (!linksets[linkset-1].ss7.ss7) {
  15567. ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
  15568. return CLI_SUCCESS;
  15569. }
  15570. ss7 = &linksets[linkset-1].ss7;
  15571. if (a->argc == 5) {
  15572. dpc = atoi(a->argv[4]);
  15573. if (dpc < 1) {
  15574. ast_cli(a->fd, "Invalid DPC specified!\n");
  15575. return CLI_SUCCESS;
  15576. }
  15577. }
  15578. ast_cli(a->fd, FORMAT, "CIC", "DPC", "DAHDI", "STATE", "BLOCKING");
  15579. for (i = 0; i < ss7->numchans; i++) {
  15580. if (!dpc || (ss7->pvts[i] && ss7->pvts[i]->dpc == dpc)) {
  15581. struct dahdi_pvt *p = ss7->pvts[i]->chan_pvt;
  15582. if (ss7->pvts[i]->owner) {
  15583. state = "Used";
  15584. } else if (ss7->pvts[i]->ss7call) {
  15585. state = "Pending";
  15586. } else if (!p->inservice) {
  15587. state = "NotInServ";
  15588. } else {
  15589. state = "Idle";
  15590. }
  15591. if (p->locallyblocked) {
  15592. strcpy(blocking, "L:");
  15593. if (p->locallyblocked & SS7_BLOCKED_MAINTENANCE) {
  15594. strcat(blocking, "M");
  15595. } else {
  15596. strcat(blocking, " ");
  15597. }
  15598. if (p->locallyblocked & SS7_BLOCKED_HARDWARE) {
  15599. strcat(blocking, "H");
  15600. } else {
  15601. strcat(blocking, " ");
  15602. }
  15603. } else {
  15604. strcpy(blocking, " ");
  15605. }
  15606. if (p->remotelyblocked) {
  15607. strcat(blocking, " R:");
  15608. if (p->remotelyblocked & SS7_BLOCKED_MAINTENANCE) {
  15609. strcat(blocking, "M");
  15610. } else {
  15611. strcat(blocking, " ");
  15612. }
  15613. if (p->remotelyblocked & SS7_BLOCKED_HARDWARE) {
  15614. strcat(blocking, "H");
  15615. } else {
  15616. strcat(blocking, " ");
  15617. }
  15618. }
  15619. ast_cli(a->fd, FORMAT2, ss7->pvts[i]->cic, ss7->pvts[i]->dpc, ss7->pvts[i]->channel, state, blocking);
  15620. }
  15621. }
  15622. return CLI_SUCCESS;
  15623. #undef FORMAT
  15624. #undef FORMAT2
  15625. }
  15626. #endif /* defined(HAVE_SS7) */
  15627. #if defined(HAVE_SS7)
  15628. static char *handle_ss7_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  15629. {
  15630. switch (cmd) {
  15631. case CLI_INIT:
  15632. e->command = "ss7 show version";
  15633. e->usage =
  15634. "Usage: ss7 show version\n"
  15635. " Show the libss7 version\n";
  15636. return NULL;
  15637. case CLI_GENERATE:
  15638. return NULL;
  15639. }
  15640. ast_cli(a->fd, "libss7 version: %s\n", ss7_get_version());
  15641. return CLI_SUCCESS;
  15642. }
  15643. #endif /* defined(HAVE_SS7) */
  15644. #if defined(HAVE_SS7)
  15645. static struct ast_cli_entry dahdi_ss7_cli[] = {
  15646. AST_CLI_DEFINE(handle_ss7_debug, "Enables SS7 debugging on a linkset"),
  15647. AST_CLI_DEFINE(handle_ss7_cic_blocking, "Blocks/Unblocks the given CIC"),
  15648. AST_CLI_DEFINE(handle_ss7_linkset_mng, "Resets/Blocks/Unblocks all CICs on a linkset"),
  15649. AST_CLI_DEFINE(handle_ss7_group_blocking, "Blocks/Unblocks the given CIC range"),
  15650. AST_CLI_DEFINE(handle_ss7_reset_cic, "Resets the given CIC"),
  15651. AST_CLI_DEFINE(handle_ss7_group_reset, "Resets the given CIC range"),
  15652. AST_CLI_DEFINE(handle_ss7_mtp3_restart, "Restart a link"),
  15653. AST_CLI_DEFINE(handle_ss7_net_mng, "Send an NET MNG message"),
  15654. AST_CLI_DEFINE(handle_ss7_show_linkset, "Shows the status of a linkset"),
  15655. AST_CLI_DEFINE(handle_ss7_show_channels, "Displays SS7 channel information"),
  15656. AST_CLI_DEFINE(handle_ss7_show_calls, "Show ss7 calls"),
  15657. AST_CLI_DEFINE(handle_ss7_show_cics, "Show cics on a linkset"),
  15658. AST_CLI_DEFINE(handle_ss7_version, "Displays libss7 version"),
  15659. };
  15660. #endif /* defined(HAVE_SS7) */
  15661. #if defined(HAVE_PRI)
  15662. #if defined(HAVE_PRI_CCSS)
  15663. /*!
  15664. * \internal
  15665. * \brief CC agent initialization.
  15666. * \since 1.8
  15667. *
  15668. * \param agent CC core agent control.
  15669. * \param chan Original channel the agent will attempt to recall.
  15670. *
  15671. * \details
  15672. * This callback is called when the CC core is initialized. Agents should allocate
  15673. * any private data necessary for the call and assign it to the private_data
  15674. * on the agent. Additionally, if any ast_cc_agent_flags are pertinent to the
  15675. * specific agent type, they should be set in this function as well.
  15676. *
  15677. * \retval 0 on success.
  15678. * \retval -1 on error.
  15679. */
  15680. static int dahdi_pri_cc_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
  15681. {
  15682. struct dahdi_pvt *pvt;
  15683. struct sig_pri_chan *pvt_chan;
  15684. int res;
  15685. ast_assert(!strcmp(ast_channel_tech(chan)->type, "DAHDI"));
  15686. pvt = ast_channel_tech_pvt(chan);
  15687. if (dahdi_sig_pri_lib_handles(pvt->sig)) {
  15688. pvt_chan = pvt->sig_pvt;
  15689. } else {
  15690. pvt_chan = NULL;
  15691. }
  15692. if (!pvt_chan) {
  15693. return -1;
  15694. }
  15695. ast_module_ref(ast_module_info->self);
  15696. res = sig_pri_cc_agent_init(agent, pvt_chan);
  15697. if (res) {
  15698. ast_module_unref(ast_module_info->self);
  15699. }
  15700. return res;
  15701. }
  15702. #endif /* defined(HAVE_PRI_CCSS) */
  15703. #endif /* defined(HAVE_PRI) */
  15704. #if defined(HAVE_PRI)
  15705. #if defined(HAVE_PRI_CCSS)
  15706. /*!
  15707. * \internal
  15708. * \brief Destroy private data on the agent.
  15709. * \since 1.8
  15710. *
  15711. * \param agent CC core agent control.
  15712. *
  15713. * \details
  15714. * The core will call this function upon completion
  15715. * or failure of CC.
  15716. *
  15717. * \return Nothing
  15718. */
  15719. static void dahdi_pri_cc_agent_destructor(struct ast_cc_agent *agent)
  15720. {
  15721. sig_pri_cc_agent_destructor(agent);
  15722. ast_module_unref(ast_module_info->self);
  15723. }
  15724. #endif /* defined(HAVE_PRI_CCSS) */
  15725. #endif /* defined(HAVE_PRI) */
  15726. #if defined(HAVE_PRI)
  15727. #if defined(HAVE_PRI_CCSS)
  15728. static struct ast_cc_agent_callbacks dahdi_pri_cc_agent_callbacks = {
  15729. .type = dahdi_pri_cc_type,
  15730. .init = dahdi_pri_cc_agent_init,
  15731. .start_offer_timer = sig_pri_cc_agent_start_offer_timer,
  15732. .stop_offer_timer = sig_pri_cc_agent_stop_offer_timer,
  15733. .respond = sig_pri_cc_agent_req_rsp,
  15734. .status_request = sig_pri_cc_agent_status_req,
  15735. .stop_ringing = sig_pri_cc_agent_stop_ringing,
  15736. .party_b_free = sig_pri_cc_agent_party_b_free,
  15737. .start_monitoring = sig_pri_cc_agent_start_monitoring,
  15738. .callee_available = sig_pri_cc_agent_callee_available,
  15739. .destructor = dahdi_pri_cc_agent_destructor,
  15740. };
  15741. #endif /* defined(HAVE_PRI_CCSS) */
  15742. #endif /* defined(HAVE_PRI) */
  15743. #if defined(HAVE_PRI)
  15744. #if defined(HAVE_PRI_CCSS)
  15745. static struct ast_cc_monitor_callbacks dahdi_pri_cc_monitor_callbacks = {
  15746. .type = dahdi_pri_cc_type,
  15747. .request_cc = sig_pri_cc_monitor_req_cc,
  15748. .suspend = sig_pri_cc_monitor_suspend,
  15749. .unsuspend = sig_pri_cc_monitor_unsuspend,
  15750. .status_response = sig_pri_cc_monitor_status_rsp,
  15751. .cancel_available_timer = sig_pri_cc_monitor_cancel_available_timer,
  15752. .destructor = sig_pri_cc_monitor_destructor,
  15753. };
  15754. #endif /* defined(HAVE_PRI_CCSS) */
  15755. #endif /* defined(HAVE_PRI) */
  15756. static int __unload_module(void)
  15757. {
  15758. struct dahdi_pvt *p;
  15759. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  15760. int i, j;
  15761. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  15762. #ifdef HAVE_PRI
  15763. for (i = 0; i < NUM_SPANS; i++) {
  15764. if (pris[i].pri.master != AST_PTHREADT_NULL) {
  15765. pthread_cancel(pris[i].pri.master);
  15766. pthread_kill(pris[i].pri.master, SIGURG);
  15767. }
  15768. }
  15769. ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
  15770. ast_unregister_application(dahdi_send_keypad_facility_app);
  15771. #ifdef HAVE_PRI_PROG_W_CAUSE
  15772. ast_unregister_application(dahdi_send_callrerouting_facility_app);
  15773. #endif
  15774. #endif
  15775. #if defined(HAVE_SS7)
  15776. for (i = 0; i < NUM_SPANS; i++) {
  15777. if (linksets[i].ss7.master != AST_PTHREADT_NULL) {
  15778. pthread_cancel(linksets[i].ss7.master);
  15779. pthread_kill(linksets[i].ss7.master, SIGURG);
  15780. }
  15781. }
  15782. ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
  15783. #endif /* defined(HAVE_SS7) */
  15784. #if defined(HAVE_OPENR2)
  15785. dahdi_r2_destroy_links();
  15786. ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
  15787. ast_unregister_application(dahdi_accept_r2_call_app);
  15788. #endif
  15789. ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));
  15790. ast_manager_unregister("DAHDIDialOffhook");
  15791. ast_manager_unregister("DAHDIHangup");
  15792. ast_manager_unregister("DAHDITransfer");
  15793. ast_manager_unregister("DAHDIDNDoff");
  15794. ast_manager_unregister("DAHDIDNDon");
  15795. ast_manager_unregister("DAHDIShowChannels");
  15796. ast_manager_unregister("DAHDIRestart");
  15797. #if defined(HAVE_PRI)
  15798. ast_manager_unregister("PRIShowSpans");
  15799. ast_manager_unregister("PRIDebugSet");
  15800. ast_manager_unregister("PRIDebugFileSet");
  15801. ast_manager_unregister("PRIDebugFileUnset");
  15802. #endif /* defined(HAVE_PRI) */
  15803. ast_data_unregister(NULL);
  15804. ast_channel_unregister(&dahdi_tech);
  15805. /* Hangup all interfaces if they have an owner */
  15806. ast_mutex_lock(&iflock);
  15807. for (p = iflist; p; p = p->next) {
  15808. if (p->owner)
  15809. ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
  15810. }
  15811. ast_mutex_unlock(&iflock);
  15812. ast_mutex_lock(&monlock);
  15813. if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
  15814. pthread_cancel(monitor_thread);
  15815. pthread_kill(monitor_thread, SIGURG);
  15816. pthread_join(monitor_thread, NULL);
  15817. }
  15818. monitor_thread = AST_PTHREADT_STOP;
  15819. ast_mutex_unlock(&monlock);
  15820. destroy_all_channels();
  15821. #if defined(HAVE_PRI)
  15822. for (i = 0; i < NUM_SPANS; i++) {
  15823. if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
  15824. pthread_join(pris[i].pri.master, NULL);
  15825. }
  15826. for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) {
  15827. dahdi_close_pri_fd(&(pris[i]), j);
  15828. }
  15829. sig_pri_stop_pri(&pris[i].pri);
  15830. }
  15831. #if defined(HAVE_PRI_CCSS)
  15832. ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks);
  15833. ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks);
  15834. #endif /* defined(HAVE_PRI_CCSS) */
  15835. sig_pri_unload();
  15836. #endif
  15837. #if defined(HAVE_SS7)
  15838. for (i = 0; i < NUM_SPANS; i++) {
  15839. if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
  15840. pthread_join(linksets[i].ss7.master, NULL);
  15841. }
  15842. for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) {
  15843. dahdi_close_ss7_fd(&(linksets[i]), j);
  15844. }
  15845. if (linksets[i].ss7.ss7) {
  15846. ss7_destroy(linksets[i].ss7.ss7);
  15847. linksets[i].ss7.ss7 = NULL;
  15848. }
  15849. }
  15850. #endif /* defined(HAVE_SS7) */
  15851. ast_cond_destroy(&ss_thread_complete);
  15852. dahdi_native_unload();
  15853. ao2_cleanup(dahdi_tech.capabilities);
  15854. dahdi_tech.capabilities = NULL;
  15855. STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
  15856. return 0;
  15857. }
  15858. static int unload_module(void)
  15859. {
  15860. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  15861. int y;
  15862. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  15863. #ifdef HAVE_PRI
  15864. for (y = 0; y < NUM_SPANS; y++)
  15865. ast_mutex_destroy(&pris[y].pri.lock);
  15866. #endif
  15867. #if defined(HAVE_SS7)
  15868. for (y = 0; y < NUM_SPANS; y++)
  15869. ast_mutex_destroy(&linksets[y].ss7.lock);
  15870. #endif /* defined(HAVE_SS7) */
  15871. return __unload_module();
  15872. }
  15873. static void string_replace(char *str, int char1, int char2)
  15874. {
  15875. for (; *str; str++) {
  15876. if (*str == char1) {
  15877. *str = char2;
  15878. }
  15879. }
  15880. }
  15881. static char *parse_spanchan(char *chanstr, char **subdir)
  15882. {
  15883. char *p;
  15884. if ((p = strrchr(chanstr, '!')) == NULL) {
  15885. *subdir = NULL;
  15886. return chanstr;
  15887. }
  15888. *p++ = '\0';
  15889. string_replace(chanstr, '!', '/');
  15890. *subdir = chanstr;
  15891. return p;
  15892. }
  15893. static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
  15894. {
  15895. char *c, *chan;
  15896. char *subdir;
  15897. int x, start, finish;
  15898. struct dahdi_pvt *tmp;
  15899. if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) {
  15900. ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
  15901. return -1;
  15902. }
  15903. c = ast_strdupa(value);
  15904. c = parse_spanchan(c, &subdir);
  15905. while ((chan = strsep(&c, ","))) {
  15906. if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
  15907. /* Range */
  15908. } else if (sscanf(chan, "%30d", &start)) {
  15909. /* Just one */
  15910. finish = start;
  15911. } else if (!strcasecmp(chan, "pseudo")) {
  15912. finish = start = CHAN_PSEUDO;
  15913. } else {
  15914. ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
  15915. return -1;
  15916. }
  15917. if (finish < start) {
  15918. ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
  15919. x = finish;
  15920. finish = start;
  15921. start = x;
  15922. }
  15923. for (x = start; x <= finish; x++) {
  15924. char fn[PATH_MAX];
  15925. int real_channel = x;
  15926. if (!ast_strlen_zero(subdir)) {
  15927. real_channel = device2chan(subdir, x, fn, sizeof(fn));
  15928. if (real_channel < 0) {
  15929. if (conf->ignore_failed_channels) {
  15930. ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n",
  15931. subdir, x, real_channel);
  15932. continue;
  15933. } else {
  15934. ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n",
  15935. subdir, x, real_channel);
  15936. return -1;
  15937. }
  15938. }
  15939. }
  15940. if (conf->wanted_channels_start &&
  15941. (real_channel < conf->wanted_channels_start ||
  15942. real_channel > conf->wanted_channels_end)
  15943. ) {
  15944. continue;
  15945. }
  15946. tmp = mkintf(real_channel, conf, reload);
  15947. if (tmp) {
  15948. ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig));
  15949. } else {
  15950. ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
  15951. (reload == 1) ? "reconfigure" : "register", value);
  15952. return -1;
  15953. }
  15954. if (real_channel == CHAN_PSEUDO) {
  15955. has_pseudo = 1;
  15956. }
  15957. }
  15958. }
  15959. return 0;
  15960. }
  15961. /** The length of the parameters list of 'dahdichan'.
  15962. * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
  15963. #define MAX_CHANLIST_LEN 80
  15964. static void process_echocancel(struct dahdi_chan_conf *confp, const char *data, unsigned int line)
  15965. {
  15966. char *parse = ast_strdupa(data);
  15967. char *params[DAHDI_MAX_ECHOCANPARAMS + 1];
  15968. unsigned int param_count;
  15969. unsigned int x;
  15970. if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params))))
  15971. return;
  15972. memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel));
  15973. /* first parameter is tap length, process it here */
  15974. x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]);
  15975. if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
  15976. confp->chan.echocancel.head.tap_length = x;
  15977. else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0])))
  15978. confp->chan.echocancel.head.tap_length = 128;
  15979. /* now process any remaining parameters */
  15980. for (x = 1; x < param_count; x++) {
  15981. struct {
  15982. char *name;
  15983. char *value;
  15984. } param;
  15985. if (ast_app_separate_args(params[x], '=', (char **) &param, 2) < 1) {
  15986. ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
  15987. continue;
  15988. }
  15989. if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) {
  15990. ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
  15991. continue;
  15992. }
  15993. strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name);
  15994. if (param.value) {
  15995. if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) {
  15996. ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
  15997. continue;
  15998. }
  15999. }
  16000. confp->chan.echocancel.head.param_count++;
  16001. }
  16002. }
  16003. #if defined(HAVE_PRI)
  16004. #if defined(HAVE_PRI_DISPLAY_TEXT)
  16005. /*!
  16006. * \internal
  16007. * \brief Determine the configured display text options.
  16008. * \since 10.0
  16009. *
  16010. * \param value Configuration value string.
  16011. *
  16012. * \return Configured display text option flags.
  16013. */
  16014. static unsigned long dahdi_display_text_option(const char *value)
  16015. {
  16016. char *val_str;
  16017. char *opt_str;
  16018. unsigned long options;
  16019. options = 0;
  16020. val_str = ast_strdupa(value);
  16021. for (;;) {
  16022. opt_str = strsep(&val_str, ",");
  16023. if (!opt_str) {
  16024. break;
  16025. }
  16026. opt_str = ast_strip(opt_str);
  16027. if (!*opt_str) {
  16028. continue;
  16029. }
  16030. if (!strcasecmp(opt_str, "block")) {
  16031. options |= PRI_DISPLAY_OPTION_BLOCK;
  16032. } else if (!strcasecmp(opt_str, "name_initial")) {
  16033. options |= PRI_DISPLAY_OPTION_NAME_INITIAL;
  16034. } else if (!strcasecmp(opt_str, "name_update")) {
  16035. options |= PRI_DISPLAY_OPTION_NAME_UPDATE;
  16036. } else if (!strcasecmp(opt_str, "name")) {
  16037. options |= (PRI_DISPLAY_OPTION_NAME_INITIAL | PRI_DISPLAY_OPTION_NAME_UPDATE);
  16038. } else if (!strcasecmp(opt_str, "text")) {
  16039. options |= PRI_DISPLAY_OPTION_TEXT;
  16040. }
  16041. }
  16042. return options;
  16043. }
  16044. #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
  16045. #endif /* defined(HAVE_PRI) */
  16046. #if defined(HAVE_PRI)
  16047. #if defined(HAVE_PRI_DATETIME_SEND)
  16048. /*!
  16049. * \internal
  16050. * \brief Determine the configured date/time send policy option.
  16051. * \since 10.0
  16052. *
  16053. * \param value Configuration value string.
  16054. *
  16055. * \return Configured date/time send policy option.
  16056. */
  16057. static int dahdi_datetime_send_option(const char *value)
  16058. {
  16059. int option;
  16060. option = PRI_DATE_TIME_SEND_DEFAULT;
  16061. if (ast_false(value)) {
  16062. option = PRI_DATE_TIME_SEND_NO;
  16063. } else if (!strcasecmp(value, "date")) {
  16064. option = PRI_DATE_TIME_SEND_DATE;
  16065. } else if (!strcasecmp(value, "date_hh")) {
  16066. option = PRI_DATE_TIME_SEND_DATE_HH;
  16067. } else if (!strcasecmp(value, "date_hhmm")) {
  16068. option = PRI_DATE_TIME_SEND_DATE_HHMM;
  16069. } else if (!strcasecmp(value, "date_hhmmss")) {
  16070. option = PRI_DATE_TIME_SEND_DATE_HHMMSS;
  16071. }
  16072. return option;
  16073. }
  16074. #endif /* defined(HAVE_PRI_DATETIME_SEND) */
  16075. #endif /* defined(HAVE_PRI) */
  16076. /*! process_dahdi() - ignore keyword 'channel' and similar */
  16077. #define PROC_DAHDI_OPT_NOCHAN (1 << 0)
  16078. /*! process_dahdi() - No warnings on non-existing cofiguration keywords */
  16079. #define PROC_DAHDI_OPT_NOWARN (1 << 1)
  16080. static void parse_busy_pattern(struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence)
  16081. {
  16082. int count_pattern = 0;
  16083. int norval = 0;
  16084. char *temp = NULL;
  16085. for (; ;) {
  16086. /* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */
  16087. if (!sscanf(v->value, "%30d", &norval) && count_pattern == 0) {
  16088. ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
  16089. break;
  16090. }
  16091. busy_cadence->pattern[count_pattern] = norval;
  16092. count_pattern++;
  16093. if (count_pattern == 4) {
  16094. break;
  16095. }
  16096. temp = strchr(v->value, ',');
  16097. if (temp == NULL) {
  16098. break;
  16099. }
  16100. v->value = temp + 1;
  16101. }
  16102. busy_cadence->length = count_pattern;
  16103. if (count_pattern % 2 != 0) {
  16104. /* The pattern length must be divisible by two */
  16105. ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
  16106. }
  16107. }
  16108. static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
  16109. {
  16110. struct dahdi_pvt *tmp;
  16111. int y;
  16112. struct ast_variable *dahdichan = NULL;
  16113. for (; v; v = v->next) {
  16114. if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
  16115. continue;
  16116. /* Create the interface list */
  16117. if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) {
  16118. if (options & PROC_DAHDI_OPT_NOCHAN) {
  16119. ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value);
  16120. continue;
  16121. }
  16122. if (build_channels(confp, v->value, reload, v->lineno)) {
  16123. if (confp->ignore_failed_channels) {
  16124. ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value);
  16125. continue;
  16126. } else {
  16127. return -1;
  16128. }
  16129. }
  16130. ast_debug(1, "Channel '%s' configured.\n", v->value);
  16131. } else if (!strcasecmp(v->name, "ignore_failed_channels")) {
  16132. confp->ignore_failed_channels = ast_true(v->value);
  16133. } else if (!strcasecmp(v->name, "buffers")) {
  16134. if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
  16135. ast_log(LOG_WARNING, "Using default buffer policy.\n");
  16136. confp->chan.buf_no = numbufs;
  16137. confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
  16138. }
  16139. } else if (!strcasecmp(v->name, "faxbuffers")) {
  16140. if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
  16141. confp->chan.usefaxbuffers = 1;
  16142. }
  16143. } else if (!strcasecmp(v->name, "dahdichan")) {
  16144. /* Only process the last dahdichan value. */
  16145. dahdichan = v;
  16146. } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
  16147. usedistinctiveringdetection = ast_true(v->value);
  16148. } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
  16149. distinctiveringaftercid = ast_true(v->value);
  16150. } else if (!strcasecmp(v->name, "dring1context")) {
  16151. ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData));
  16152. } else if (!strcasecmp(v->name, "dring2context")) {
  16153. ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData));
  16154. } else if (!strcasecmp(v->name, "dring3context")) {
  16155. ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData));
  16156. } else if (!strcasecmp(v->name, "dring1range")) {
  16157. confp->chan.drings.ringnum[0].range = atoi(v->value);
  16158. } else if (!strcasecmp(v->name, "dring2range")) {
  16159. confp->chan.drings.ringnum[1].range = atoi(v->value);
  16160. } else if (!strcasecmp(v->name, "dring3range")) {
  16161. confp->chan.drings.ringnum[2].range = atoi(v->value);
  16162. } else if (!strcasecmp(v->name, "dring1")) {
  16163. sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &confp->chan.drings.ringnum[0].ring[2]);
  16164. } else if (!strcasecmp(v->name, "dring2")) {
  16165. sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[1].ring[0], &confp->chan.drings.ringnum[1].ring[1], &confp->chan.drings.ringnum[1].ring[2]);
  16166. } else if (!strcasecmp(v->name, "dring3")) {
  16167. sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[2].ring[0], &confp->chan.drings.ringnum[2].ring[1], &confp->chan.drings.ringnum[2].ring[2]);
  16168. } else if (!strcasecmp(v->name, "usecallerid")) {
  16169. confp->chan.use_callerid = ast_true(v->value);
  16170. } else if (!strcasecmp(v->name, "cidsignalling")) {
  16171. if (!strcasecmp(v->value, "bell"))
  16172. confp->chan.cid_signalling = CID_SIG_BELL;
  16173. else if (!strcasecmp(v->value, "v23"))
  16174. confp->chan.cid_signalling = CID_SIG_V23;
  16175. else if (!strcasecmp(v->value, "dtmf"))
  16176. confp->chan.cid_signalling = CID_SIG_DTMF;
  16177. else if (!strcasecmp(v->value, "smdi"))
  16178. confp->chan.cid_signalling = CID_SIG_SMDI;
  16179. else if (!strcasecmp(v->value, "v23_jp"))
  16180. confp->chan.cid_signalling = CID_SIG_V23_JP;
  16181. else if (ast_true(v->value))
  16182. confp->chan.cid_signalling = CID_SIG_BELL;
  16183. } else if (!strcasecmp(v->name, "cidstart")) {
  16184. if (!strcasecmp(v->value, "ring"))
  16185. confp->chan.cid_start = CID_START_RING;
  16186. else if (!strcasecmp(v->value, "polarity_in"))
  16187. confp->chan.cid_start = CID_START_POLARITY_IN;
  16188. else if (!strcasecmp(v->value, "polarity"))
  16189. confp->chan.cid_start = CID_START_POLARITY;
  16190. else if (!strcasecmp(v->value, "dtmf"))
  16191. confp->chan.cid_start = CID_START_DTMF_NOALERT;
  16192. else if (ast_true(v->value))
  16193. confp->chan.cid_start = CID_START_RING;
  16194. } else if (!strcasecmp(v->name, "threewaycalling")) {
  16195. confp->chan.threewaycalling = ast_true(v->value);
  16196. } else if (!strcasecmp(v->name, "cancallforward")) {
  16197. confp->chan.cancallforward = ast_true(v->value);
  16198. } else if (!strcasecmp(v->name, "relaxdtmf")) {
  16199. if (ast_true(v->value))
  16200. confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
  16201. else
  16202. confp->chan.dtmfrelax = 0;
  16203. } else if (!strcasecmp(v->name, "mailbox")) {
  16204. ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
  16205. } else if (!strcasecmp(v->name, "description")) {
  16206. ast_copy_string(confp->chan.description, v->value, sizeof(confp->chan.description));
  16207. } else if (!strcasecmp(v->name, "hasvoicemail")) {
  16208. if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
  16209. /*
  16210. * hasvoicemail is a users.conf legacy voicemail enable method.
  16211. * hasvoicemail is only going to work for app_voicemail mailboxes.
  16212. */
  16213. if (strchr(cat, '@')) {
  16214. ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
  16215. } else {
  16216. snprintf(confp->chan.mailbox, sizeof(confp->chan.mailbox),
  16217. "%s@default", cat);
  16218. }
  16219. }
  16220. } else if (!strcasecmp(v->name, "adsi")) {
  16221. confp->chan.adsi = ast_true(v->value);
  16222. } else if (!strcasecmp(v->name, "usesmdi")) {
  16223. confp->chan.use_smdi = ast_true(v->value);
  16224. } else if (!strcasecmp(v->name, "smdiport")) {
  16225. ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
  16226. } else if (!strcasecmp(v->name, "transfer")) {
  16227. confp->chan.transfer = ast_true(v->value);
  16228. } else if (!strcasecmp(v->name, "canpark")) {
  16229. confp->chan.canpark = ast_true(v->value);
  16230. } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
  16231. confp->chan.echocanbridged = ast_true(v->value);
  16232. } else if (!strcasecmp(v->name, "busydetect")) {
  16233. confp->chan.busydetect = ast_true(v->value);
  16234. } else if (!strcasecmp(v->name, "busycount")) {
  16235. confp->chan.busycount = atoi(v->value);
  16236. } else if (!strcasecmp(v->name, "busypattern")) {
  16237. parse_busy_pattern(v, &confp->chan.busy_cadence);
  16238. } else if (!strcasecmp(v->name, "callprogress")) {
  16239. confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;
  16240. if (ast_true(v->value))
  16241. confp->chan.callprogress |= CALLPROGRESS_PROGRESS;
  16242. } else if (!strcasecmp(v->name, "waitfordialtone")) {
  16243. confp->chan.waitfordialtone = atoi(v->value);
  16244. } else if (!strcasecmp(v->name, "dialtone_detect")) {
  16245. if (!strcasecmp(v->value, "always")) {
  16246. confp->chan.dialtone_detect = -1;
  16247. } else if (ast_true(v->value)) {
  16248. confp->chan.dialtone_detect = DEFAULT_DIALTONE_DETECT_TIMEOUT;
  16249. } else if (ast_false(v->value)) {
  16250. confp->chan.dialtone_detect = 0;
  16251. } else {
  16252. confp->chan.dialtone_detect = ast_strlen_zero(v->value) ? 0 : (8 * atoi(v->value)) / READ_SIZE;
  16253. }
  16254. } else if (!strcasecmp(v->name, "faxdetect")) {
  16255. confp->chan.callprogress &= ~CALLPROGRESS_FAX;
  16256. if (!strcasecmp(v->value, "incoming")) {
  16257. confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING;
  16258. } else if (!strcasecmp(v->value, "outgoing")) {
  16259. confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING;
  16260. } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
  16261. confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING;
  16262. } else if (!strcasecmp(v->name, "echocancel")) {
  16263. process_echocancel(confp, v->value, v->lineno);
  16264. } else if (!strcasecmp(v->name, "echotraining")) {
  16265. if (sscanf(v->value, "%30d", &y) == 1) {
  16266. if ((y < 10) || (y > 4000)) {
  16267. ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno);
  16268. } else {
  16269. confp->chan.echotraining = y;
  16270. }
  16271. } else if (ast_true(v->value)) {
  16272. confp->chan.echotraining = 400;
  16273. } else
  16274. confp->chan.echotraining = 0;
  16275. } else if (!strcasecmp(v->name, "hidecallerid")) {
  16276. confp->chan.hidecallerid = ast_true(v->value);
  16277. } else if (!strcasecmp(v->name, "hidecalleridname")) {
  16278. confp->chan.hidecalleridname = ast_true(v->value);
  16279. } else if (!strcasecmp(v->name, "pulsedial")) {
  16280. confp->chan.pulse = ast_true(v->value);
  16281. } else if (!strcasecmp(v->name, "callreturn")) {
  16282. confp->chan.callreturn = ast_true(v->value);
  16283. } else if (!strcasecmp(v->name, "callwaiting")) {
  16284. confp->chan.callwaiting = ast_true(v->value);
  16285. } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
  16286. confp->chan.callwaitingcallerid = ast_true(v->value);
  16287. } else if (!strcasecmp(v->name, "context")) {
  16288. ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
  16289. } else if (!strcasecmp(v->name, "language")) {
  16290. ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
  16291. } else if (!strcasecmp(v->name, "progzone")) {
  16292. ast_copy_string(progzone, v->value, sizeof(progzone));
  16293. } else if (!strcasecmp(v->name, "mohinterpret")
  16294. ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
  16295. ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
  16296. } else if (!strcasecmp(v->name, "mohsuggest")) {
  16297. ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
  16298. } else if (!strcasecmp(v->name, "parkinglot")) {
  16299. ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot));
  16300. } else if (!strcasecmp(v->name, "stripmsd")) {
  16301. ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name);
  16302. confp->chan.stripmsd = atoi(v->value);
  16303. } else if (!strcasecmp(v->name, "jitterbuffers")) {
  16304. numbufs = atoi(v->value);
  16305. } else if (!strcasecmp(v->name, "group")) {
  16306. confp->chan.group = ast_get_group(v->value);
  16307. } else if (!strcasecmp(v->name, "callgroup")) {
  16308. if (!strcasecmp(v->value, "none"))
  16309. confp->chan.callgroup = 0;
  16310. else
  16311. confp->chan.callgroup = ast_get_group(v->value);
  16312. } else if (!strcasecmp(v->name, "pickupgroup")) {
  16313. if (!strcasecmp(v->value, "none"))
  16314. confp->chan.pickupgroup = 0;
  16315. else
  16316. confp->chan.pickupgroup = ast_get_group(v->value);
  16317. } else if (!strcasecmp(v->name, "namedcallgroup")) {
  16318. confp->chan.named_callgroups = ast_get_namedgroups(v->value);
  16319. } else if (!strcasecmp(v->name, "namedpickupgroup")) {
  16320. confp->chan.named_pickupgroups = ast_get_namedgroups(v->value);
  16321. } else if (!strcasecmp(v->name, "setvar")) {
  16322. char *varname = ast_strdupa(v->value), *varval = NULL;
  16323. struct ast_variable *tmpvar;
  16324. if (varname && (varval = strchr(varname, '='))) {
  16325. *varval++ = '\0';
  16326. if ((tmpvar = ast_variable_new(varname, varval, ""))) {
  16327. tmpvar->next = confp->chan.vars;
  16328. confp->chan.vars = tmpvar;
  16329. }
  16330. }
  16331. } else if (!strcasecmp(v->name, "immediate")) {
  16332. confp->chan.immediate = ast_true(v->value);
  16333. } else if (!strcasecmp(v->name, "transfertobusy")) {
  16334. confp->chan.transfertobusy = ast_true(v->value);
  16335. } else if (!strcasecmp(v->name, "mwimonitor")) {
  16336. confp->chan.mwimonitor_neon = 0;
  16337. confp->chan.mwimonitor_fsk = 0;
  16338. confp->chan.mwimonitor_rpas = 0;
  16339. if (strcasestr(v->value, "fsk")) {
  16340. confp->chan.mwimonitor_fsk = 1;
  16341. }
  16342. if (strcasestr(v->value, "rpas")) {
  16343. confp->chan.mwimonitor_rpas = 1;
  16344. }
  16345. if (strcasestr(v->value, "neon")) {
  16346. confp->chan.mwimonitor_neon = 1;
  16347. }
  16348. /* If set to true or yes, assume that simple fsk is desired */
  16349. if (ast_true(v->value)) {
  16350. confp->chan.mwimonitor_fsk = 1;
  16351. }
  16352. } else if (!strcasecmp(v->name, "hwrxgain")) {
  16353. confp->chan.hwrxgain_enabled = 0;
  16354. if (strcasecmp(v->value, "disabled")) {
  16355. if (sscanf(v->value, "%30f", &confp->chan.hwrxgain) == 1) {
  16356. confp->chan.hwrxgain_enabled = 1;
  16357. } else {
  16358. ast_log(LOG_WARNING, "Invalid hwrxgain: %s at line %d.\n", v->value, v->lineno);
  16359. }
  16360. }
  16361. } else if (!strcasecmp(v->name, "hwtxgain")) {
  16362. confp->chan.hwtxgain_enabled = 0;
  16363. if (strcasecmp(v->value, "disabled")) {
  16364. if (sscanf(v->value, "%30f", &confp->chan.hwtxgain) == 1) {
  16365. confp->chan.hwtxgain_enabled = 1;
  16366. } else {
  16367. ast_log(LOG_WARNING, "Invalid hwtxgain: %s at line %d.\n", v->value, v->lineno);
  16368. }
  16369. }
  16370. } else if (!strcasecmp(v->name, "cid_rxgain")) {
  16371. if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) {
  16372. ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno);
  16373. }
  16374. } else if (!strcasecmp(v->name, "rxgain")) {
  16375. if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
  16376. ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno);
  16377. }
  16378. } else if (!strcasecmp(v->name, "txgain")) {
  16379. if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
  16380. ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno);
  16381. }
  16382. } else if (!strcasecmp(v->name, "txdrc")) {
  16383. if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) {
  16384. ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value);
  16385. }
  16386. } else if (!strcasecmp(v->name, "rxdrc")) {
  16387. if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) {
  16388. ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value);
  16389. }
  16390. } else if (!strcasecmp(v->name, "tonezone")) {
  16391. if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
  16392. ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno);
  16393. }
  16394. } else if (!strcasecmp(v->name, "callerid")) {
  16395. if (!strcasecmp(v->value, "asreceived")) {
  16396. confp->chan.cid_num[0] = '\0';
  16397. confp->chan.cid_name[0] = '\0';
  16398. } else {
  16399. ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
  16400. }
  16401. } else if (!strcasecmp(v->name, "fullname")) {
  16402. ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
  16403. } else if (!strcasecmp(v->name, "cid_number")) {
  16404. ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
  16405. } else if (!strcasecmp(v->name, "cid_tag")) {
  16406. ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag));
  16407. } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) {
  16408. confp->chan.dahditrcallerid = ast_true(v->value);
  16409. } else if (!strcasecmp(v->name, "restrictcid")) {
  16410. confp->chan.restrictcid = ast_true(v->value);
  16411. } else if (!strcasecmp(v->name, "usecallingpres")) {
  16412. confp->chan.use_callingpres = ast_true(v->value);
  16413. } else if (!strcasecmp(v->name, "accountcode")) {
  16414. ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
  16415. } else if (!strcasecmp(v->name, "amaflags")) {
  16416. y = ast_channel_string2amaflag(v->value);
  16417. if (y < 0)
  16418. ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno);
  16419. else
  16420. confp->chan.amaflags = y;
  16421. } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
  16422. confp->chan.polarityonanswerdelay = atoi(v->value);
  16423. } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
  16424. confp->chan.answeronpolarityswitch = ast_true(v->value);
  16425. } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
  16426. confp->chan.hanguponpolarityswitch = ast_true(v->value);
  16427. } else if (!strcasecmp(v->name, "sendcalleridafter")) {
  16428. confp->chan.sendcalleridafter = atoi(v->value);
  16429. } else if (!strcasecmp(v->name, "mwimonitornotify")) {
  16430. ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify));
  16431. } else if (ast_cc_is_config_param(v->name)) {
  16432. ast_cc_set_param(confp->chan.cc_params, v->name, v->value);
  16433. } else if (!strcasecmp(v->name, "mwisendtype")) {
  16434. #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */
  16435. if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */
  16436. mwisend_rpas = 1;
  16437. } else {
  16438. mwisend_rpas = 0;
  16439. }
  16440. #else
  16441. /* Default is fsk, to turn it off you must specify nofsk */
  16442. memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting));
  16443. if (strcasestr(v->value, "nofsk")) { /* NoFSK */
  16444. confp->chan.mwisend_fsk = 0;
  16445. } else { /* Default FSK */
  16446. confp->chan.mwisend_fsk = 1;
  16447. }
  16448. if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */
  16449. confp->chan.mwisend_rpas = 1;
  16450. } else {
  16451. confp->chan.mwisend_rpas = 0;
  16452. }
  16453. if (strcasestr(v->value, "lrev")) { /* Line Reversal */
  16454. confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
  16455. }
  16456. if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */
  16457. confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
  16458. }
  16459. if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ) { /* 90V DC pulses */
  16460. confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
  16461. }
  16462. #endif
  16463. } else if (reload != 1) {
  16464. if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
  16465. int orig_radio = confp->chan.radio;
  16466. int orig_outsigmod = confp->chan.outsigmod;
  16467. int orig_auto = confp->is_sig_auto;
  16468. confp->chan.radio = 0;
  16469. confp->chan.outsigmod = -1;
  16470. confp->is_sig_auto = 0;
  16471. if (!strcasecmp(v->value, "em")) {
  16472. confp->chan.sig = SIG_EM;
  16473. } else if (!strcasecmp(v->value, "em_e1")) {
  16474. confp->chan.sig = SIG_EM_E1;
  16475. } else if (!strcasecmp(v->value, "em_w")) {
  16476. confp->chan.sig = SIG_EMWINK;
  16477. } else if (!strcasecmp(v->value, "fxs_ls")) {
  16478. confp->chan.sig = SIG_FXSLS;
  16479. } else if (!strcasecmp(v->value, "fxs_gs")) {
  16480. confp->chan.sig = SIG_FXSGS;
  16481. } else if (!strcasecmp(v->value, "fxs_ks")) {
  16482. confp->chan.sig = SIG_FXSKS;
  16483. } else if (!strcasecmp(v->value, "fxo_ls")) {
  16484. confp->chan.sig = SIG_FXOLS;
  16485. } else if (!strcasecmp(v->value, "fxo_gs")) {
  16486. confp->chan.sig = SIG_FXOGS;
  16487. } else if (!strcasecmp(v->value, "fxo_ks")) {
  16488. confp->chan.sig = SIG_FXOKS;
  16489. } else if (!strcasecmp(v->value, "fxs_rx")) {
  16490. confp->chan.sig = SIG_FXSKS;
  16491. confp->chan.radio = 1;
  16492. } else if (!strcasecmp(v->value, "fxo_rx")) {
  16493. confp->chan.sig = SIG_FXOLS;
  16494. confp->chan.radio = 1;
  16495. } else if (!strcasecmp(v->value, "fxs_tx")) {
  16496. confp->chan.sig = SIG_FXSLS;
  16497. confp->chan.radio = 1;
  16498. } else if (!strcasecmp(v->value, "fxo_tx")) {
  16499. confp->chan.sig = SIG_FXOGS;
  16500. confp->chan.radio = 1;
  16501. } else if (!strcasecmp(v->value, "em_rx")) {
  16502. confp->chan.sig = SIG_EM;
  16503. confp->chan.radio = 1;
  16504. } else if (!strcasecmp(v->value, "em_tx")) {
  16505. confp->chan.sig = SIG_EM;
  16506. confp->chan.radio = 1;
  16507. } else if (!strcasecmp(v->value, "em_rxtx")) {
  16508. confp->chan.sig = SIG_EM;
  16509. confp->chan.radio = 2;
  16510. } else if (!strcasecmp(v->value, "em_txrx")) {
  16511. confp->chan.sig = SIG_EM;
  16512. confp->chan.radio = 2;
  16513. } else if (!strcasecmp(v->value, "sf")) {
  16514. confp->chan.sig = SIG_SF;
  16515. } else if (!strcasecmp(v->value, "sf_w")) {
  16516. confp->chan.sig = SIG_SFWINK;
  16517. } else if (!strcasecmp(v->value, "sf_featd")) {
  16518. confp->chan.sig = SIG_FEATD;
  16519. } else if (!strcasecmp(v->value, "sf_featdmf")) {
  16520. confp->chan.sig = SIG_FEATDMF;
  16521. } else if (!strcasecmp(v->value, "sf_featb")) {
  16522. confp->chan.sig = SIG_SF_FEATB;
  16523. } else if (!strcasecmp(v->value, "sf")) {
  16524. confp->chan.sig = SIG_SF;
  16525. } else if (!strcasecmp(v->value, "sf_rx")) {
  16526. confp->chan.sig = SIG_SF;
  16527. confp->chan.radio = 1;
  16528. } else if (!strcasecmp(v->value, "sf_tx")) {
  16529. confp->chan.sig = SIG_SF;
  16530. confp->chan.radio = 1;
  16531. } else if (!strcasecmp(v->value, "sf_rxtx")) {
  16532. confp->chan.sig = SIG_SF;
  16533. confp->chan.radio = 2;
  16534. } else if (!strcasecmp(v->value, "sf_txrx")) {
  16535. confp->chan.sig = SIG_SF;
  16536. confp->chan.radio = 2;
  16537. } else if (!strcasecmp(v->value, "featd")) {
  16538. confp->chan.sig = SIG_FEATD;
  16539. } else if (!strcasecmp(v->value, "featdmf")) {
  16540. confp->chan.sig = SIG_FEATDMF;
  16541. } else if (!strcasecmp(v->value, "featdmf_ta")) {
  16542. confp->chan.sig = SIG_FEATDMF_TA;
  16543. } else if (!strcasecmp(v->value, "e911")) {
  16544. confp->chan.sig = SIG_E911;
  16545. } else if (!strcasecmp(v->value, "fgccama")) {
  16546. confp->chan.sig = SIG_FGC_CAMA;
  16547. } else if (!strcasecmp(v->value, "fgccamamf")) {
  16548. confp->chan.sig = SIG_FGC_CAMAMF;
  16549. } else if (!strcasecmp(v->value, "featb")) {
  16550. confp->chan.sig = SIG_FEATB;
  16551. #ifdef HAVE_PRI
  16552. } else if (!strcasecmp(v->value, "pri_net")) {
  16553. confp->chan.sig = SIG_PRI;
  16554. confp->pri.pri.nodetype = PRI_NETWORK;
  16555. } else if (!strcasecmp(v->value, "pri_cpe")) {
  16556. confp->chan.sig = SIG_PRI;
  16557. confp->pri.pri.nodetype = PRI_CPE;
  16558. } else if (!strcasecmp(v->value, "bri_cpe")) {
  16559. confp->chan.sig = SIG_BRI;
  16560. confp->pri.pri.nodetype = PRI_CPE;
  16561. } else if (!strcasecmp(v->value, "bri_net")) {
  16562. confp->chan.sig = SIG_BRI;
  16563. confp->pri.pri.nodetype = PRI_NETWORK;
  16564. } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
  16565. confp->chan.sig = SIG_BRI_PTMP;
  16566. confp->pri.pri.nodetype = PRI_CPE;
  16567. } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
  16568. #if defined(HAVE_PRI_CALL_HOLD)
  16569. confp->chan.sig = SIG_BRI_PTMP;
  16570. confp->pri.pri.nodetype = PRI_NETWORK;
  16571. #else
  16572. ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno);
  16573. #endif /* !defined(HAVE_PRI_CALL_HOLD) */
  16574. #endif
  16575. #if defined(HAVE_SS7)
  16576. } else if (!strcasecmp(v->value, "ss7")) {
  16577. confp->chan.sig = SIG_SS7;
  16578. #endif /* defined(HAVE_SS7) */
  16579. #ifdef HAVE_OPENR2
  16580. } else if (!strcasecmp(v->value, "mfcr2")) {
  16581. confp->chan.sig = SIG_MFCR2;
  16582. #endif
  16583. } else if (!strcasecmp(v->value, "auto")) {
  16584. confp->is_sig_auto = 1;
  16585. } else {
  16586. confp->chan.outsigmod = orig_outsigmod;
  16587. confp->chan.radio = orig_radio;
  16588. confp->is_sig_auto = orig_auto;
  16589. ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
  16590. }
  16591. } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) {
  16592. if (!strcasecmp(v->value, "em")) {
  16593. confp->chan.outsigmod = SIG_EM;
  16594. } else if (!strcasecmp(v->value, "em_e1")) {
  16595. confp->chan.outsigmod = SIG_EM_E1;
  16596. } else if (!strcasecmp(v->value, "em_w")) {
  16597. confp->chan.outsigmod = SIG_EMWINK;
  16598. } else if (!strcasecmp(v->value, "sf")) {
  16599. confp->chan.outsigmod = SIG_SF;
  16600. } else if (!strcasecmp(v->value, "sf_w")) {
  16601. confp->chan.outsigmod = SIG_SFWINK;
  16602. } else if (!strcasecmp(v->value, "sf_featd")) {
  16603. confp->chan.outsigmod = SIG_FEATD;
  16604. } else if (!strcasecmp(v->value, "sf_featdmf")) {
  16605. confp->chan.outsigmod = SIG_FEATDMF;
  16606. } else if (!strcasecmp(v->value, "sf_featb")) {
  16607. confp->chan.outsigmod = SIG_SF_FEATB;
  16608. } else if (!strcasecmp(v->value, "sf")) {
  16609. confp->chan.outsigmod = SIG_SF;
  16610. } else if (!strcasecmp(v->value, "featd")) {
  16611. confp->chan.outsigmod = SIG_FEATD;
  16612. } else if (!strcasecmp(v->value, "featdmf")) {
  16613. confp->chan.outsigmod = SIG_FEATDMF;
  16614. } else if (!strcasecmp(v->value, "featdmf_ta")) {
  16615. confp->chan.outsigmod = SIG_FEATDMF_TA;
  16616. } else if (!strcasecmp(v->value, "e911")) {
  16617. confp->chan.outsigmod = SIG_E911;
  16618. } else if (!strcasecmp(v->value, "fgccama")) {
  16619. confp->chan.outsigmod = SIG_FGC_CAMA;
  16620. } else if (!strcasecmp(v->value, "fgccamamf")) {
  16621. confp->chan.outsigmod = SIG_FGC_CAMAMF;
  16622. } else if (!strcasecmp(v->value, "featb")) {
  16623. confp->chan.outsigmod = SIG_FEATB;
  16624. } else {
  16625. ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
  16626. }
  16627. #ifdef HAVE_PRI
  16628. } else if (!strcasecmp(v->name, "pridialplan")) {
  16629. if (!strcasecmp(v->value, "national")) {
  16630. confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
  16631. } else if (!strcasecmp(v->value, "unknown")) {
  16632. confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
  16633. } else if (!strcasecmp(v->value, "private")) {
  16634. confp->pri.pri.dialplan = PRI_PRIVATE + 1;
  16635. } else if (!strcasecmp(v->value, "international")) {
  16636. confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
  16637. } else if (!strcasecmp(v->value, "local")) {
  16638. confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
  16639. } else if (!strcasecmp(v->value, "dynamic")) {
  16640. confp->pri.pri.dialplan = -1;
  16641. } else if (!strcasecmp(v->value, "redundant")) {
  16642. confp->pri.pri.dialplan = -2;
  16643. } else {
  16644. ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
  16645. }
  16646. } else if (!strcasecmp(v->name, "prilocaldialplan")) {
  16647. if (!strcasecmp(v->value, "national")) {
  16648. confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
  16649. } else if (!strcasecmp(v->value, "unknown")) {
  16650. confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
  16651. } else if (!strcasecmp(v->value, "private")) {
  16652. confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
  16653. } else if (!strcasecmp(v->value, "international")) {
  16654. confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
  16655. } else if (!strcasecmp(v->value, "local")) {
  16656. confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
  16657. } else if (!strcasecmp(v->value, "from_channel")) {
  16658. confp->pri.pri.localdialplan = 0;
  16659. } else if (!strcasecmp(v->value, "dynamic")) {
  16660. confp->pri.pri.localdialplan = -1;
  16661. } else if (!strcasecmp(v->value, "redundant")) {
  16662. confp->pri.pri.localdialplan = -2;
  16663. } else {
  16664. ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno);
  16665. }
  16666. } else if (!strcasecmp(v->name, "pricpndialplan")) {
  16667. if (!strcasecmp(v->value, "national")) {
  16668. confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
  16669. } else if (!strcasecmp(v->value, "unknown")) {
  16670. confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
  16671. } else if (!strcasecmp(v->value, "private")) {
  16672. confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
  16673. } else if (!strcasecmp(v->value, "international")) {
  16674. confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
  16675. } else if (!strcasecmp(v->value, "local")) {
  16676. confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
  16677. } else if (!strcasecmp(v->value, "from_channel")) {
  16678. confp->pri.pri.cpndialplan = 0;
  16679. } else if (!strcasecmp(v->value, "dynamic")) {
  16680. confp->pri.pri.cpndialplan = -1;
  16681. } else if (!strcasecmp(v->value, "redundant")) {
  16682. confp->pri.pri.cpndialplan = -2;
  16683. } else {
  16684. ast_log(LOG_WARNING, "Unknown PRI cpndialplan '%s' at line %d.\n", v->value, v->lineno);
  16685. }
  16686. } else if (!strcasecmp(v->name, "switchtype")) {
  16687. if (!strcasecmp(v->value, "national"))
  16688. confp->pri.pri.switchtype = PRI_SWITCH_NI2;
  16689. else if (!strcasecmp(v->value, "ni1"))
  16690. confp->pri.pri.switchtype = PRI_SWITCH_NI1;
  16691. else if (!strcasecmp(v->value, "dms100"))
  16692. confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
  16693. else if (!strcasecmp(v->value, "4ess"))
  16694. confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
  16695. else if (!strcasecmp(v->value, "5ess"))
  16696. confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
  16697. else if (!strcasecmp(v->value, "euroisdn"))
  16698. confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
  16699. else if (!strcasecmp(v->value, "qsig"))
  16700. confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
  16701. else {
  16702. ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno);
  16703. return -1;
  16704. }
  16705. } else if (!strcasecmp(v->name, "msn")) {
  16706. ast_copy_string(confp->pri.pri.msn_list, v->value,
  16707. sizeof(confp->pri.pri.msn_list));
  16708. } else if (!strcasecmp(v->name, "nsf")) {
  16709. if (!strcasecmp(v->value, "sdn"))
  16710. confp->pri.pri.nsf = PRI_NSF_SDN;
  16711. else if (!strcasecmp(v->value, "megacom"))
  16712. confp->pri.pri.nsf = PRI_NSF_MEGACOM;
  16713. else if (!strcasecmp(v->value, "tollfreemegacom"))
  16714. confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
  16715. else if (!strcasecmp(v->value, "accunet"))
  16716. confp->pri.pri.nsf = PRI_NSF_ACCUNET;
  16717. else if (!strcasecmp(v->value, "none"))
  16718. confp->pri.pri.nsf = PRI_NSF_NONE;
  16719. else {
  16720. ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno);
  16721. confp->pri.pri.nsf = PRI_NSF_NONE;
  16722. }
  16723. } else if (!strcasecmp(v->name, "priindication")) {
  16724. if (!strcasecmp(v->value, "outofband"))
  16725. confp->chan.priindication_oob = 1;
  16726. else if (!strcasecmp(v->value, "inband"))
  16727. confp->chan.priindication_oob = 0;
  16728. else
  16729. ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
  16730. v->value, v->lineno);
  16731. } else if (!strcasecmp(v->name, "priexclusive")) {
  16732. confp->chan.priexclusive = ast_true(v->value);
  16733. } else if (!strcasecmp(v->name, "internationalprefix")) {
  16734. ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix));
  16735. } else if (!strcasecmp(v->name, "nationalprefix")) {
  16736. ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix));
  16737. } else if (!strcasecmp(v->name, "localprefix")) {
  16738. ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix));
  16739. } else if (!strcasecmp(v->name, "privateprefix")) {
  16740. ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix));
  16741. } else if (!strcasecmp(v->name, "unknownprefix")) {
  16742. ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix));
  16743. } else if (!strcasecmp(v->name, "resetinterval")) {
  16744. if (!strcasecmp(v->value, "never"))
  16745. confp->pri.pri.resetinterval = -1;
  16746. else if (atoi(v->value) >= 60)
  16747. confp->pri.pri.resetinterval = atoi(v->value);
  16748. else
  16749. ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
  16750. v->value, v->lineno);
  16751. } else if (!strcasecmp(v->name, "minunused")) {
  16752. confp->pri.pri.minunused = atoi(v->value);
  16753. } else if (!strcasecmp(v->name, "minidle")) {
  16754. confp->pri.pri.minidle = atoi(v->value);
  16755. } else if (!strcasecmp(v->name, "idleext")) {
  16756. ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext));
  16757. } else if (!strcasecmp(v->name, "idledial")) {
  16758. ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial));
  16759. } else if (!strcasecmp(v->name, "overlapdial")) {
  16760. if (ast_true(v->value)) {
  16761. confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
  16762. } else if (!strcasecmp(v->value, "incoming")) {
  16763. confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
  16764. } else if (!strcasecmp(v->value, "outgoing")) {
  16765. confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
  16766. } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
  16767. confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
  16768. } else {
  16769. confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
  16770. }
  16771. #ifdef HAVE_PRI_PROG_W_CAUSE
  16772. } else if (!strcasecmp(v->name, "qsigchannelmapping")) {
  16773. if (!strcasecmp(v->value, "logical")) {
  16774. confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL;
  16775. } else if (!strcasecmp(v->value, "physical")) {
  16776. confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
  16777. } else {
  16778. confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
  16779. }
  16780. #endif
  16781. } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) {
  16782. confp->pri.pri.discardremoteholdretrieval = ast_true(v->value);
  16783. #if defined(HAVE_PRI_SERVICE_MESSAGES)
  16784. } else if (!strcasecmp(v->name, "service_message_support")) {
  16785. /* assuming switchtype for this channel group has been configured already */
  16786. if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
  16787. || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
  16788. || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) {
  16789. confp->pri.pri.enable_service_message_support = 1;
  16790. } else {
  16791. confp->pri.pri.enable_service_message_support = 0;
  16792. }
  16793. #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
  16794. #ifdef HAVE_PRI_INBANDDISCONNECT
  16795. } else if (!strcasecmp(v->name, "inbanddisconnect")) {
  16796. confp->pri.pri.inbanddisconnect = ast_true(v->value);
  16797. #endif
  16798. } else if (!strcasecmp(v->name, "pritimer")) {
  16799. #ifdef PRI_GETSET_TIMERS
  16800. char tmp[20];
  16801. char *timerc;
  16802. char *c;
  16803. int timer;
  16804. int timeridx;
  16805. ast_copy_string(tmp, v->value, sizeof(tmp));
  16806. c = tmp;
  16807. timerc = strsep(&c, ",");
  16808. if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
  16809. timeridx = pri_timer2idx(timerc);
  16810. timer = atoi(c);
  16811. if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
  16812. ast_log(LOG_WARNING,
  16813. "'%s' is not a valid ISDN timer at line %d.\n", timerc,
  16814. v->lineno);
  16815. } else if (!timer) {
  16816. ast_log(LOG_WARNING,
  16817. "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
  16818. c, timerc, v->lineno);
  16819. } else {
  16820. confp->pri.pri.pritimers[timeridx] = timer;
  16821. }
  16822. } else {
  16823. ast_log(LOG_WARNING,
  16824. "'%s' is not a valid ISDN timer configuration string at line %d.\n",
  16825. v->value, v->lineno);
  16826. }
  16827. #endif /* PRI_GETSET_TIMERS */
  16828. } else if (!strcasecmp(v->name, "facilityenable")) {
  16829. confp->pri.pri.facilityenable = ast_true(v->value);
  16830. #if defined(HAVE_PRI_AOC_EVENTS)
  16831. } else if (!strcasecmp(v->name, "aoc_enable")) {
  16832. confp->pri.pri.aoc_passthrough_flag = 0;
  16833. if (strchr(v->value, 's') || strchr(v->value, 'S')) {
  16834. confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S;
  16835. }
  16836. if (strchr(v->value, 'd') || strchr(v->value, 'D')) {
  16837. confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D;
  16838. }
  16839. if (strchr(v->value, 'e') || strchr(v->value, 'E')) {
  16840. confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E;
  16841. }
  16842. } else if (!strcasecmp(v->name, "aoce_delayhangup")) {
  16843. confp->pri.pri.aoce_delayhangup = ast_true(v->value);
  16844. #endif /* defined(HAVE_PRI_AOC_EVENTS) */
  16845. #if defined(HAVE_PRI_CALL_HOLD)
  16846. } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) {
  16847. confp->pri.pri.hold_disconnect_transfer = ast_true(v->value);
  16848. #endif /* defined(HAVE_PRI_CALL_HOLD) */
  16849. } else if (!strcasecmp(v->name, "moh_signaling")
  16850. || !strcasecmp(v->name, "moh_signalling")) {
  16851. if (!strcasecmp(v->value, "moh")) {
  16852. confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
  16853. } else if (!strcasecmp(v->value, "notify")) {
  16854. confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_NOTIFY;
  16855. #if defined(HAVE_PRI_CALL_HOLD)
  16856. } else if (!strcasecmp(v->value, "hold")) {
  16857. confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
  16858. #endif /* defined(HAVE_PRI_CALL_HOLD) */
  16859. } else {
  16860. confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
  16861. }
  16862. #if defined(HAVE_PRI_CCSS)
  16863. } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) {
  16864. if (!strcasecmp(v->value, "global")) {
  16865. confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */
  16866. } else if (!strcasecmp(v->value, "specific")) {
  16867. confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
  16868. } else {
  16869. confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
  16870. }
  16871. } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) {
  16872. if (!strcasecmp(v->value, "release")) {
  16873. confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */
  16874. } else if (!strcasecmp(v->value, "retain")) {
  16875. confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
  16876. } else if (!strcasecmp(v->value, "do_not_care")) {
  16877. confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */
  16878. } else {
  16879. confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
  16880. }
  16881. } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) {
  16882. if (!strcasecmp(v->value, "release")) {
  16883. confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */
  16884. } else if (!strcasecmp(v->value, "retain")) {
  16885. confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
  16886. } else {
  16887. confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
  16888. }
  16889. #endif /* defined(HAVE_PRI_CCSS) */
  16890. #if defined(HAVE_PRI_CALL_WAITING)
  16891. } else if (!strcasecmp(v->name, "max_call_waiting_calls")) {
  16892. confp->pri.pri.max_call_waiting_calls = atoi(v->value);
  16893. if (confp->pri.pri.max_call_waiting_calls < 0) {
  16894. /* Negative values are not allowed. */
  16895. confp->pri.pri.max_call_waiting_calls = 0;
  16896. }
  16897. } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) {
  16898. confp->pri.pri.allow_call_waiting_calls = ast_true(v->value);
  16899. #endif /* defined(HAVE_PRI_CALL_WAITING) */
  16900. #if defined(HAVE_PRI_MWI)
  16901. } else if (!strcasecmp(v->name, "mwi_mailboxes")) {
  16902. ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value,
  16903. sizeof(confp->pri.pri.mwi_mailboxes));
  16904. } else if (!strcasecmp(v->name, "mwi_vm_boxes")) {
  16905. ast_copy_string(confp->pri.pri.mwi_vm_boxes, v->value,
  16906. sizeof(confp->pri.pri.mwi_vm_boxes));
  16907. } else if (!strcasecmp(v->name, "mwi_vm_numbers")) {
  16908. ast_copy_string(confp->pri.pri.mwi_vm_numbers, v->value,
  16909. sizeof(confp->pri.pri.mwi_vm_numbers));
  16910. #endif /* defined(HAVE_PRI_MWI) */
  16911. } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) {
  16912. confp->pri.pri.append_msn_to_user_tag = ast_true(v->value);
  16913. } else if (!strcasecmp(v->name, "inband_on_setup_ack")) {
  16914. confp->pri.pri.inband_on_setup_ack = ast_true(v->value);
  16915. } else if (!strcasecmp(v->name, "inband_on_proceeding")) {
  16916. confp->pri.pri.inband_on_proceeding = ast_true(v->value);
  16917. #if defined(HAVE_PRI_DISPLAY_TEXT)
  16918. } else if (!strcasecmp(v->name, "display_send")) {
  16919. confp->pri.pri.display_flags_send = dahdi_display_text_option(v->value);
  16920. } else if (!strcasecmp(v->name, "display_receive")) {
  16921. confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->value);
  16922. #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
  16923. #if defined(HAVE_PRI_MCID)
  16924. } else if (!strcasecmp(v->name, "mcid_send")) {
  16925. confp->pri.pri.mcid_send = ast_true(v->value);
  16926. #endif /* defined(HAVE_PRI_MCID) */
  16927. #if defined(HAVE_PRI_DATETIME_SEND)
  16928. } else if (!strcasecmp(v->name, "datetime_send")) {
  16929. confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value);
  16930. #endif /* defined(HAVE_PRI_DATETIME_SEND) */
  16931. } else if (!strcasecmp(v->name, "layer1_presence")) {
  16932. if (!strcasecmp(v->value, "required")) {
  16933. confp->pri.pri.layer1_ignored = 0;
  16934. } else if (!strcasecmp(v->value, "ignore")) {
  16935. confp->pri.pri.layer1_ignored = 1;
  16936. } else {
  16937. /* Default */
  16938. confp->pri.pri.layer1_ignored = 0;
  16939. }
  16940. #if defined(HAVE_PRI_L2_PERSISTENCE)
  16941. } else if (!strcasecmp(v->name, "layer2_persistence")) {
  16942. if (!strcasecmp(v->value, "keep_up")) {
  16943. confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
  16944. } else if (!strcasecmp(v->value, "leave_down")) {
  16945. confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
  16946. } else {
  16947. confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
  16948. }
  16949. #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
  16950. } else if (!strcasecmp(v->name, "colp_send")) {
  16951. if (!strcasecmp(v->value, "block")) {
  16952. confp->pri.pri.colp_send = SIG_PRI_COLP_BLOCK;
  16953. } else if (!strcasecmp(v->value, "connect")) {
  16954. confp->pri.pri.colp_send = SIG_PRI_COLP_CONNECT;
  16955. } else if (!strcasecmp(v->value, "update")) {
  16956. confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
  16957. } else {
  16958. confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
  16959. }
  16960. #endif /* HAVE_PRI */
  16961. #if defined(HAVE_SS7)
  16962. } else if (!strcasecmp(v->name, "ss7type")) {
  16963. if (!strcasecmp(v->value, "itu")) {
  16964. cur_ss7type = SS7_ITU;
  16965. } else if (!strcasecmp(v->value, "ansi")) {
  16966. cur_ss7type = SS7_ANSI;
  16967. } else {
  16968. ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno);
  16969. }
  16970. } else if (!strcasecmp(v->name, "slc")) {
  16971. cur_slc = atoi(v->value);
  16972. } else if (!strcasecmp(v->name, "linkset")) {
  16973. cur_linkset = atoi(v->value);
  16974. } else if (!strcasecmp(v->name, "pointcode")) {
  16975. cur_pointcode = parse_pointcode(v->value);
  16976. } else if (!strcasecmp(v->name, "adjpointcode")) {
  16977. cur_adjpointcode = parse_pointcode(v->value);
  16978. } else if (!strcasecmp(v->name, "defaultdpc")) {
  16979. cur_defaultdpc = parse_pointcode(v->value);
  16980. } else if (!strcasecmp(v->name, "cicbeginswith")) {
  16981. cur_cicbeginswith = atoi(v->value);
  16982. } else if (!strcasecmp(v->name, "networkindicator")) {
  16983. if (!strcasecmp(v->value, "national")) {
  16984. cur_networkindicator = SS7_NI_NAT;
  16985. } else if (!strcasecmp(v->value, "national_spare")) {
  16986. cur_networkindicator = SS7_NI_NAT_SPARE;
  16987. } else if (!strcasecmp(v->value, "international")) {
  16988. cur_networkindicator = SS7_NI_INT;
  16989. } else if (!strcasecmp(v->value, "international_spare")) {
  16990. cur_networkindicator = SS7_NI_INT_SPARE;
  16991. } else {
  16992. cur_networkindicator = -1;
  16993. }
  16994. } else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
  16995. ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix));
  16996. } else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
  16997. ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix));
  16998. } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) {
  16999. ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix));
  17000. } else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
  17001. ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix));
  17002. } else if (!strcasecmp(v->name, "ss7_networkroutedprefix")) {
  17003. ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->value, sizeof(confp->ss7.ss7.networkroutedprefix));
  17004. } else if (!strcasecmp(v->name, "ss7_called_nai")) {
  17005. if (!strcasecmp(v->value, "national")) {
  17006. confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
  17007. } else if (!strcasecmp(v->value, "international")) {
  17008. confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
  17009. } else if (!strcasecmp(v->value, "subscriber")) {
  17010. confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
  17011. } else if (!strcasecmp(v->value, "unknown")) {
  17012. confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
  17013. } else if (!strcasecmp(v->value, "dynamic")) {
  17014. confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC;
  17015. } else {
  17016. ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno);
  17017. }
  17018. } else if (!strcasecmp(v->name, "ss7_calling_nai")) {
  17019. if (!strcasecmp(v->value, "national")) {
  17020. confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
  17021. } else if (!strcasecmp(v->value, "international")) {
  17022. confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
  17023. } else if (!strcasecmp(v->value, "subscriber")) {
  17024. confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
  17025. } else if (!strcasecmp(v->value, "unknown")) {
  17026. confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
  17027. } else if (!strcasecmp(v->value, "dynamic")) {
  17028. confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC;
  17029. } else {
  17030. ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
  17031. }
  17032. } else if (!strcasecmp(v->name, "sigchan")) {
  17033. int sigchan, res;
  17034. sigchan = atoi(v->value);
  17035. res = linkset_addsigchan(sigchan);
  17036. if (res < 0) {
  17037. return -1;
  17038. }
  17039. } else if (!strcasecmp(v->name, "ss7_explicitacm")) {
  17040. struct dahdi_ss7 *link;
  17041. link = ss7_resolve_linkset(cur_linkset);
  17042. if (!link) {
  17043. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17044. return -1;
  17045. }
  17046. if (ast_true(v->value)) {
  17047. link->ss7.flags |= LINKSET_FLAG_EXPLICITACM;
  17048. } else {
  17049. link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
  17050. }
  17051. } else if (!strcasecmp(v->name, "ss7_autoacm")) {
  17052. struct dahdi_ss7 *link;
  17053. link = ss7_resolve_linkset(cur_linkset);
  17054. if (!link) {
  17055. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17056. return -1;
  17057. }
  17058. if (ast_true(v->value)) {
  17059. link->ss7.flags |= LINKSET_FLAG_AUTOACM;
  17060. } else {
  17061. link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
  17062. }
  17063. } else if (!strcasecmp(v->name, "ss7_initialhwblo")) {
  17064. struct dahdi_ss7 *link;
  17065. link = ss7_resolve_linkset(cur_linkset);
  17066. if (!link) {
  17067. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17068. return -1;
  17069. }
  17070. if (ast_true(v->value)) {
  17071. link->ss7.flags |= LINKSET_FLAG_INITIALHWBLO;
  17072. } else {
  17073. link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
  17074. }
  17075. } else if (!strcasecmp(v->name, "ss7_use_echocontrol")) {
  17076. struct dahdi_ss7 *link;
  17077. link = ss7_resolve_linkset(cur_linkset);
  17078. if (!link) {
  17079. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17080. return -1;
  17081. }
  17082. if (ast_true(v->value)) {
  17083. link->ss7.flags |= LINKSET_FLAG_USEECHOCONTROL;
  17084. } else {
  17085. link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
  17086. }
  17087. } else if (!strcasecmp(v->name, "ss7_default_echocontrol")) {
  17088. struct dahdi_ss7 *link;
  17089. link = ss7_resolve_linkset(cur_linkset);
  17090. if (!link) {
  17091. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17092. return -1;
  17093. }
  17094. if (ast_true(v->value)) {
  17095. link->ss7.flags |= LINKSET_FLAG_DEFAULTECHOCONTROL;
  17096. } else {
  17097. link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
  17098. }
  17099. } else if (!strncasecmp(v->name, "isup_timer.", 11)) {
  17100. struct dahdi_ss7 *link;
  17101. link = ss7_resolve_linkset(cur_linkset);
  17102. if (!link) {
  17103. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17104. return -1;
  17105. }
  17106. if (!link->ss7.ss7) {
  17107. ast_log(LOG_ERROR, "Please specify isup timers after sigchan!\n");
  17108. } else if (!ss7_set_isup_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
  17109. ast_log(LOG_ERROR, "Invalid isup timer %s\n", v->name);
  17110. }
  17111. } else if (!strncasecmp(v->name, "mtp3_timer.", 11)) {
  17112. struct dahdi_ss7 *link;
  17113. link = ss7_resolve_linkset(cur_linkset);
  17114. if (!link) {
  17115. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17116. return -1;
  17117. }
  17118. if (!link->ss7.ss7) {
  17119. ast_log(LOG_ERROR, "Please specify mtp3 timers after sigchan!\n");
  17120. } else if (!ss7_set_mtp3_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
  17121. ast_log(LOG_ERROR, "Invalid mtp3 timer %s\n", v->name);
  17122. }
  17123. } else if (!strcasecmp(v->name, "inr_if_no_calling")) {
  17124. struct dahdi_ss7 *link;
  17125. link = ss7_resolve_linkset(cur_linkset);
  17126. if (!link) {
  17127. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17128. return -1;
  17129. }
  17130. if (!link->ss7.ss7) {
  17131. ast_log(LOG_ERROR, "Please specify inr_if_no_calling after sigchan!\n");
  17132. } else if (ast_true(v->value)) {
  17133. ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
  17134. } else {
  17135. ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
  17136. }
  17137. } else if (!strcasecmp(v->name, "non_isdn_access")) {
  17138. struct dahdi_ss7 *link;
  17139. link = ss7_resolve_linkset(cur_linkset);
  17140. if (!link) {
  17141. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17142. return -1;
  17143. }
  17144. if (!link->ss7.ss7) {
  17145. ast_log(LOG_ERROR, "Please specify non_isdn_access after sigchan!\n");
  17146. } else if (ast_true(v->value)) {
  17147. ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
  17148. } else {
  17149. ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
  17150. }
  17151. } else if (!strcasecmp(v->name, "sls_shift")) {
  17152. struct dahdi_ss7 *link;
  17153. int sls_shift = atoi(v->value);
  17154. if (sls_shift < 0 || sls_shift > 7) {
  17155. ast_log(LOG_ERROR, "Invalid sls_shift value. Must be between 0 and 7\n");
  17156. return -1;
  17157. }
  17158. link = ss7_resolve_linkset(cur_linkset);
  17159. if (!link) {
  17160. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17161. return -1;
  17162. }
  17163. if (!link->ss7.ss7) {
  17164. ast_log(LOG_ERROR, "Please specify sls_shift after sigchan!\n");
  17165. } else {
  17166. ss7_set_sls_shift(link->ss7.ss7, sls_shift);
  17167. }
  17168. } else if (!strcasecmp(v->name, "cause_location")) {
  17169. struct dahdi_ss7 *link;
  17170. int cause_location = atoi(v->value);
  17171. if (cause_location < 0 || cause_location > 15) {
  17172. ast_log(LOG_ERROR, "Invalid cause_location value. Must be between 0 and 15\n");
  17173. return -1;
  17174. }
  17175. link = ss7_resolve_linkset(cur_linkset);
  17176. if (!link) {
  17177. ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
  17178. return -1;
  17179. }
  17180. if (!link->ss7.ss7) {
  17181. ast_log(LOG_ERROR, "Please specify cause_location after sigchan!\n");
  17182. } else {
  17183. ss7_set_cause_location(link->ss7.ss7, cause_location);
  17184. }
  17185. #endif /* defined(HAVE_SS7) */
  17186. #ifdef HAVE_OPENR2
  17187. } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
  17188. ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file));
  17189. ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", confp->mfcr2.r2proto_file);
  17190. } else if (!strcasecmp(v->name, "mfcr2_logdir")) {
  17191. ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir));
  17192. } else if (!strcasecmp(v->name, "mfcr2_variant")) {
  17193. confp->mfcr2.variant = openr2_proto_get_variant(v->value);
  17194. if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
  17195. ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno);
  17196. confp->mfcr2.variant = OR2_VAR_ITU;
  17197. }
  17198. } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
  17199. confp->mfcr2.mfback_timeout = atoi(v->value);
  17200. if (!confp->mfcr2.mfback_timeout) {
  17201. ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
  17202. confp->mfcr2.mfback_timeout = -1;
  17203. } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
  17204. ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
  17205. }
  17206. } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
  17207. confp->mfcr2.metering_pulse_timeout = atoi(v->value);
  17208. if (confp->mfcr2.metering_pulse_timeout > 500) {
  17209. ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
  17210. }
  17211. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
  17212. } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) {
  17213. confp->mfcr2.dtmf_detection = ast_true(v->value) ? 1 : 0;
  17214. } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) {
  17215. confp->mfcr2.dtmf_dialing = ast_true(v->value) ? 1 : 0;
  17216. } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) {
  17217. confp->mfcr2.dtmf_time_on = atoi(v->value);
  17218. } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) {
  17219. confp->mfcr2.dtmf_time_off = atoi(v->value);
  17220. #endif
  17221. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
  17222. } else if (!strcasecmp(v->name, "mfcr2_dtmf_end_timeout")) {
  17223. confp->mfcr2.dtmf_end_timeout = atoi(v->value);
  17224. #endif
  17225. } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
  17226. confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0;
  17227. } else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
  17228. confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0;
  17229. } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
  17230. confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0;
  17231. } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
  17232. confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0;
  17233. } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
  17234. confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0;
  17235. } else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
  17236. confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0;
  17237. } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
  17238. confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0;
  17239. #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
  17240. } else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
  17241. confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0;
  17242. #endif
  17243. } else if (!strcasecmp(v->name, "mfcr2_call_files")) {
  17244. confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0;
  17245. } else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
  17246. confp->mfcr2.max_ani = atoi(v->value);
  17247. if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION) {
  17248. confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1;
  17249. }
  17250. } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
  17251. confp->mfcr2.max_dnis = atoi(v->value);
  17252. if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION) {
  17253. confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1;
  17254. }
  17255. } else if (!strcasecmp(v->name, "mfcr2_category")) {
  17256. confp->mfcr2.category = openr2_proto_get_category(v->value);
  17257. if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
  17258. confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
  17259. ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
  17260. v->value, v->lineno);
  17261. }
  17262. } else if (!strcasecmp(v->name, "mfcr2_logging")) {
  17263. openr2_log_level_t tmplevel;
  17264. char *clevel;
  17265. char *logval = ast_strdupa(v->value);
  17266. while (logval) {
  17267. clevel = strsep(&logval,",");
  17268. if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
  17269. ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno);
  17270. continue;
  17271. }
  17272. confp->mfcr2.loglevel |= tmplevel;
  17273. }
  17274. #endif /* HAVE_OPENR2 */
  17275. } else if (!strcasecmp(v->name, "cadence")) {
  17276. /* setup to scan our argument */
  17277. int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  17278. int i;
  17279. struct dahdi_ring_cadence new_cadence;
  17280. int cid_location = -1;
  17281. int firstcadencepos = 0;
  17282. char original_args[80];
  17283. int cadence_is_ok = 1;
  17284. ast_copy_string(original_args, v->value, sizeof(original_args));
  17285. /* 16 cadences allowed (8 pairs) */
  17286. element_count = sscanf(v->value, "%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
  17287. /* Cadence must be even (on/off) */
  17288. if (element_count % 2 == 1) {
  17289. ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno);
  17290. cadence_is_ok = 0;
  17291. }
  17292. /* Ring cadences cannot be negative */
  17293. for (i = 0; i < element_count; i++) {
  17294. if (c[i] == 0) {
  17295. ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno);
  17296. cadence_is_ok = 0;
  17297. break;
  17298. } else if (c[i] < 0) {
  17299. if (i % 2 == 1) {
  17300. /* Silence duration, negative possibly okay */
  17301. if (cid_location == -1) {
  17302. cid_location = i;
  17303. c[i] *= -1;
  17304. } else {
  17305. ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno);
  17306. cadence_is_ok = 0;
  17307. break;
  17308. }
  17309. } else {
  17310. if (firstcadencepos == 0) {
  17311. firstcadencepos = i; /* only recorded to avoid duplicate specification */
  17312. /* duration will be passed negative to the DAHDI driver */
  17313. } else {
  17314. ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno);
  17315. cadence_is_ok = 0;
  17316. break;
  17317. }
  17318. }
  17319. }
  17320. }
  17321. /* Substitute our scanned cadence */
  17322. for (i = 0; i < 16; i++) {
  17323. new_cadence.ringcadence[i] = c[i];
  17324. }
  17325. if (cadence_is_ok) {
  17326. /* ---we scanned it without getting annoyed; now some sanity checks--- */
  17327. if (element_count < 2) {
  17328. ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno);
  17329. } else {
  17330. if (cid_location == -1) {
  17331. /* user didn't say; default to first pause */
  17332. cid_location = 1;
  17333. } else {
  17334. /* convert element_index to cidrings value */
  17335. cid_location = (cid_location + 1) / 2;
  17336. }
  17337. /* ---we like their cadence; try to install it--- */
  17338. if (!user_has_defined_cadences++)
  17339. /* this is the first user-defined cadence; clear the default user cadences */
  17340. num_cadence = 0;
  17341. if ((num_cadence+1) >= NUM_CADENCE_MAX)
  17342. ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno);
  17343. else {
  17344. cadences[num_cadence] = new_cadence;
  17345. cidrings[num_cadence++] = cid_location;
  17346. ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args);
  17347. }
  17348. }
  17349. }
  17350. } else if (!strcasecmp(v->name, "ringtimeout")) {
  17351. ringt_base = (atoi(v->value) * 8) / READ_SIZE;
  17352. } else if (!strcasecmp(v->name, "prewink")) {
  17353. confp->timing.prewinktime = atoi(v->value);
  17354. } else if (!strcasecmp(v->name, "preflash")) {
  17355. confp->timing.preflashtime = atoi(v->value);
  17356. } else if (!strcasecmp(v->name, "wink")) {
  17357. confp->timing.winktime = atoi(v->value);
  17358. } else if (!strcasecmp(v->name, "flash")) {
  17359. confp->timing.flashtime = atoi(v->value);
  17360. } else if (!strcasecmp(v->name, "start")) {
  17361. confp->timing.starttime = atoi(v->value);
  17362. } else if (!strcasecmp(v->name, "rxwink")) {
  17363. confp->timing.rxwinktime = atoi(v->value);
  17364. } else if (!strcasecmp(v->name, "rxflash")) {
  17365. confp->timing.rxflashtime = atoi(v->value);
  17366. } else if (!strcasecmp(v->name, "debounce")) {
  17367. confp->timing.debouncetime = atoi(v->value);
  17368. } else if (!strcasecmp(v->name, "toneduration")) {
  17369. int toneduration;
  17370. int ctlfd;
  17371. int res;
  17372. struct dahdi_dialparams dps;
  17373. ctlfd = open("/dev/dahdi/ctl", O_RDWR);
  17374. if (ctlfd == -1) {
  17375. ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno);
  17376. return -1;
  17377. }
  17378. toneduration = atoi(v->value);
  17379. if (toneduration > -1) {
  17380. memset(&dps, 0, sizeof(dps));
  17381. dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
  17382. res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
  17383. if (res < 0) {
  17384. ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno));
  17385. close(ctlfd);
  17386. return -1;
  17387. }
  17388. }
  17389. close(ctlfd);
  17390. } else if (!strcasecmp(v->name, "defaultcic")) {
  17391. ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
  17392. } else if (!strcasecmp(v->name, "defaultozz")) {
  17393. ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
  17394. } else if (!strcasecmp(v->name, "mwilevel")) {
  17395. mwilevel = atoi(v->value);
  17396. } else if (!strcasecmp(v->name, "dtmfcidlevel")) {
  17397. dtmfcid_level = atoi(v->value);
  17398. } else if (!strcasecmp(v->name, "reportalarms")) {
  17399. if (!strcasecmp(v->value, "all"))
  17400. report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS;
  17401. if (!strcasecmp(v->value, "none"))
  17402. report_alarms = 0;
  17403. else if (!strcasecmp(v->value, "channels"))
  17404. report_alarms = REPORT_CHANNEL_ALARMS;
  17405. else if (!strcasecmp(v->value, "spans"))
  17406. report_alarms = REPORT_SPAN_ALARMS;
  17407. }
  17408. } else if (!(options & PROC_DAHDI_OPT_NOWARN) )
  17409. ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);
  17410. }
  17411. /* Since confp has already filled invidual dahdi_pvt objects with channels at this point, clear the variables in confp's pvt. */
  17412. if (confp->chan.vars) {
  17413. ast_variables_destroy(confp->chan.vars);
  17414. confp->chan.vars = NULL;
  17415. }
  17416. if (dahdichan) {
  17417. /* Process the deferred dahdichan value. */
  17418. if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno)) {
  17419. if (confp->ignore_failed_channels) {
  17420. ast_log(LOG_WARNING,
  17421. "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
  17422. dahdichan->value);
  17423. } else {
  17424. return -1;
  17425. }
  17426. }
  17427. }
  17428. /* mark the first channels of each DAHDI span to watch for their span alarms */
  17429. for (tmp = iflist, y=-1; tmp; tmp = tmp->next) {
  17430. if (!tmp->destroy && tmp->span != y) {
  17431. tmp->manages_span_alarms = 1;
  17432. y = tmp->span;
  17433. } else {
  17434. tmp->manages_span_alarms = 0;
  17435. }
  17436. }
  17437. /*< \todo why check for the pseudo in the per-channel section.
  17438. * Any actual use for manual setup of the pseudo channel? */
  17439. if (!has_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) {
  17440. /* use the default configuration for a channel, so
  17441. that any settings from real configured channels
  17442. don't "leak" into the pseudo channel config
  17443. */
  17444. struct dahdi_chan_conf conf = dahdi_chan_conf_default();
  17445. if (conf.chan.cc_params) {
  17446. tmp = mkintf(CHAN_PSEUDO, &conf, reload);
  17447. } else {
  17448. tmp = NULL;
  17449. }
  17450. if (tmp) {
  17451. ast_verb(3, "Automatically generated pseudo channel\n");
  17452. has_pseudo = 1;
  17453. } else {
  17454. ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
  17455. }
  17456. ast_cc_config_params_destroy(conf.chan.cc_params);
  17457. }
  17458. /* Since named callgroup and named pickup group are ref'd to dahdi_pvt at this point, unref container in confp's pvt. */
  17459. confp->chan.named_callgroups = ast_unref_namedgroups(confp->chan.named_callgroups);
  17460. confp->chan.named_pickupgroups = ast_unref_namedgroups(confp->chan.named_pickupgroups);
  17461. return 0;
  17462. }
  17463. /*!
  17464. * \internal
  17465. * \brief Deep copy struct dahdi_chan_conf.
  17466. * \since 1.8
  17467. *
  17468. * \param dest Destination.
  17469. * \param src Source.
  17470. *
  17471. * \return Nothing
  17472. */
  17473. static void deep_copy_dahdi_chan_conf(struct dahdi_chan_conf *dest, const struct dahdi_chan_conf *src)
  17474. {
  17475. struct ast_cc_config_params *cc_params;
  17476. cc_params = dest->chan.cc_params;
  17477. *dest = *src;
  17478. dest->chan.cc_params = cc_params;
  17479. ast_cc_copy_config_params(dest->chan.cc_params, src->chan.cc_params);
  17480. }
  17481. /*!
  17482. * \internal
  17483. * \brief Setup DAHDI channel driver.
  17484. *
  17485. * \param reload enum: load_module(0), reload(1), restart(2).
  17486. * \param default_conf Default config parameters. So cc_params can be properly destroyed.
  17487. * \param base_conf Default config parameters per section. So cc_params can be properly destroyed.
  17488. * \param conf Local config parameters. So cc_params can be properly destroyed.
  17489. *
  17490. * \retval 0 on success.
  17491. * \retval -1 on error.
  17492. */
  17493. static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, struct dahdi_chan_conf *base_conf, struct dahdi_chan_conf *conf)
  17494. {
  17495. struct ast_config *cfg;
  17496. struct ast_config *ucfg;
  17497. struct ast_variable *v;
  17498. struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 };
  17499. const char *chans;
  17500. const char *cat;
  17501. int res;
  17502. #ifdef HAVE_PRI
  17503. char *c;
  17504. int spanno;
  17505. int i;
  17506. int logicalspan;
  17507. int trunkgroup;
  17508. int dchannels[SIG_PRI_NUM_DCHANS];
  17509. #endif
  17510. int have_cfg_now;
  17511. static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */
  17512. cfg = ast_config_load(config, config_flags);
  17513. have_cfg_now = !!cfg;
  17514. if (!cfg) {
  17515. /* Error if we have no config file */
  17516. if (had_cfg_before) {
  17517. ast_log(LOG_ERROR, "Unable to load config %s\n", config);
  17518. ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
  17519. }
  17520. cfg = ast_config_new();/* Dummy config */
  17521. if (!cfg) {
  17522. return 0;
  17523. }
  17524. ucfg = ast_config_load("users.conf", config_flags);
  17525. if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
  17526. ast_config_destroy(cfg);
  17527. return 0;
  17528. }
  17529. if (ucfg == CONFIG_STATUS_FILEINVALID) {
  17530. ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
  17531. ast_config_destroy(cfg);
  17532. return 0;
  17533. }
  17534. } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
  17535. ucfg = ast_config_load("users.conf", config_flags);
  17536. if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
  17537. return 0;
  17538. }
  17539. if (ucfg == CONFIG_STATUS_FILEINVALID) {
  17540. ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
  17541. return 0;
  17542. }
  17543. ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
  17544. cfg = ast_config_load(config, config_flags);
  17545. have_cfg_now = !!cfg;
  17546. if (!cfg) {
  17547. if (had_cfg_before) {
  17548. /* We should have been able to load the config. */
  17549. ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config);
  17550. ast_config_destroy(ucfg);
  17551. return 0;
  17552. }
  17553. cfg = ast_config_new();/* Dummy config */
  17554. if (!cfg) {
  17555. ast_config_destroy(ucfg);
  17556. return 0;
  17557. }
  17558. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  17559. ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
  17560. ast_config_destroy(ucfg);
  17561. return 0;
  17562. }
  17563. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  17564. ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
  17565. return 0;
  17566. } else {
  17567. ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
  17568. ucfg = ast_config_load("users.conf", config_flags);
  17569. if (ucfg == CONFIG_STATUS_FILEINVALID) {
  17570. ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
  17571. ast_config_destroy(cfg);
  17572. return 0;
  17573. }
  17574. }
  17575. had_cfg_before = have_cfg_now;
  17576. /* It's a little silly to lock it, but we might as well just to be sure */
  17577. ast_mutex_lock(&iflock);
  17578. #ifdef HAVE_PRI
  17579. if (reload != 1) {
  17580. /* Process trunkgroups first */
  17581. v = ast_variable_browse(cfg, "trunkgroups");
  17582. while (v) {
  17583. if (!strcasecmp(v->name, "trunkgroup")) {
  17584. trunkgroup = atoi(v->value);
  17585. if (trunkgroup > 0) {
  17586. if ((c = strchr(v->value, ','))) {
  17587. i = 0;
  17588. memset(dchannels, 0, sizeof(dchannels));
  17589. while (c && (i < SIG_PRI_NUM_DCHANS)) {
  17590. dchannels[i] = atoi(c + 1);
  17591. if (dchannels[i] < 0) {
  17592. ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
  17593. } else
  17594. i++;
  17595. c = strchr(c + 1, ',');
  17596. }
  17597. if (i) {
  17598. if (pri_create_trunkgroup(trunkgroup, dchannels)) {
  17599. ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of chan_dahdi.conf\n", trunkgroup, dchannels[0], v->lineno);
  17600. } else
  17601. ast_verb(2, "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
  17602. } else
  17603. ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
  17604. } else
  17605. ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
  17606. } else
  17607. ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
  17608. } else if (!strcasecmp(v->name, "spanmap")) {
  17609. spanno = atoi(v->value);
  17610. if (spanno > 0) {
  17611. if ((c = strchr(v->value, ','))) {
  17612. trunkgroup = atoi(c + 1);
  17613. if (trunkgroup > 0) {
  17614. if ((c = strchr(c + 1, ',')))
  17615. logicalspan = atoi(c + 1);
  17616. else
  17617. logicalspan = 0;
  17618. if (logicalspan >= 0) {
  17619. if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
  17620. ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
  17621. } else
  17622. ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
  17623. } else
  17624. ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->lineno);
  17625. } else
  17626. ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
  17627. } else
  17628. ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
  17629. } else
  17630. ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
  17631. } else {
  17632. ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
  17633. }
  17634. v = v->next;
  17635. }
  17636. }
  17637. #endif
  17638. /* Copy the default jb config over global_jbconf */
  17639. memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
  17640. mwimonitornotify[0] = '\0';
  17641. v = ast_variable_browse(cfg, "channels");
  17642. if ((res = process_dahdi(base_conf,
  17643. "" /* Must be empty for the channels category. Silly voicemail mailbox. */,
  17644. v, reload, 0))) {
  17645. ast_mutex_unlock(&iflock);
  17646. ast_config_destroy(cfg);
  17647. if (ucfg) {
  17648. ast_config_destroy(ucfg);
  17649. }
  17650. return res;
  17651. }
  17652. /* Now get configuration from all normal sections in chan_dahdi.conf: */
  17653. for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
  17654. /* [channels] and [trunkgroups] are used. Let's also reserve
  17655. * [globals] and [general] for future use
  17656. */
  17657. if (!strcasecmp(cat, "general") ||
  17658. !strcasecmp(cat, "trunkgroups") ||
  17659. !strcasecmp(cat, "globals") ||
  17660. !strcasecmp(cat, "channels")) {
  17661. continue;
  17662. }
  17663. chans = ast_variable_retrieve(cfg, cat, "dahdichan");
  17664. if (ast_strlen_zero(chans)) {
  17665. /* Section is useless without a dahdichan value present. */
  17666. continue;
  17667. }
  17668. /* Copy base_conf to conf. */
  17669. deep_copy_dahdi_chan_conf(conf, base_conf);
  17670. if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) {
  17671. ast_mutex_unlock(&iflock);
  17672. ast_config_destroy(cfg);
  17673. if (ucfg) {
  17674. ast_config_destroy(ucfg);
  17675. }
  17676. return res;
  17677. }
  17678. }
  17679. ast_config_destroy(cfg);
  17680. if (ucfg) {
  17681. /* Reset base_conf, so things don't leak from chan_dahdi.conf */
  17682. deep_copy_dahdi_chan_conf(base_conf, default_conf);
  17683. process_dahdi(base_conf,
  17684. "" /* Must be empty for the general category. Silly voicemail mailbox. */,
  17685. ast_variable_browse(ucfg, "general"), 1, 0);
  17686. for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
  17687. if (!strcasecmp(cat, "general")) {
  17688. continue;
  17689. }
  17690. chans = ast_variable_retrieve(ucfg, cat, "dahdichan");
  17691. if (ast_strlen_zero(chans)) {
  17692. /* Section is useless without a dahdichan value present. */
  17693. continue;
  17694. }
  17695. /* Copy base_conf to conf. */
  17696. deep_copy_dahdi_chan_conf(conf, base_conf);
  17697. if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) {
  17698. ast_config_destroy(ucfg);
  17699. ast_mutex_unlock(&iflock);
  17700. return res;
  17701. }
  17702. }
  17703. ast_config_destroy(ucfg);
  17704. }
  17705. ast_mutex_unlock(&iflock);
  17706. #ifdef HAVE_PRI
  17707. if (reload != 1) {
  17708. int x;
  17709. for (x = 0; x < NUM_SPANS; x++) {
  17710. if (pris[x].pri.pvts[0] &&
  17711. pris[x].pri.master == AST_PTHREADT_NULL) {
  17712. prepare_pri(pris + x);
  17713. if (sig_pri_start_pri(&pris[x].pri)) {
  17714. ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
  17715. return -1;
  17716. } else
  17717. ast_verb(2, "Starting D-Channel on span %d\n", x + 1);
  17718. }
  17719. }
  17720. }
  17721. #endif
  17722. #if defined(HAVE_SS7)
  17723. if (reload != 1) {
  17724. int x;
  17725. for (x = 0; x < NUM_SPANS; x++) {
  17726. if (linksets[x].ss7.ss7) {
  17727. if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) {
  17728. ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1);
  17729. return -1;
  17730. } else
  17731. ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1);
  17732. }
  17733. }
  17734. }
  17735. #endif /* defined(HAVE_SS7) */
  17736. #ifdef HAVE_OPENR2
  17737. if (reload != 1) {
  17738. int x;
  17739. for (x = 0; x < r2links_count; x++) {
  17740. if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) {
  17741. ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
  17742. return -1;
  17743. } else {
  17744. ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
  17745. }
  17746. }
  17747. }
  17748. #endif
  17749. /* And start the monitor for the first time */
  17750. restart_monitor();
  17751. return 0;
  17752. }
  17753. /*!
  17754. * \internal
  17755. * \brief Setup DAHDI channel driver.
  17756. *
  17757. * \param reload enum: load_module(0), reload(1), restart(2).
  17758. *
  17759. * \retval 0 on success.
  17760. * \retval -1 on error.
  17761. */
  17762. static int setup_dahdi(int reload)
  17763. {
  17764. int res;
  17765. struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
  17766. struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
  17767. struct dahdi_chan_conf conf = dahdi_chan_conf_default();
  17768. if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) {
  17769. res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf);
  17770. } else {
  17771. res = -1;
  17772. }
  17773. ast_cc_config_params_destroy(default_conf.chan.cc_params);
  17774. ast_cc_config_params_destroy(base_conf.chan.cc_params);
  17775. ast_cc_config_params_destroy(conf.chan.cc_params);
  17776. return res;
  17777. }
  17778. /*!
  17779. * \internal
  17780. * \brief Callback used to generate the dahdi status tree.
  17781. * \param[in] search The search pattern tree.
  17782. * \retval NULL on error.
  17783. * \retval non-NULL The generated tree.
  17784. */
  17785. static int dahdi_status_data_provider_get(const struct ast_data_search *search,
  17786. struct ast_data *data_root)
  17787. {
  17788. int ctl, res, span;
  17789. struct ast_data *data_span, *data_alarms;
  17790. struct dahdi_spaninfo s;
  17791. ctl = open("/dev/dahdi/ctl", O_RDWR);
  17792. if (ctl < 0) {
  17793. ast_log(LOG_ERROR, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
  17794. return -1;
  17795. }
  17796. for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
  17797. s.spanno = span;
  17798. res = ioctl(ctl, DAHDI_SPANSTAT, &s);
  17799. if (res) {
  17800. continue;
  17801. }
  17802. data_span = ast_data_add_node(data_root, "span");
  17803. if (!data_span) {
  17804. continue;
  17805. }
  17806. ast_data_add_str(data_span, "description", s.desc);
  17807. /* insert the alarms status */
  17808. data_alarms = ast_data_add_node(data_span, "alarms");
  17809. if (!data_alarms) {
  17810. continue;
  17811. }
  17812. ast_data_add_bool(data_alarms, "BLUE", s.alarms & DAHDI_ALARM_BLUE);
  17813. ast_data_add_bool(data_alarms, "YELLOW", s.alarms & DAHDI_ALARM_YELLOW);
  17814. ast_data_add_bool(data_alarms, "RED", s.alarms & DAHDI_ALARM_RED);
  17815. ast_data_add_bool(data_alarms, "LOOPBACK", s.alarms & DAHDI_ALARM_LOOPBACK);
  17816. ast_data_add_bool(data_alarms, "RECOVER", s.alarms & DAHDI_ALARM_RECOVER);
  17817. ast_data_add_bool(data_alarms, "NOTOPEN", s.alarms & DAHDI_ALARM_NOTOPEN);
  17818. ast_data_add_int(data_span, "irqmisses", s.irqmisses);
  17819. ast_data_add_int(data_span, "bpviol", s.bpvcount);
  17820. ast_data_add_int(data_span, "crc4", s.crc4count);
  17821. ast_data_add_str(data_span, "framing", s.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
  17822. s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
  17823. s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
  17824. "CAS");
  17825. ast_data_add_str(data_span, "coding", s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
  17826. s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
  17827. s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
  17828. "Unknown");
  17829. ast_data_add_str(data_span, "options", s.lineconfig & DAHDI_CONFIG_CRC4 ?
  17830. s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" :
  17831. s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "");
  17832. ast_data_add_str(data_span, "lbo", lbostr[s.lbo]);
  17833. /* if this span doesn't match remove it. */
  17834. if (!ast_data_search_match(search, data_span)) {
  17835. ast_data_remove_node(data_root, data_span);
  17836. }
  17837. }
  17838. close(ctl);
  17839. return 0;
  17840. }
  17841. /*!
  17842. * \internal
  17843. * \brief Callback used to generate the dahdi channels tree.
  17844. * \param[in] search The search pattern tree.
  17845. * \retval NULL on error.
  17846. * \retval non-NULL The generated tree.
  17847. */
  17848. static int dahdi_channels_data_provider_get(const struct ast_data_search *search,
  17849. struct ast_data *data_root)
  17850. {
  17851. struct dahdi_pvt *tmp;
  17852. struct ast_data *data_channel;
  17853. ast_mutex_lock(&iflock);
  17854. for (tmp = iflist; tmp; tmp = tmp->next) {
  17855. data_channel = ast_data_add_node(data_root, "channel");
  17856. if (!data_channel) {
  17857. continue;
  17858. }
  17859. ast_data_add_structure(dahdi_pvt, data_channel, tmp);
  17860. /* if this channel doesn't match remove it. */
  17861. if (!ast_data_search_match(search, data_channel)) {
  17862. ast_data_remove_node(data_root, data_channel);
  17863. }
  17864. }
  17865. ast_mutex_unlock(&iflock);
  17866. return 0;
  17867. }
  17868. /*!
  17869. * \internal
  17870. * \brief Callback used to generate the dahdi channels tree.
  17871. * \param[in] search The search pattern tree.
  17872. * \retval NULL on error.
  17873. * \retval non-NULL The generated tree.
  17874. */
  17875. static int dahdi_version_data_provider_get(const struct ast_data_search *search,
  17876. struct ast_data *data_root)
  17877. {
  17878. int pseudo_fd = -1;
  17879. struct dahdi_versioninfo vi = {
  17880. .version = "Unknown",
  17881. .echo_canceller = "Unknown"
  17882. };
  17883. if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) {
  17884. ast_log(LOG_ERROR, "Failed to open control file to get version.\n");
  17885. return -1;
  17886. }
  17887. if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) {
  17888. ast_log(LOG_ERROR, "Failed to get DAHDI version: %s\n", strerror(errno));
  17889. }
  17890. close(pseudo_fd);
  17891. ast_data_add_str(data_root, "value", vi.version);
  17892. ast_data_add_str(data_root, "echocanceller", vi.echo_canceller);
  17893. return 0;
  17894. }
  17895. static const struct ast_data_handler dahdi_status_data_provider = {
  17896. .version = AST_DATA_HANDLER_VERSION,
  17897. .get = dahdi_status_data_provider_get
  17898. };
  17899. static const struct ast_data_handler dahdi_channels_data_provider = {
  17900. .version = AST_DATA_HANDLER_VERSION,
  17901. .get = dahdi_channels_data_provider_get
  17902. };
  17903. static const struct ast_data_handler dahdi_version_data_provider = {
  17904. .version = AST_DATA_HANDLER_VERSION,
  17905. .get = dahdi_version_data_provider_get
  17906. };
  17907. static const struct ast_data_entry dahdi_data_providers[] = {
  17908. AST_DATA_ENTRY("asterisk/channel/dahdi/status", &dahdi_status_data_provider),
  17909. AST_DATA_ENTRY("asterisk/channel/dahdi/channels", &dahdi_channels_data_provider),
  17910. AST_DATA_ENTRY("asterisk/channel/dahdi/version", &dahdi_version_data_provider)
  17911. };
  17912. /*!
  17913. * \brief Load the module
  17914. *
  17915. * Module loading including tests for configuration or dependencies.
  17916. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  17917. * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
  17918. * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
  17919. * configuration file or other non-critical problem return
  17920. * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  17921. */
  17922. static int load_module(void)
  17923. {
  17924. int res;
  17925. #if defined(HAVE_PRI) || defined(HAVE_SS7)
  17926. int y;
  17927. #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
  17928. if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
  17929. return AST_MODULE_LOAD_FAILURE;
  17930. }
  17931. if (!(dahdi_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
  17932. return AST_MODULE_LOAD_FAILURE;
  17933. }
  17934. ast_format_cap_append(dahdi_tech.capabilities, ast_format_slin, 0);
  17935. ast_format_cap_append(dahdi_tech.capabilities, ast_format_ulaw, 0);
  17936. ast_format_cap_append(dahdi_tech.capabilities, ast_format_alaw, 0);
  17937. if (dahdi_native_load(ast_module_info->self, &dahdi_tech)) {
  17938. ao2_ref(dahdi_tech.capabilities, -1);
  17939. return AST_MODULE_LOAD_FAILURE;
  17940. }
  17941. #ifdef HAVE_PRI
  17942. memset(pris, 0, sizeof(pris));
  17943. for (y = 0; y < NUM_SPANS; y++) {
  17944. sig_pri_init_pri(&pris[y].pri);
  17945. }
  17946. pri_set_error(dahdi_pri_error);
  17947. pri_set_message(dahdi_pri_message);
  17948. ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec);
  17949. #ifdef HAVE_PRI_PROG_W_CAUSE
  17950. ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec);
  17951. #endif
  17952. #if defined(HAVE_PRI_CCSS)
  17953. if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
  17954. || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
  17955. __unload_module();
  17956. return AST_MODULE_LOAD_FAILURE;
  17957. }
  17958. #endif /* defined(HAVE_PRI_CCSS) */
  17959. if (sig_pri_load(
  17960. #if defined(HAVE_PRI_CCSS)
  17961. dahdi_pri_cc_type
  17962. #else
  17963. NULL
  17964. #endif /* defined(HAVE_PRI_CCSS) */
  17965. )) {
  17966. __unload_module();
  17967. return AST_MODULE_LOAD_FAILURE;
  17968. }
  17969. #endif
  17970. #if defined(HAVE_SS7)
  17971. memset(linksets, 0, sizeof(linksets));
  17972. for (y = 0; y < NUM_SPANS; y++) {
  17973. sig_ss7_init_linkset(&linksets[y].ss7);
  17974. }
  17975. ss7_set_error(dahdi_ss7_error);
  17976. ss7_set_message(dahdi_ss7_message);
  17977. ss7_set_hangup(sig_ss7_cb_hangup);
  17978. ss7_set_notinservice(sig_ss7_cb_notinservice);
  17979. ss7_set_call_null(sig_ss7_cb_call_null);
  17980. #endif /* defined(HAVE_SS7) */
  17981. res = setup_dahdi(0);
  17982. /* Make sure we can register our DAHDI channel type */
  17983. if (res) {
  17984. __unload_module();
  17985. return AST_MODULE_LOAD_DECLINE;
  17986. }
  17987. if (ast_channel_register(&dahdi_tech)) {
  17988. ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
  17989. __unload_module();
  17990. return AST_MODULE_LOAD_FAILURE;
  17991. }
  17992. #ifdef HAVE_PRI
  17993. ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
  17994. #endif
  17995. #if defined(HAVE_SS7)
  17996. ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
  17997. #endif /* defined(HAVE_SS7) */
  17998. #ifdef HAVE_OPENR2
  17999. ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
  18000. ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
  18001. #endif
  18002. ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));
  18003. /* register all the data providers */
  18004. ast_data_register_multiple(dahdi_data_providers, ARRAY_LEN(dahdi_data_providers));
  18005. memset(round_robin, 0, sizeof(round_robin));
  18006. ast_manager_register_xml("DAHDITransfer", 0, action_transfer);
  18007. ast_manager_register_xml("DAHDIHangup", 0, action_transferhangup);
  18008. ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook);
  18009. ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon);
  18010. ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff);
  18011. ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels);
  18012. ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart);
  18013. #if defined(HAVE_PRI)
  18014. ast_manager_register_xml("PRIShowSpans", 0, action_prishowspans);
  18015. ast_manager_register_xml("PRIDebugSet", 0, action_pri_debug_set);
  18016. ast_manager_register_xml("PRIDebugFileSet", EVENT_FLAG_SYSTEM, action_pri_debug_file_set);
  18017. ast_manager_register_xml("PRIDebugFileUnset", 0, action_pri_debug_file_unset);
  18018. #endif /* defined(HAVE_PRI) */
  18019. ast_cond_init(&ss_thread_complete, NULL);
  18020. return res;
  18021. }
  18022. static int dahdi_sendtext(struct ast_channel *c, const char *text)
  18023. {
  18024. #define END_SILENCE_LEN 400
  18025. #define HEADER_MS 50
  18026. #define TRAILER_MS 5
  18027. #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
  18028. #define ASCII_BYTES_PER_CHAR 80
  18029. unsigned char *buf,*mybuf;
  18030. struct dahdi_pvt *p = ast_channel_tech_pvt(c);
  18031. struct pollfd fds[1];
  18032. int size,res,fd,len,x;
  18033. int bytes=0;
  18034. int idx;
  18035. /*
  18036. * Initial carrier (imaginary)
  18037. *
  18038. * Note: The following float variables are used by the
  18039. * PUT_CLID_MARKMS and PUT_CLID() macros.
  18040. */
  18041. float cr = 1.0;
  18042. float ci = 0.0;
  18043. float scont = 0.0;
  18044. if (!text[0]) {
  18045. return(0); /* if nothing to send, don't */
  18046. }
  18047. idx = dahdi_get_index(c, p, 0);
  18048. if (idx < 0) {
  18049. ast_log(LOG_WARNING, "Huh? I don't exist?\n");
  18050. return -1;
  18051. }
  18052. if ((!p->tdd) && (!p->mate)) {
  18053. #if defined(HAVE_PRI)
  18054. #if defined(HAVE_PRI_DISPLAY_TEXT)
  18055. ast_mutex_lock(&p->lock);
  18056. if (dahdi_sig_pri_lib_handles(p->sig)) {
  18057. sig_pri_sendtext(p->sig_pvt, text);
  18058. }
  18059. ast_mutex_unlock(&p->lock);
  18060. #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
  18061. #endif /* defined(HAVE_PRI) */
  18062. return(0); /* if not in TDD mode, just return */
  18063. }
  18064. if (p->mate)
  18065. buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
  18066. else
  18067. buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
  18068. if (!buf)
  18069. return -1;
  18070. mybuf = buf;
  18071. if (p->mate) {
  18072. /* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
  18073. struct ast_format *codec = AST_LAW(p);
  18074. for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
  18075. PUT_CLID_MARKMS;
  18076. }
  18077. /* Put actual message */
  18078. for (x = 0; text[x]; x++) {
  18079. PUT_CLID(text[x]);
  18080. }
  18081. for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */
  18082. PUT_CLID_MARKMS;
  18083. }
  18084. len = bytes;
  18085. buf = mybuf;
  18086. } else {
  18087. len = tdd_generate(p->tdd, buf, text);
  18088. if (len < 1) {
  18089. ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
  18090. ast_free(mybuf);
  18091. return -1;
  18092. }
  18093. }
  18094. memset(buf + len, 0x7f, END_SILENCE_LEN);
  18095. len += END_SILENCE_LEN;
  18096. fd = p->subs[idx].dfd;
  18097. while (len) {
  18098. if (ast_check_hangup(c)) {
  18099. ast_free(mybuf);
  18100. return -1;
  18101. }
  18102. size = len;
  18103. if (size > READ_SIZE)
  18104. size = READ_SIZE;
  18105. fds[0].fd = fd;
  18106. fds[0].events = POLLOUT | POLLPRI;
  18107. fds[0].revents = 0;
  18108. res = poll(fds, 1, -1);
  18109. if (!res) {
  18110. ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
  18111. continue;
  18112. }
  18113. /* if got exception */
  18114. if (fds[0].revents & POLLPRI) {
  18115. ast_free(mybuf);
  18116. return -1;
  18117. }
  18118. if (!(fds[0].revents & POLLOUT)) {
  18119. ast_debug(1, "write fd not ready on channel %d\n", p->channel);
  18120. continue;
  18121. }
  18122. res = write(fd, buf, size);
  18123. if (res != size) {
  18124. if (res == -1) {
  18125. ast_free(mybuf);
  18126. return -1;
  18127. }
  18128. ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
  18129. break;
  18130. }
  18131. len -= size;
  18132. buf += size;
  18133. }
  18134. ast_free(mybuf);
  18135. return(0);
  18136. }
  18137. static int reload(void)
  18138. {
  18139. int res = 0;
  18140. res = setup_dahdi(1);
  18141. if (res) {
  18142. ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
  18143. return -1;
  18144. }
  18145. return 0;
  18146. }
  18147. /* This is a workaround so that menuselect displays a proper description
  18148. * AST_MODULE_INFO(, , "DAHDI Telephony"
  18149. */
  18150. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, tdesc,
  18151. .support_level = AST_MODULE_SUPPORT_CORE,
  18152. .load = load_module,
  18153. .unload = unload_module,
  18154. .reload = reload,
  18155. .load_pri = AST_MODPRI_CHANNEL_DRIVER,
  18156. .nonoptreq = "res_smdi",
  18157. );