chan_unistim.c 205 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * UNISTIM channel driver for asterisk
  5. *
  6. * Copyright (C) 2005 - 2007, Cedric Hans
  7. *
  8. * Cedric Hans <cedric.hans@mlkj.net>
  9. *
  10. * Asterisk 1.4 patch by Peter Be
  11. *
  12. * See http://www.asterisk.org for more information about
  13. * the Asterisk project. Please do not directly contact
  14. * any of the maintainers of this project for assistance;
  15. * the project provides a web site, mailing lists and IRC
  16. * channels for your use.
  17. *
  18. * This program is free software, distributed under the terms of
  19. * the GNU General Public License Version 2. See the LICENSE file
  20. * at the top of the source tree.
  21. */
  22. /*!
  23. * \file
  24. *
  25. * \brief chan_unistim channel driver for Asterisk
  26. * \author Cedric Hans <cedric.hans@mlkj.net>
  27. *
  28. * Unistim (Unified Networks IP Stimulus) channel driver
  29. * for Nortel i2002, i2004 and i2050
  30. *
  31. * \ingroup channel_drivers
  32. */
  33. /*** MODULEINFO
  34. <support_level>extended</support_level>
  35. ***/
  36. #include "asterisk.h"
  37. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  38. #include <sys/stat.h>
  39. #include <signal.h>
  40. #if defined(__CYGWIN__)
  41. /*
  42. * cygwin headers are partly inconsistent. struct iovec is defined in sys/uio.h
  43. * which is not included by default by sys/socket.h - in_pktinfo is defined in
  44. * w32api/ws2tcpip.h but this probably has compatibility problems with sys/socket.h
  45. * So for the time being we simply disable HAVE_PKTINFO when building under cygwin.
  46. * This should be done in some common header, but for now this is the only file
  47. * using iovec and in_pktinfo so it suffices to apply the fix here.
  48. */
  49. #ifdef HAVE_PKTINFO
  50. #undef HAVE_PKTINFO
  51. #endif
  52. #endif /* __CYGWIN__ */
  53. #include "asterisk/paths.h" /* ast_config_AST_LOG_DIR used in (too ?) many places */
  54. #include "asterisk/network.h"
  55. #include "asterisk/channel.h"
  56. #include "asterisk/config.h"
  57. #include "asterisk/module.h"
  58. #include "asterisk/pbx.h"
  59. #include "asterisk/rtp_engine.h"
  60. #include "asterisk/netsock2.h"
  61. #include "asterisk/acl.h"
  62. #include "asterisk/callerid.h"
  63. #include "asterisk/cli.h"
  64. #include "asterisk/app.h"
  65. #include "asterisk/musiconhold.h"
  66. #include "asterisk/causes.h"
  67. #include "asterisk/indications.h"
  68. #include "asterisk/pickup.h"
  69. #include "asterisk/astobj2.h"
  70. #include "asterisk/astdb.h"
  71. #include "asterisk/features_config.h"
  72. #include "asterisk/bridge.h"
  73. #include "asterisk/stasis_channels.h"
  74. #define DEFAULTCONTEXT "default"
  75. #define DEFAULTCALLERID "Unknown"
  76. #define DEFAULTCALLERNAME " "
  77. #define DEFAULTHEIGHT 3
  78. #define USTM_LOG_DIR "unistimHistory"
  79. #define USTM_LANG_DIR "unistimLang"
  80. /*! Size of the transmit buffer */
  81. #define MAX_BUF_SIZE 64
  82. /*! Number of slots for the transmit queue */
  83. #define MAX_BUF_NUMBER 50
  84. /*! Number of digits displayed on screen */
  85. #define MAX_SCREEN_NUMBER 15
  86. /*! Try x times before removing the phone */
  87. #define NB_MAX_RETRANSMIT 8
  88. /*! Nb of milliseconds waited when no events are scheduled */
  89. #define IDLE_WAIT 1000
  90. /*! Wait x milliseconds before resending a packet */
  91. #define RETRANSMIT_TIMER 2000
  92. /*! How often the mailbox is checked for new messages */
  93. #define TIMER_MWI 5000
  94. /*! Timeout value for entered number being dialed */
  95. #define DEFAULT_INTERDIGIT_TIMER 4000
  96. /*! Not used */
  97. #define DEFAULT_CODEC 0x00
  98. #define SIZE_PAGE 4096
  99. #define DEVICE_NAME_LEN 16
  100. #define AST_CONFIG_MAX_PATH 255
  101. #define MAX_ENTRY_LOG 30
  102. #define SUB_REAL 0
  103. #define SUB_RING 1
  104. #define SUB_THREEWAY 2
  105. #define SUB_ONHOLD 3
  106. struct ast_format_cap *global_cap;
  107. enum autoprovision {
  108. AUTOPROVISIONING_NO = 0,
  109. AUTOPROVISIONING_YES,
  110. AUTOPROVISIONING_TN
  111. };
  112. enum autoprov_extn {
  113. /*! Do not create an extension into the default dialplan */
  114. EXTENSION_NONE = 0,
  115. /*! Prompt user for an extension number and register it */
  116. EXTENSION_ASK,
  117. /*! Register an extension with the line=> value */
  118. EXTENSION_LINE,
  119. /*! Used with AUTOPROVISIONING_TN */
  120. EXTENSION_TN
  121. };
  122. #define OUTPUT_HANDSET 0xC0
  123. #define OUTPUT_HEADPHONE 0xC1
  124. #define OUTPUT_SPEAKER 0xC2
  125. #define VOLUME_LOW 0x01
  126. #define VOLUME_LOW_SPEAKER 0x03
  127. #define VOLUME_NORMAL 0x02
  128. #define VOLUME_INSANELY_LOUD 0x07
  129. #define MUTE_OFF 0x00
  130. #define MUTE_ON 0xFF
  131. #define MUTE_ON_DISCRET 0xCE
  132. #define SIZE_HEADER 6
  133. #define SIZE_MAC_ADDR 17
  134. #define TEXT_LENGTH_MAX 24
  135. #define TEXT_LINE0 0x00
  136. #define TEXT_LINE1 0x20
  137. #define TEXT_LINE2 0x40
  138. #define TEXT_NORMAL 0x05
  139. #define TEXT_INVERSE 0x25
  140. #define STATUS_LENGTH_MAX 28
  141. #define FAV_ICON_NONE 0x00
  142. #define FAV_ICON_ONHOOK_BLACK 0x20
  143. #define FAV_ICON_ONHOOK_WHITE 0x21
  144. #define FAV_ICON_SPEAKER_ONHOOK_BLACK 0x22
  145. #define FAV_ICON_SPEAKER_ONHOOK_WHITE 0x23
  146. #define FAV_ICON_OFFHOOK_BLACK 0x24
  147. #define FAV_ICON_OFFHOOK_WHITE 0x25
  148. #define FAV_ICON_ONHOLD_BLACK 0x26
  149. #define FAV_ICON_ONHOLD_WHITE 0x27
  150. #define FAV_ICON_SPEAKER_OFFHOOK_BLACK 0x28
  151. #define FAV_ICON_SPEAKER_OFFHOOK_WHITE 0x29
  152. #define FAV_ICON_PHONE_BLACK 0x2A
  153. #define FAV_ICON_PHONE_WHITE 0x2B
  154. #define FAV_ICON_SPEAKER_ONHOLD_BLACK 0x2C
  155. #define FAV_ICON_SPEAKER_ONHOLD_WHITE 0x2D
  156. #define FAV_ICON_HEADPHONES 0x2E
  157. #define FAV_ICON_HEADPHONES_ONHOLD 0x2F
  158. #define FAV_ICON_HOME 0x30
  159. #define FAV_ICON_CITY 0x31
  160. #define FAV_ICON_SHARP 0x32
  161. #define FAV_ICON_PAGER 0x33
  162. #define FAV_ICON_CALL_CENTER 0x34
  163. #define FAV_ICON_FAX 0x35
  164. #define FAV_ICON_MAILBOX 0x36
  165. #define FAV_ICON_REFLECT 0x37
  166. #define FAV_ICON_COMPUTER 0x38
  167. #define FAV_ICON_FORWARD 0x39
  168. #define FAV_ICON_LOCKED 0x3A
  169. #define FAV_ICON_TRASH 0x3B
  170. #define FAV_ICON_INBOX 0x3C
  171. #define FAV_ICON_OUTBOX 0x3D
  172. #define FAV_ICON_MEETING 0x3E
  173. #define FAV_ICON_BOX 0x3F
  174. #define FAV_BLINK_FAST 0x20
  175. #define FAV_BLINK_SLOW 0x40
  176. #define FAV_MAX_LENGTH 0x0A
  177. #define FAVNUM 6
  178. #define FAV_LINE_ICON FAV_ICON_ONHOOK_BLACK
  179. static void dummy(char *unused, ...)
  180. {
  181. return;
  182. }
  183. /*! \brief Global jitterbuffer configuration - by default, jb is disabled
  184. * \note Values shown here match the defaults shown in unistim.conf.sample */
  185. static struct ast_jb_conf default_jbconf =
  186. {
  187. .flags = 0,
  188. .max_size = 200,
  189. .resync_threshold = 1000,
  190. .impl = "fixed",
  191. .target_extra = 40,
  192. };
  193. static struct ast_jb_conf global_jbconf;
  194. /* #define DUMP_PACKET 1 */
  195. /* #define DEBUG_TIMER ast_verbose */
  196. #define DEBUG_TIMER dummy
  197. /*! Enable verbose output. can also be set with the CLI */
  198. static int unistimdebug = 0;
  199. static int unistim_port;
  200. static enum autoprovision autoprovisioning = AUTOPROVISIONING_NO;
  201. static int unistim_keepalive;
  202. static int unistimsock = -1;
  203. static struct {
  204. unsigned int tos;
  205. unsigned int tos_audio;
  206. unsigned int cos;
  207. unsigned int cos_audio;
  208. } qos = { 0, 0, 0, 0 };
  209. static struct io_context *io;
  210. static struct ast_sched_context *sched;
  211. static struct sockaddr_in public_ip = { 0, };
  212. static unsigned char *buff; /*! Receive buffer address */
  213. static int unistim_reloading = 0;
  214. AST_MUTEX_DEFINE_STATIC(unistim_reload_lock);
  215. /*! This is the thread for the monitor which checks for input on the channels
  216. * which are not currently in use. */
  217. static pthread_t monitor_thread = AST_PTHREADT_NULL;
  218. /*! Protect the monitoring thread, so only one process can kill or start it, and not
  219. * when it's doing something critical. */
  220. AST_MUTEX_DEFINE_STATIC(monlock);
  221. /*! Protect the session list */
  222. AST_MUTEX_DEFINE_STATIC(sessionlock);
  223. /*! Protect the device list */
  224. AST_MUTEX_DEFINE_STATIC(devicelock);
  225. enum phone_state {
  226. STATE_INIT,
  227. STATE_AUTHDENY,
  228. STATE_MAINPAGE,
  229. STATE_EXTENSION,
  230. STATE_DIALPAGE,
  231. STATE_RINGING,
  232. STATE_CALL,
  233. STATE_SELECTOPTION,
  234. STATE_SELECTCODEC,
  235. STATE_SELECTLANGUAGE,
  236. STATE_CLEANING,
  237. STATE_HISTORY
  238. };
  239. enum handset_state {
  240. STATE_ONHOOK,
  241. STATE_OFFHOOK,
  242. };
  243. enum phone_key {
  244. KEY_0 = 0x40,
  245. KEY_1 = 0x41,
  246. KEY_2 = 0x42,
  247. KEY_3 = 0x43,
  248. KEY_4 = 0x44,
  249. KEY_5 = 0x45,
  250. KEY_6 = 0x46,
  251. KEY_7 = 0x47,
  252. KEY_8 = 0x48,
  253. KEY_9 = 0x49,
  254. KEY_STAR = 0x4a,
  255. KEY_SHARP = 0x4b,
  256. KEY_UP = 0x4c,
  257. KEY_DOWN = 0x4d,
  258. KEY_RIGHT = 0x4e,
  259. KEY_LEFT = 0x4f,
  260. KEY_QUIT = 0x50,
  261. KEY_COPY = 0x51,
  262. KEY_FUNC1 = 0x54,
  263. KEY_FUNC2 = 0x55,
  264. KEY_FUNC3 = 0x56,
  265. KEY_FUNC4 = 0x57,
  266. KEY_ONHOLD = 0x5b,
  267. KEY_HANGUP = 0x5c,
  268. KEY_MUTE = 0x5d,
  269. KEY_HEADPHN = 0x5e,
  270. KEY_LOUDSPK = 0x5f,
  271. KEY_FAV0 = 0x60,
  272. KEY_FAV1 = 0x61,
  273. KEY_FAV2 = 0x62,
  274. KEY_FAV3 = 0x63,
  275. KEY_FAV4 = 0x64,
  276. KEY_FAV5 = 0x65,
  277. KEY_COMPUTR = 0x7b,
  278. KEY_CONF = 0x7c,
  279. KEY_SNDHIST = 0x7d,
  280. KEY_RCVHIST = 0x7e,
  281. KEY_INDEX = 0x7f
  282. };
  283. enum charset {
  284. LANG_DEFAULT,
  285. ISO_8859_1,
  286. ISO_8859_2,
  287. ISO_8859_4,
  288. ISO_8859_5,
  289. ISO_2022_JP,
  290. };
  291. static const int dtmf_row[] = { 697, 770, 852, 941 };
  292. static const float dtmf_col[] = { 1209, 1336, 1477, 1633 };
  293. struct wsabuf {
  294. u_long len;
  295. unsigned char *buf;
  296. };
  297. struct unistim_subchannel {
  298. ast_mutex_t lock;
  299. unsigned int subtype; /*! SUB_REAL, SUB_RING, SUB_THREEWAY or SUB_ONHOLD */
  300. struct ast_channel *owner; /*! Asterisk channel used by the subchannel */
  301. struct unistim_line *parent; /*! Unistim line */
  302. struct ast_rtp_instance *rtp; /*! RTP handle */
  303. int softkey; /*! Softkey assigned */
  304. pthread_t ss_thread; /*! unistim_ss thread handle */
  305. int alreadygone;
  306. char ringvolume;
  307. char ringstyle;
  308. int moh; /*!< Music on hold in progress */
  309. AST_LIST_ENTRY(unistim_subchannel) list;
  310. };
  311. /*!
  312. * \todo Convert to stringfields
  313. */
  314. struct unistim_line {
  315. ast_mutex_t lock;
  316. char name[80]; /*! Like 200 */
  317. char fullname[80]; /*! Like USTM/200\@black */
  318. char exten[AST_MAX_EXTENSION]; /*! Extension where to start */
  319. char cid_num[AST_MAX_EXTENSION]; /*! CallerID Number */
  320. char mailbox[AST_MAX_EXTENSION]; /*! Mailbox for MWI */
  321. char musicclass[MAX_MUSICCLASS]; /*! MusicOnHold class */
  322. ast_group_t callgroup; /*! Call group */
  323. ast_group_t pickupgroup; /*! Pickup group */
  324. char accountcode[AST_MAX_ACCOUNT_CODE]; /*! Account code (for billing) */
  325. int amaflags; /*! AMA flags (for billing) */
  326. struct ast_format_cap *cap; /*! Codec supported */
  327. char parkinglot[AST_MAX_CONTEXT]; /*! Parkinglot */
  328. struct unistim_line *next;
  329. struct unistim_device *parent;
  330. AST_LIST_ENTRY(unistim_line) list;
  331. };
  332. /*!
  333. * \brief A device containing one or more lines
  334. */
  335. static struct unistim_device {
  336. ast_mutex_t lock;
  337. int receiver_state; /*!< state of the receiver (see ReceiverState) */
  338. int size_phone_number; /*!< size of the phone number */
  339. char context[AST_MAX_EXTENSION]; /*!< Context to start in */
  340. char phone_number[AST_MAX_EXTENSION]; /*!< the phone number entered by the user */
  341. char redial_number[AST_MAX_EXTENSION]; /*!< the last phone number entered by the user */
  342. char id[18]; /*!< mac address of the current phone in ascii */
  343. char name[DEVICE_NAME_LEN]; /*!< name of the device */
  344. char softkeylabel[FAVNUM][11]; /*!< soft key label */
  345. char softkeynumber[FAVNUM][AST_MAX_EXTENSION]; /*!< number dialed when the soft key is pressed */
  346. char softkeyicon[FAVNUM]; /*!< icon number */
  347. char softkeydevice[FAVNUM][16]; /*!< name of the device monitored */
  348. struct unistim_subchannel *ssub[FAVNUM];
  349. struct unistim_line *sline[FAVNUM];
  350. struct unistim_device *sp[FAVNUM]; /*!< pointer to the device monitored by this soft key */
  351. char language[MAX_LANGUAGE]; /*!< Language for asterisk sounds */
  352. int height; /*!< The number of lines the phone can display */
  353. char maintext0[25]; /*!< when the phone is idle, display this string on line 0 */
  354. char maintext1[25]; /*!< when the phone is idle, display this string on line 1 */
  355. char maintext2[25]; /*!< when the phone is idle, display this string on line 2 */
  356. char titledefault[13]; /*!< title (text before date/time) */
  357. char datetimeformat; /*!< format used for displaying time/date */
  358. char contrast; /*!< contrast */
  359. char country[3]; /*!< country used for dial tone frequency */
  360. struct ast_tone_zone *tz; /*!< Tone zone for res_indications (ring, busy, congestion) */
  361. char ringvolume; /*!< Ring volume */
  362. char ringstyle; /*!< Ring melody */
  363. char cwvolume; /*!< Ring volume on call waiting */
  364. char cwstyle; /*!< Ring melody on call waiting */
  365. int interdigit_timer; /*!< Interdigit timer for dialing number by timeout */
  366. time_t nextdial; /*!< Timer used for dial by timeout */
  367. int rtp_port; /*!< RTP port used by the phone */
  368. int rtp_method; /*!< Select the unistim data used to establish a RTP session */
  369. int status_method; /*!< Select the unistim packet used for sending status text */
  370. char codec_number; /*!< The current codec used to make calls */
  371. int missed_call; /*!< Number of call unanswered */
  372. int callhistory; /*!< Allowed to record call history */
  373. int sharp_dial; /*!< Execute Dial on '#' or not */
  374. char lst_cid[TEXT_LENGTH_MAX]; /*!< Last callerID received */
  375. char lst_cnm[TEXT_LENGTH_MAX]; /*!< Last callername recevied */
  376. char call_forward[AST_MAX_EXTENSION]; /*!< Forward number */
  377. int output; /*!< Handset, headphone or speaker */
  378. int previous_output; /*!< Previous output */
  379. int volume; /*!< Default volume */
  380. int selected; /*!< softkey selected */
  381. int mute; /*!< Mute mode */
  382. int lastmsgssent; /*! Used by MWI */
  383. time_t nextmsgcheck; /*! Used by MWI */
  384. int nat; /*!< Used by the obscure ast_rtp_setnat */
  385. enum autoprov_extn extension; /*!< See ifdef EXTENSION for valid values */
  386. char extension_number[11]; /*!< Extension number entered by the user */
  387. char to_delete; /*!< Used in reload */
  388. struct ast_silence_generator *silence_generator;
  389. AST_LIST_HEAD(,unistim_subchannel) subs; /*!< pointer to our current connection, channel... */
  390. AST_LIST_HEAD(,unistim_line) lines;
  391. struct ast_ha *ha;
  392. struct unistimsession *session;
  393. struct unistim_device *next;
  394. } *devices = NULL;
  395. static struct unistimsession {
  396. ast_mutex_t lock;
  397. struct sockaddr_in sin; /*!< IP address of the phone */
  398. struct sockaddr_in sout; /*!< IP address of server */
  399. int timeout; /*!< time-out in ticks : resend packet if no ack was received before the timeout occured */
  400. unsigned short seq_phone; /*!< sequence number for the next packet (when we receive a request) */
  401. unsigned short seq_server; /*!< sequence number for the next packet (when we send a request) */
  402. unsigned short last_seq_ack; /*!< sequence number of the last ACK received */
  403. unsigned long tick_next_ping; /*!< time for the next ping */
  404. int last_buf_available; /*!< number of a free slot */
  405. int nb_retransmit; /*!< number of retransmition */
  406. int state; /*!< state of the phone (see phone_state) */
  407. int size_buff_entry; /*!< size of the buffer used to enter datas */
  408. char buff_entry[16]; /*!< Buffer for temporary datas */
  409. char macaddr[18]; /*!< mac adress of the phone (not always available) */
  410. char firmware[8]; /*!< firmware of the phone (not always available) */
  411. struct wsabuf wsabufsend[MAX_BUF_NUMBER]; /*!< Size of each paquet stored in the buffer array & pointer to this buffer */
  412. unsigned char buf[MAX_BUF_NUMBER][MAX_BUF_SIZE]; /*!< Buffer array used to keep the lastest non-acked paquets */
  413. struct unistim_device *device;
  414. struct unistimsession *next;
  415. } *sessions = NULL;
  416. /*! Store on screen phone menu item (label and handler function) */
  417. struct unistim_menu_item {
  418. char *label;
  419. int state;
  420. void (*handle_option)(struct unistimsession *);
  421. };
  422. /*! Language item for currently existed translations */
  423. struct unistim_languages {
  424. char *label;
  425. char *lang_short;
  426. int encoding;
  427. struct ao2_container *trans;
  428. };
  429. /*!
  430. * \page Unistim datagram formats
  431. *
  432. * Format of datagrams :
  433. * bytes 0 & 1 : ffff for discovery packet, 0000 for everything else
  434. * byte 2 : sequence number (high part)
  435. * byte 3 : sequence number (low part)
  436. * byte 4 : 2 = ask question or send info, 1 = answer or ACK, 0 = retransmit request
  437. * byte 5 : direction, 1 = server to phone, 2 = phone to server arguments
  438. */
  439. static const unsigned char packet_rcv_discovery[] =
  440. { 0xff, 0xff, 0xff, 0xff, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 };
  441. static const unsigned char packet_send_discovery_ack[] =
  442. { 0x00, 0x00, /*Initial Seq (2 bytes) */ 0x00, 0x00, 0x00, 0x01 };
  443. static const unsigned char packet_recv_firm_version[] =
  444. { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x0a, 0x02 };
  445. static const unsigned char packet_recv_it_type[] =
  446. { 0x00, 0x00, 0x00, 0x13, 0x9a, 0x04, 0x03 };
  447. static const unsigned char packet_recv_pressed_key[] =
  448. { 0x00, 0x00, 0x00, 0x13, 0x99, 0x04, 0x00 };
  449. static const unsigned char packet_recv_pick_up[] =
  450. { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x04 };
  451. static const unsigned char packet_recv_hangup[] =
  452. { 0x00, 0x00, 0x00, 0x13, 0x99, 0x03, 0x03 };
  453. static const unsigned char packet_recv_r2[] = { 0x00, 0x00, 0x00, 0x13, 0x96, 0x03, 0x03 };
  454. /*! TransportAdapter */
  455. static const unsigned char packet_recv_resume_connection_with_server[] =
  456. { 0xff, 0xff, 0xff, 0xff, 0x9e, 0x03, 0x08 };
  457. static const unsigned char packet_recv_mac_addr[] =
  458. { 0xff, 0xff, 0xff, 0xff, 0x9a, 0x0d, 0x07 /*MacAddr */ };
  459. static const unsigned char packet_send_date_time3[] =
  460. { 0x11, 0x09, 0x02, 0x02, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07,
  461. /*Minutes */ 0x08, 0x32
  462. };
  463. static const unsigned char packet_send_date_time[] =
  464. { 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05, /*Day */ 0x06, /*Hour */ 0x07, /*Minutes */
  465. 0x08, 0x32, 0x17, 0x04, 0x24, 0x07, 0x19,
  466. 0x04, 0x07, 0x00, 0x19, 0x05, 0x09, 0x3e, 0x0f, 0x16, 0x05, 0x00, 0x80, 0x00, 0x1e,
  467. 0x05, 0x12, 0x00, 0x78
  468. };
  469. static const unsigned char packet_send_no_ring[] =
  470. { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00 };
  471. static const unsigned char packet_send_s4[] =
  472. { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff,
  473. 0x16, 0x05, 0x1c, 0x00, 0x00, 0x17, 0x05,
  474. 0x0b, 0x00, 0x00, 0x19, 0x04, 0x00, 0x00, 0x19, 0x04, 0x00, 0x08, 0x19, 0x04, 0x00,
  475. 0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
  476. 0x31, 0x00, 0x00, 0x16, 0x05, 0x04, 0x00, 0x00
  477. };
  478. static const unsigned char packet_send_call[] =
  479. { 0x16, 0x04, 0x1a, 0x00, 0x16, 0x04, 0x11, 0x00, 0x16, 0x06, 0x32, 0xdf,
  480. 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16, 0x0a, 0x38, 0x00, 0x12, 0xca, 0x03,
  481. 0xc0, 0xc3, 0xc5, 0x16, 0x16, 0x30, 0x00,
  482. 0x00, /*codec */ 0x12, 0x12, /* frames per packet */ 0x01, 0x5c, 0x00, /*port RTP */
  483. 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41,
  484. /*port RTP */ 0x0f, 0xa0, /* port RTCP */ 0x9c, 0x41, /* IP Address */ 0x0a, 0x01,
  485. 0x16, 0x66
  486. };
  487. static const unsigned char packet_send_stream_based_tone_off[] =
  488. { 0x16, 0x05, 0x1c, 0x00, 0x00 };
  489. /* static const unsigned char packet_send_Mute[] = { 0x16, 0x05, 0x04, 0x00, 0x00 };
  490. static const unsigned char packet_send_CloseAudioStreamRX[] = { 0x16, 0x05, 0x31, 0x00, 0xff };
  491. static const unsigned char packet_send_CloseAudioStreamTX[] = { 0x16, 0x05, 0x31, 0xff, 0x00 };*/
  492. static const unsigned char packet_send_stream_based_tone_on[] =
  493. { 0x16, 0x06, 0x1b, 0x00, 0x00, 0x05 };
  494. static const unsigned char packet_send_stream_based_tone_single_freq[] =
  495. { 0x16, 0x06, 0x1d, 0x00, 0x01, 0xb8 };
  496. static const unsigned char packet_send_stream_based_tone_dial_freq[] =
  497. { 0x16, 0x08, 0x1d, 0x00, 0x01, 0xb8, 0x01, 0x5e };
  498. static const unsigned char packet_send_select_output[] =
  499. { 0x16, 0x06, 0x32, 0xc0, 0x01, 0x00 };
  500. static const unsigned char packet_send_ring[] =
  501. { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
  502. 0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13 /* Ring type 10 to 17 */ , 0x18, 0x16, 0x04, 0x18, /* volume 00, 10, 20... */
  503. 0x20, 0x16, 0x04, 0x10, 0x00
  504. };
  505. static const unsigned char packet_send_end_call[] =
  506. { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x31, 0x00, 0x00, 0x19, 0x04, 0x00,
  507. 0x10, 0x19, 0x04, 0x00, 0x18, 0x16, 0x05,
  508. 0x04, 0x00, 0x00, 0x16, 0x04, 0x37, 0x10
  509. };
  510. static const unsigned char packet_send_s9[] =
  511. { 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x19, 0x04, 0x00, 0x10, 0x16, 0x05, 0x1c, 0x00,
  512. 0x00 };
  513. static const unsigned char packet_send_rtp_packet_size[] =
  514. { 0x16, 0x08, 0x38, 0x00, 0x00, 0xe0, 0x00, 0xa0 };
  515. static const unsigned char packet_send_jitter_buffer_conf[] =
  516. { 0x16, 0x0e, 0x3a, 0x00, /* jitter */ 0x02, /* high water mark */ 0x04, 0x00, 0x00,
  517. /* early packet resync 2 bytes */ 0x3e, 0x80,
  518. 0x00, 0x00, /* late packet resync 2 bytes */ 0x3e, 0x80
  519. };
  520. /* Duration in ms div 2 (0x20 = 64ms, 0x08 = 16ms)
  521. static unsigned char packet_send_StreamBasedToneCad[] =
  522. { 0x16, 0x0a, 0x1e, 0x00, duration on 0x0a, duration off 0x0d, duration on 0x0a, duration off 0x0d, duration on 0x0a, duration off 0x2b }; */
  523. static const unsigned char packet_send_open_audio_stream_rx[] =
  524. { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
  525. 0x0e, 0x01, /* Port */ 0x14, 0x50, 0x00,
  526. 0x00, /* Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
  527. };
  528. static const unsigned char packet_send_open_audio_stream_tx[] =
  529. { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x01, 0x00, 0xb8, 0xb8, 0x0e,
  530. 0x0e, 0x01, /* Local port */ 0x14, 0x50,
  531. 0x00, 0x00, /* Rmt Port */ 0x14, 0x50, 0x00, 0x00, /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
  532. };
  533. static const unsigned char packet_send_open_audio_stream_rx3[] =
  534. { 0x16, 0x1a, 0x30, 0x00, 0xff, /* Codec */ 0x00, 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
  535. 0x06, 0x81, /* RTP Port */ 0x14, 0x50,
  536. /* RTCP Port */ 0x14,
  537. 0x51, /* RTP Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00, /* Dest IP */ 0x0a, 0x93,
  538. 0x69, 0x05
  539. };
  540. static const unsigned char packet_send_open_audio_stream_tx3[] =
  541. { 0x16, 0x1a, 0x30, 0xff, 0x00, 0x00, /* Codec */ 0x00, 0x02, 0x01, 0xb8, 0xb8, 0x06,
  542. 0x06, 0x81, /* RTP Local port */ 0x14, 0x50,
  543. /* RTCP Port */ 0x00, 0x00, /* RTP Rmt Port */ 0x14, 0x50, /* RTCP Port */ 0x00, 0x00,
  544. /* Dest IP */ 0x0a, 0x93, 0x69, 0x05
  545. };
  546. static const unsigned char packet_send_arrow[] = { 0x17, 0x04, 0x04, 0x00 };
  547. static const unsigned char packet_send_blink_cursor[] = { 0x17, 0x04, 0x10, 0x86 };
  548. static const unsigned char packet_send_date_time2[] = { 0x17, 0x04, 0x17, 0x3d, 0x11, 0x09, 0x02, 0x0a, /*Month */ 0x05, /*Day */
  549. 0x06, /*Hour */ 0x07, /*Minutes */ 0x08, 0x32
  550. };
  551. static const unsigned char packet_send_Contrast[] =
  552. { 0x17, 0x04, 0x24, /*Contrast */ 0x08 };
  553. static const unsigned char packet_send_start_timer[] =
  554. { 0x17, 0x05, 0x0b, /*Timer option*/0x05, /* Timer ID */0x00, 0x17, 0x08, 0x16,
  555. /* Text */ 0x44, 0x75, 0x72, 0xe9, 0x65 };
  556. static const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, 0x02, 0x00 };
  557. static const unsigned char packet_send_icon[] = { 0x17, 0x05, 0x14, /*pos */ 0x00, /*icon */ 0x25 }; /* display an icon in front of the text zone */
  558. static const unsigned char packet_send_S7[] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 };
  559. static const unsigned char packet_send_set_pos_cursor[] =
  560. { 0x17, 0x06, 0x10, 0x81, 0x04, /*pos */ 0x20 };
  561. /*static unsigned char packet_send_MonthLabelsDownload[] =
  562. { 0x17, 0x0a, 0x15, Month (3 char) 0x46, 0x65, 0x62, 0x4d, 0xe4, 0x72, 0x20 }; */
  563. static const unsigned char packet_send_favorite[] =
  564. { 0x17, 0x0f, 0x19, 0x10, /*pos */ 0x01, /*name */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  565. 0x20, 0x20, 0x20, 0x20, /*end_name */ 0x19,
  566. 0x05, 0x0f, /*pos */ 0x01, /*icone */ 0x00
  567. };
  568. static const unsigned char packet_send_title[] =
  569. { 0x17, 0x10, 0x19, 0x02, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  570. 0x20, 0x20, 0x20, 0x20 /*end_text */ };
  571. static const unsigned char packet_send_text[] =
  572. { 0x17, 0x1e, 0x1b, 0x04, /*pos */ 0x00, /*inverse */ 0x25, /*text */ 0x20, 0x20,
  573. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  574. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  575. /*end_text */ 0x17, 0x04, 0x10, 0x87
  576. };
  577. static const unsigned char packet_send_status[] =
  578. { 0x17, 0x20, 0x19, 0x08, /*text */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  579. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  580. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 /*end_text */
  581. };
  582. static const unsigned char packet_send_status2[] =
  583. { 0x17, 0x0b, 0x19, /* pos [08|28|48|68] */ 0x00, /* text */ 0x20, 0x20, 0x20, 0x20,
  584. 0x20, 0x20, 0x20 /* end_text */ };
  585. /* Multiple character set support */
  586. /* ISO-8859-1 - Western European) */
  587. static const unsigned char packet_send_charset_iso_8859_1[] =
  588. { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x41, 0x1b, 0x00 };
  589. /* ISO-8859-2 - Central European) */
  590. static const unsigned char packet_send_charset_iso_8859_2[] =
  591. { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x42, 0x1b, 0x00 };
  592. /* ISO-8859-4 - Baltic) */
  593. static const unsigned char packet_send_charset_iso_8859_4[] =
  594. { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x44, 0x1b, 0x00 };
  595. /* ISO 8859-5 - cyrilic */
  596. static const unsigned char packet_send_charset_iso_8859_5[] =
  597. { 0x17, 0x08, 0x21, 0x1b, 0x2d, 0x4c, 0x1b, 0x00 };
  598. /* Japaneese (ISO-2022-JP ?) */
  599. static const unsigned char packet_send_charset_iso_2022_jp[] =
  600. { 0x17, 0x08, 0x21, 0x1b, 0x29, 0x49, 0x1b, 0x7e };
  601. static const unsigned char packet_send_led_update[] = { 0x19, 0x04, 0x00, 0x00 };
  602. static const unsigned char packet_send_query_basic_manager_04[] = { 0x1a, 0x04, 0x01, 0x04 };
  603. static const unsigned char packet_send_query_mac_address[] = { 0x1a, 0x04, 0x01, 0x08 };
  604. static const unsigned char packet_send_query_basic_manager_10[] = { 0x1a, 0x04, 0x01, 0x10 };
  605. static const unsigned char packet_send_S1[] = { 0x1a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x13 };
  606. static unsigned char packet_send_ping[] =
  607. { 0x1e, 0x05, 0x12, 0x00, /*Watchdog timer */ 0x78 };
  608. #define BUFFSEND unsigned char buffsend[64] = { 0x00, 0x00, 0xaa, 0xbb, 0x02, 0x01 }
  609. static const char tdesc[] = "UNISTIM Channel Driver";
  610. static const char channel_type[] = "USTM";
  611. /*! Protos */
  612. static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
  613. static int load_module(void);
  614. static int reload(void);
  615. static int unload_module(void);
  616. static int reload_config(void);
  617. static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan);
  618. static void show_main_page(struct unistimsession *pte);
  619. static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
  620. const char *dest, int *cause);
  621. static int unistim_call(struct ast_channel *ast, const char *dest, int timeout);
  622. static int unistim_hangup(struct ast_channel *ast);
  623. static int unistim_answer(struct ast_channel *ast);
  624. static struct ast_frame *unistim_read(struct ast_channel *ast);
  625. static int unistim_write(struct ast_channel *ast, struct ast_frame *frame);
  626. static int unistim_indicate(struct ast_channel *ast, int ind, const void *data,
  627. size_t datalen);
  628. static int unistim_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
  629. static int unistim_senddigit_begin(struct ast_channel *ast, char digit);
  630. static int unistim_senddigit_end(struct ast_channel *ast, char digit,
  631. unsigned int duration);
  632. static int unistim_sendtext(struct ast_channel *ast, const char *text);
  633. static int write_entry_history(struct unistimsession *pte, FILE * f, char c,
  634. char *line1);
  635. static void change_callerid(struct unistimsession *pte, int type, char *callerid);
  636. static struct ast_channel_tech unistim_tech = {
  637. .type = channel_type,
  638. .description = tdesc,
  639. .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
  640. .requester = unistim_request,
  641. .call = unistim_call,
  642. .hangup = unistim_hangup,
  643. .answer = unistim_answer,
  644. .read = unistim_read,
  645. .write = unistim_write,
  646. .indicate = unistim_indicate,
  647. .fixup = unistim_fixup,
  648. .send_digit_begin = unistim_senddigit_begin,
  649. .send_digit_end = unistim_senddigit_end,
  650. .send_text = unistim_sendtext,
  651. };
  652. static void send_start_rtp(struct unistim_subchannel *);
  653. static void send_callerid_screen(struct unistimsession *, struct unistim_subchannel *);
  654. static void key_favorite(struct unistimsession *, char);
  655. static void handle_select_codec(struct unistimsession *);
  656. static void handle_select_language(struct unistimsession *);
  657. static int find_language(const char*);
  658. static int unistim_free_sub(struct unistim_subchannel *);
  659. static struct unistim_menu_item options_menu[] =
  660. {
  661. {"Change codec", STATE_SELECTCODEC, handle_select_codec},
  662. {"Language", STATE_SELECTLANGUAGE, handle_select_language},
  663. {NULL, 0, NULL}
  664. };
  665. static struct unistim_languages options_languages[] =
  666. {
  667. {"English", "en", ISO_8859_1, NULL},
  668. {"French", "fr", ISO_8859_1, NULL},
  669. {"Russian", "ru", ISO_8859_5, NULL},
  670. {NULL, NULL, 0, NULL}
  671. };
  672. static char ustm_strcopy[1024];
  673. struct ustm_lang_entry {
  674. const char *str_orig;
  675. const char *str_trans;
  676. };
  677. static int lang_hash_fn(const void *obj, const int flags)
  678. {
  679. const struct ustm_lang_entry *entry = obj;
  680. return ast_str_hash(entry->str_orig);
  681. }
  682. static int lang_cmp_fn(void *obj, void *arg, int flags)
  683. {
  684. struct ustm_lang_entry *entry1 = obj;
  685. struct ustm_lang_entry *entry2 = arg;
  686. return (!strcmp(entry1->str_orig, entry2->str_orig)) ? (CMP_MATCH | CMP_STOP) : 0;
  687. }
  688. static const char *ustmtext(const char *str, struct unistimsession *pte)
  689. {
  690. struct ustm_lang_entry *lang_entry;
  691. struct ustm_lang_entry le_search;
  692. struct unistim_languages *lang = NULL;
  693. int size;
  694. if (pte->device) {
  695. lang = &options_languages[find_language(pte->device->language)];
  696. }
  697. if (!lang) {
  698. return str;
  699. }
  700. /* Check if specified language exists */
  701. if (!lang->trans) {
  702. char tmp[1024], *p, *p_orig = NULL, *p_trans = NULL;
  703. FILE *f;
  704. if (!(lang->trans = ao2_container_alloc(8, lang_hash_fn, lang_cmp_fn))) {
  705. ast_log(LOG_ERROR, "Unable to allocate container for translation!\n");
  706. return str;
  707. }
  708. snprintf(tmp, sizeof(tmp), "%s/%s/%s.po", ast_config_AST_VAR_DIR,
  709. USTM_LANG_DIR, lang->lang_short);
  710. f = fopen(tmp, "r");
  711. if (!f) {
  712. ast_log(LOG_WARNING, "There is no translation file for '%s'\n", lang->lang_short);
  713. return str;
  714. }
  715. while (fgets(tmp, sizeof(tmp), f)) {
  716. if (!(p = strchr(tmp, '\n'))) {
  717. ast_log(LOG_ERROR, "Too long line found in language file - truncated!\n");
  718. continue;
  719. }
  720. *p = '\0';
  721. if (!(p = strchr(tmp, '"'))) {
  722. continue;
  723. }
  724. if (tmp == strstr(tmp, "msgid")) {
  725. p_orig = ast_strdup(p + 1);
  726. p = strchr(p_orig, '"');
  727. } else if (tmp == strstr(tmp, "msgstr")) {
  728. p_trans = ast_strdup(p + 1);
  729. p = strchr(p_trans, '"');
  730. } else {
  731. continue;
  732. }
  733. *p = '\0';
  734. if (!p_trans || !p_orig) {
  735. continue;
  736. }
  737. if (ast_strlen_zero(p_trans)) {
  738. ast_free(p_trans);
  739. ast_free(p_orig);
  740. p_trans = NULL;
  741. p_orig = NULL;
  742. continue;
  743. }
  744. if (!(lang_entry = ao2_alloc(sizeof(*lang_entry), NULL))) {
  745. fclose(f);
  746. return str;
  747. }
  748. lang_entry->str_trans = p_trans;
  749. lang_entry->str_orig = p_orig;
  750. ao2_link(lang->trans, lang_entry);
  751. p_trans = NULL;
  752. p_orig = NULL;
  753. }
  754. fclose(f);
  755. }
  756. le_search.str_orig = str;
  757. if ((lang_entry = ao2_find(lang->trans, &le_search, OBJ_POINTER))) {
  758. size = strlen(lang_entry->str_trans)+1;
  759. if (size > 1024) {
  760. size = 1024;
  761. }
  762. memcpy(ustm_strcopy, lang_entry->str_trans, size);
  763. ao2_ref(lang_entry, -1);
  764. return ustm_strcopy;
  765. }
  766. return str;
  767. }
  768. static void display_last_error(const char *sz_msg)
  769. {
  770. /* Display the error message */
  771. ast_log(LOG_WARNING, "%s : (%d) %s\n", sz_msg, errno, strerror(errno));
  772. }
  773. static unsigned int get_tick_count(void)
  774. {
  775. struct timeval now = ast_tvnow();
  776. return (now.tv_sec * 1000) + (now.tv_usec / 1000);
  777. }
  778. /* Send data to a phone without retransmit nor buffering */
  779. static void send_raw_client(int size, const unsigned char *data, struct sockaddr_in *addr_to,
  780. const struct sockaddr_in *addr_ourip)
  781. {
  782. #ifdef HAVE_PKTINFO
  783. struct iovec msg_iov;
  784. struct msghdr msg;
  785. char buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
  786. struct cmsghdr *ip_msg = (struct cmsghdr *) buffer;
  787. struct in_pktinfo *pki = (struct in_pktinfo *) CMSG_DATA(ip_msg);
  788. /* cast this to a non-const pointer, since the sendmsg() API
  789. * does not provide read-only and write-only flavors of the
  790. * structures used for its arguments, but in this case we know
  791. * the data will not be modified
  792. */
  793. msg_iov.iov_base = (char *) data;
  794. msg_iov.iov_len = size;
  795. msg.msg_name = addr_to; /* optional address */
  796. msg.msg_namelen = sizeof(struct sockaddr_in); /* size of address */
  797. msg.msg_iov = &msg_iov; /* scatter/gather array */
  798. msg.msg_iovlen = 1; /* # elements in msg_iov */
  799. msg.msg_control = ip_msg; /* ancillary data */
  800. msg.msg_controllen = sizeof(buffer); /* ancillary data buffer len */
  801. msg.msg_flags = 0; /* flags on received message */
  802. ip_msg->cmsg_len = CMSG_LEN(sizeof(*pki));
  803. ip_msg->cmsg_level = IPPROTO_IP;
  804. ip_msg->cmsg_type = IP_PKTINFO;
  805. pki->ipi_ifindex = 0; /* Interface index, 0 = use interface specified in routing table */
  806. pki->ipi_spec_dst.s_addr = addr_ourip->sin_addr.s_addr; /* Local address */
  807. /* pki->ipi_addr = ; Header Destination address - ignored by kernel */
  808. #ifdef DUMP_PACKET
  809. if (unistimdebug) {
  810. int tmp;
  811. ast_verb(0, "\n**> From %s sending %d bytes to %s ***\n",
  812. ast_inet_ntoa(addr_ourip->sin_addr), (int) size,
  813. ast_inet_ntoa(addr_to->sin_addr));
  814. for (tmp = 0; tmp < size; tmp++)
  815. ast_verb(0, "%02hhx ", data[tmp]);
  816. ast_verb(0, "\n******************************************\n");
  817. }
  818. #endif
  819. if (sendmsg(unistimsock, &msg, 0) == -1) {
  820. display_last_error("Error sending datas");
  821. }
  822. #else
  823. if (sendto(unistimsock, data, size, 0, (struct sockaddr *) addr_to, sizeof(*addr_to))
  824. == -1)
  825. display_last_error("Error sending datas");
  826. #endif
  827. }
  828. static void send_client(int size, const unsigned char *data, struct unistimsession *pte)
  829. {
  830. unsigned int tick;
  831. int buf_pos;
  832. unsigned short seq = ntohs(++pte->seq_server);
  833. ast_mutex_lock(&pte->lock);
  834. buf_pos = pte->last_buf_available;
  835. if (buf_pos >= MAX_BUF_NUMBER) {
  836. ast_log(LOG_WARNING, "Error : send queue overflow\n");
  837. ast_mutex_unlock(&pte->lock);
  838. return;
  839. }
  840. memcpy((void *)data + sizeof(unsigned short), (void *)&seq, sizeof(unsigned short));
  841. pte->wsabufsend[buf_pos].len = size;
  842. memcpy(pte->wsabufsend[buf_pos].buf, data, size);
  843. tick = get_tick_count();
  844. pte->timeout = tick + RETRANSMIT_TIMER;
  845. /*#ifdef DUMP_PACKET */
  846. if (unistimdebug) {
  847. ast_verb(6, "Sending datas with seq #0x%04x Using slot #%d :\n", (unsigned)pte->seq_server, buf_pos);
  848. }
  849. /*#endif */
  850. send_raw_client(pte->wsabufsend[buf_pos].len, pte->wsabufsend[buf_pos].buf, &(pte->sin),
  851. &(pte->sout));
  852. pte->last_buf_available++;
  853. ast_mutex_unlock(&pte->lock);
  854. }
  855. static void send_ping(struct unistimsession *pte)
  856. {
  857. BUFFSEND;
  858. if (unistimdebug) {
  859. ast_verb(6, "Sending ping\n");
  860. }
  861. pte->tick_next_ping = get_tick_count() + unistim_keepalive;
  862. memcpy(buffsend + SIZE_HEADER, packet_send_ping, sizeof(packet_send_ping));
  863. send_client(SIZE_HEADER + sizeof(packet_send_ping), buffsend, pte);
  864. }
  865. static int get_to_address(int fd, struct sockaddr_in *toAddr)
  866. {
  867. #ifdef HAVE_PKTINFO
  868. int err;
  869. struct msghdr msg;
  870. struct {
  871. struct cmsghdr cm;
  872. int len;
  873. struct in_addr address;
  874. } ip_msg;
  875. /* Zero out the structures before we use them */
  876. /* This sets several key values to NULL */
  877. memset(&msg, 0, sizeof(msg));
  878. memset(&ip_msg, 0, sizeof(ip_msg));
  879. /* Initialize the message structure */
  880. msg.msg_control = &ip_msg;
  881. msg.msg_controllen = sizeof(ip_msg);
  882. /* Get info about the incoming packet */
  883. err = recvmsg(fd, &msg, MSG_PEEK);
  884. if (err == -1) {
  885. ast_log(LOG_WARNING, "recvmsg returned an error: %s\n", strerror(errno));
  886. }
  887. memcpy(&toAddr->sin_addr, &ip_msg.address, sizeof(struct in_addr));
  888. return err;
  889. #else
  890. memcpy(&toAddr, &public_ip, sizeof(&toAddr));
  891. return 0;
  892. #endif
  893. }
  894. /* Allocate memory & initialize structures for a new phone */
  895. /* addr_from : ip address of the phone */
  896. static struct unistimsession *create_client(const struct sockaddr_in *addr_from)
  897. {
  898. int tmp;
  899. struct unistimsession *s;
  900. if (!(s = ast_calloc(1, sizeof(*s))))
  901. return NULL;
  902. memcpy(&s->sin, addr_from, sizeof(struct sockaddr_in));
  903. get_to_address(unistimsock, &s->sout);
  904. s->sout.sin_family = AF_INET;
  905. if (unistimdebug) {
  906. ast_verb(0, "Creating a new entry for the phone from %s received via server ip %s\n",
  907. ast_inet_ntoa(addr_from->sin_addr), ast_inet_ntoa(s->sout.sin_addr));
  908. }
  909. ast_mutex_init(&s->lock);
  910. ast_mutex_lock(&sessionlock);
  911. s->next = sessions;
  912. sessions = s;
  913. s->timeout = get_tick_count() + RETRANSMIT_TIMER;
  914. s->state = STATE_INIT;
  915. s->tick_next_ping = get_tick_count() + unistim_keepalive;
  916. /* Initialize struct wsabuf */
  917. for (tmp = 0; tmp < MAX_BUF_NUMBER; tmp++) {
  918. s->wsabufsend[tmp].buf = s->buf[tmp];
  919. }
  920. ast_mutex_unlock(&sessionlock);
  921. return s;
  922. }
  923. static void send_end_call(struct unistimsession *pte)
  924. {
  925. BUFFSEND;
  926. if (unistimdebug) {
  927. ast_verb(0, "Sending end call\n");
  928. }
  929. memcpy(buffsend + SIZE_HEADER, packet_send_end_call, sizeof(packet_send_end_call));
  930. send_client(SIZE_HEADER + sizeof(packet_send_end_call), buffsend, pte);
  931. }
  932. static void set_ping_timer(struct unistimsession *pte)
  933. {
  934. unsigned int tick = 0; /* XXX what is this for, anyways */
  935. pte->timeout = pte->tick_next_ping;
  936. DEBUG_TIMER("tick = %u next ping at %u tick\n", tick, pte->timeout);
  937. return;
  938. }
  939. /* Checking if our send queue is empty,
  940. * if true, setting up a timer for keepalive */
  941. static void check_send_queue(struct unistimsession *pte)
  942. {
  943. /* Check if our send queue contained only one element */
  944. if (pte->last_buf_available == 1) {
  945. if (unistimdebug) {
  946. ast_verb(6, "Our single packet was ACKed.\n");
  947. }
  948. pte->last_buf_available--;
  949. set_ping_timer(pte);
  950. return;
  951. }
  952. /* Check if this ACK catch up our latest packet */
  953. else if (pte->last_seq_ack + 1 == pte->seq_server + 1) {
  954. if (unistimdebug) {
  955. ast_verb(6, "Our send queue is completely ACKed.\n");
  956. }
  957. pte->last_buf_available = 0; /* Purge the send queue */
  958. set_ping_timer(pte);
  959. return;
  960. }
  961. if (unistimdebug) {
  962. ast_verb(6, "We still have packets in our send queue\n");
  963. }
  964. return;
  965. }
  966. static void send_start_timer(struct unistimsession *pte)
  967. {
  968. BUFFSEND;
  969. if (unistimdebug) {
  970. ast_verb(0, "Sending start timer\n");
  971. }
  972. memcpy(buffsend + SIZE_HEADER, packet_send_start_timer, sizeof(packet_send_start_timer));
  973. send_client(SIZE_HEADER + sizeof(packet_send_start_timer), buffsend, pte);
  974. }
  975. static void send_stop_timer(struct unistimsession *pte)
  976. {
  977. BUFFSEND;
  978. if (unistimdebug) {
  979. ast_verb(0, "Sending stop timer\n");
  980. }
  981. memcpy(buffsend + SIZE_HEADER, packet_send_stop_timer, sizeof(packet_send_stop_timer));
  982. send_client(SIZE_HEADER + sizeof(packet_send_stop_timer), buffsend, pte);
  983. }
  984. static void send_icon(unsigned char pos, unsigned char status, struct unistimsession *pte)
  985. {
  986. BUFFSEND;
  987. if (unistimdebug) {
  988. ast_verb(0, "Sending icon pos %d with status 0x%02hhx\n", pos, status);
  989. }
  990. memcpy(buffsend + SIZE_HEADER, packet_send_icon, sizeof(packet_send_icon));
  991. buffsend[9] = pos;
  992. buffsend[10] = status;
  993. send_client(SIZE_HEADER + sizeof(packet_send_icon), buffsend, pte);
  994. }
  995. static void send_tone(struct unistimsession *pte, uint16_t tone1, uint16_t tone2)
  996. {
  997. BUFFSEND;
  998. if (!tone1) {
  999. if (unistimdebug) {
  1000. ast_verb(0, "Sending Stream Based Tone Off\n");
  1001. }
  1002. memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_off,
  1003. sizeof(packet_send_stream_based_tone_off));
  1004. send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_off), buffsend, pte);
  1005. return;
  1006. }
  1007. /* Since most of the world use a continuous tone, it's useless
  1008. if (unistimdebug)
  1009. ast_verb(0, "Sending Stream Based Tone Cadence Download\n");
  1010. memcpy (buffsend + SIZE_HEADER, packet_send_StreamBasedToneCad, sizeof (packet_send_StreamBasedToneCad));
  1011. send_client (SIZE_HEADER + sizeof (packet_send_StreamBasedToneCad), buffsend, pte); */
  1012. if (unistimdebug) {
  1013. ast_verb(0, "Sending Stream Based Tone Frequency Component List Download %d %d\n", tone1, tone2);
  1014. }
  1015. tone1 *= 8;
  1016. if (!tone2) {
  1017. memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_single_freq,
  1018. sizeof(packet_send_stream_based_tone_single_freq));
  1019. buffsend[10] = (tone1 & 0xff00) >> 8;
  1020. buffsend[11] = (tone1 & 0x00ff);
  1021. send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_single_freq), buffsend,
  1022. pte);
  1023. } else {
  1024. tone2 *= 8;
  1025. memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_dial_freq,
  1026. sizeof(packet_send_stream_based_tone_dial_freq));
  1027. buffsend[10] = (tone1 & 0xff00) >> 8;
  1028. buffsend[11] = (tone1 & 0x00ff);
  1029. buffsend[12] = (tone2 & 0xff00) >> 8;
  1030. buffsend[13] = (tone2 & 0x00ff);
  1031. send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_dial_freq), buffsend,
  1032. pte);
  1033. }
  1034. if (unistimdebug) {
  1035. ast_verb(0, "Sending Stream Based Tone On\n");
  1036. }
  1037. memcpy(buffsend + SIZE_HEADER, packet_send_stream_based_tone_on,
  1038. sizeof(packet_send_stream_based_tone_on));
  1039. send_client(SIZE_HEADER + sizeof(packet_send_stream_based_tone_on), buffsend, pte);
  1040. }
  1041. /* Positions for favorites
  1042. |--------------------|
  1043. | 5 2 | <-- not on screen in i2002
  1044. | 4 1 |
  1045. | 3 0 |
  1046. */
  1047. /* status (icons) : 00 = nothing, 2x/3x = see parser.h, 4x/5x = blink fast, 6x/7x = blink slow */
  1048. static void
  1049. send_favorite(unsigned char pos, unsigned char status, struct unistimsession *pte,
  1050. const char *text)
  1051. {
  1052. BUFFSEND;
  1053. int i;
  1054. if (unistimdebug) {
  1055. ast_verb(0, "Sending favorite pos %d with status 0x%02hhx\n", pos, status);
  1056. }
  1057. memcpy(buffsend + SIZE_HEADER, packet_send_favorite, sizeof(packet_send_favorite));
  1058. buffsend[10] = pos;
  1059. buffsend[24] = pos;
  1060. buffsend[25] = status;
  1061. i = strlen(ustmtext(text, pte));
  1062. if (i > FAV_MAX_LENGTH) {
  1063. i = FAV_MAX_LENGTH;
  1064. }
  1065. memcpy(buffsend + FAV_MAX_LENGTH + 1, ustmtext(text, pte), i);
  1066. send_client(SIZE_HEADER + sizeof(packet_send_favorite), buffsend, pte);
  1067. }
  1068. static void send_favorite_short(unsigned char pos, unsigned char status, struct unistimsession *pte) {
  1069. send_favorite(pos, status, pte, pte->device->softkeylabel[pos]);
  1070. return;
  1071. }
  1072. static void send_favorite_selected(unsigned char status, struct unistimsession *pte) {
  1073. if (pte->device->selected != -1) {
  1074. send_favorite(pte->device->selected, status, pte, pte->device->softkeylabel[pte->device->selected]);
  1075. }
  1076. return;
  1077. }
  1078. static int soft_key_visible(struct unistim_device* d, unsigned char num)
  1079. {
  1080. if(d->height == 1 && num % 3 == 2) {
  1081. return 0;
  1082. }
  1083. return 1;
  1084. }
  1085. static void refresh_all_favorite(struct unistimsession *pte)
  1086. {
  1087. unsigned char i = 0;
  1088. char data[256];
  1089. struct unistim_line *line;
  1090. line = AST_LIST_FIRST(&pte->device->lines);
  1091. if (unistimdebug) {
  1092. ast_verb(0, "Refreshing all favorite\n");
  1093. }
  1094. for (i = 0; i < FAVNUM; i++) {
  1095. unsigned char status = pte->device->softkeyicon[i];
  1096. if (!soft_key_visible(pte->device, i)) {
  1097. continue;
  1098. }
  1099. if (!strcasecmp(pte->device->softkeylabel[i], "DND") && line) {
  1100. if (!ast_db_get("DND", line->name, data, sizeof(data))) {
  1101. status = FAV_ICON_SPEAKER_ONHOOK_WHITE;
  1102. }
  1103. }
  1104. send_favorite_short(i, status, pte);
  1105. }
  1106. }
  1107. static int is_key_favorite(struct unistim_device *d, int fav)
  1108. {
  1109. if ((fav < 0) && (fav > 5)) {
  1110. return 0;
  1111. }
  1112. if (d->sline[fav]) {
  1113. return 0;
  1114. }
  1115. if (d->softkeynumber[fav][0] == '\0') {
  1116. return 0;
  1117. }
  1118. return 1;
  1119. }
  1120. static int is_key_line(struct unistim_device *d, int fav)
  1121. {
  1122. if ((fav < 0) && (fav > 5)) {
  1123. return 0;
  1124. }
  1125. if (!d->sline[fav]) {
  1126. return 0;
  1127. }
  1128. if (is_key_favorite(d, fav)) {
  1129. return 0;
  1130. }
  1131. return 1;
  1132. }
  1133. static int get_active_softkey(struct unistimsession *pte)
  1134. {
  1135. return pte->device->selected;
  1136. }
  1137. static int get_avail_softkey(struct unistimsession *pte, const char* name)
  1138. {
  1139. int i;
  1140. if (!is_key_line(pte->device, pte->device->selected)) {
  1141. pte->device->selected = -1;
  1142. }
  1143. for (i = 0; i < FAVNUM; i++) {
  1144. if (pte->device->selected != -1 && pte->device->selected != i) {
  1145. continue;
  1146. }
  1147. if (!soft_key_visible(pte->device, i)) {
  1148. continue;
  1149. }
  1150. if (pte->device->ssub[i]) {
  1151. continue;
  1152. }
  1153. if (is_key_line(pte->device, i)) {
  1154. if (name && strcmp(name, pte->device->sline[i]->name)) {
  1155. continue;
  1156. }
  1157. if (unistimdebug) {
  1158. ast_verb(0, "Found softkey %d for device %s\n", i, name);
  1159. }
  1160. return i;
  1161. }
  1162. }
  1163. return -1;
  1164. }
  1165. /* Change the status for this phone (pte) and update for each phones where pte is bookmarked
  1166. * use FAV_ICON_*_BLACK constant in status parameters */
  1167. static void change_favorite_icon(struct unistimsession *pte, unsigned char status)
  1168. {
  1169. struct unistim_device *d = devices;
  1170. int i;
  1171. /* Update the current phone line softkey icon */
  1172. if (pte->state != STATE_CLEANING) {
  1173. int softkeylinepos = get_active_softkey(pte);
  1174. if (softkeylinepos != -1) {
  1175. send_favorite_short(softkeylinepos, status, pte);
  1176. }
  1177. }
  1178. /* Notify other phones if we're in their bookmark */
  1179. while (d) {
  1180. for (i = 0; i < FAVNUM; i++) {
  1181. if (d->sp[i] == pte->device) { /* It's us ? */
  1182. if (d->softkeyicon[i] != status) { /* Avoid resending the same icon */
  1183. d->softkeyicon[i] = status;
  1184. if (d->session) {
  1185. send_favorite(i, status + 1, d->session, d->softkeylabel[i]);
  1186. }
  1187. }
  1188. }
  1189. }
  1190. d = d->next;
  1191. }
  1192. }
  1193. static int register_extension(const struct unistimsession *pte)
  1194. {
  1195. struct unistim_line *line;
  1196. line = AST_LIST_FIRST(&pte->device->lines);
  1197. if (unistimdebug) {
  1198. ast_verb(0, "Trying to register extension '%s' into context '%s' to %s\n",
  1199. pte->device->extension_number, pte->device->context,
  1200. line->fullname);
  1201. }
  1202. return ast_add_extension(pte->device->context, 0,
  1203. pte->device->extension_number, 1, NULL, NULL, "Dial",
  1204. line->fullname, 0, "Unistim");
  1205. }
  1206. static int unregister_extension(const struct unistimsession *pte)
  1207. {
  1208. if (unistimdebug) {
  1209. ast_verb(0, "Trying to unregister extension '%s' context '%s'\n",
  1210. pte->device->extension_number, pte->device->context);
  1211. }
  1212. return ast_context_remove_extension(pte->device->context,
  1213. pte->device->extension_number, 1, "Unistim");
  1214. }
  1215. /* Free memory allocated for a phone */
  1216. static void close_client(struct unistimsession *s)
  1217. {
  1218. struct unistim_subchannel *sub = NULL;
  1219. struct unistimsession *cur, *prev = NULL;
  1220. ast_mutex_lock(&sessionlock);
  1221. cur = sessions;
  1222. /* Looking for the session in the linked chain */
  1223. while (cur) {
  1224. if (cur == s) {
  1225. break;
  1226. }
  1227. prev = cur;
  1228. cur = cur->next;
  1229. }
  1230. if (cur) { /* Session found ? */
  1231. if (cur->device) { /* This session was registered ? */
  1232. s->state = STATE_CLEANING;
  1233. if (unistimdebug) {
  1234. ast_verb(0, "close_client session %p device %p\n", s, s->device);
  1235. }
  1236. change_favorite_icon(s, FAV_ICON_NONE);
  1237. ast_mutex_lock(&s->device->lock);
  1238. AST_LIST_LOCK(&s->device->subs);
  1239. AST_LIST_TRAVERSE_SAFE_BEGIN(&s->device->subs, sub, list) {
  1240. if (!sub) {
  1241. continue;
  1242. }
  1243. if (sub->owner) { /* Call in progress ? */
  1244. if (unistimdebug) {
  1245. ast_verb(0, "Aborting call\n");
  1246. }
  1247. ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NETWORK_OUT_OF_ORDER);
  1248. } else {
  1249. if (unistimdebug) {
  1250. ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, s->device->name);
  1251. }
  1252. AST_LIST_REMOVE_CURRENT(list);
  1253. unistim_free_sub(sub);
  1254. }
  1255. }
  1256. AST_LIST_TRAVERSE_SAFE_END;
  1257. AST_LIST_UNLOCK(&s->device->subs);
  1258. if (!ast_strlen_zero(s->device->extension_number)) {
  1259. unregister_extension(s);
  1260. }
  1261. cur->device->session = NULL;
  1262. ast_mutex_unlock(&s->device->lock);
  1263. } else {
  1264. if (unistimdebug) {
  1265. ast_verb(0, "Freeing an unregistered client\n");
  1266. }
  1267. }
  1268. if (prev) {
  1269. prev->next = cur->next;
  1270. } else {
  1271. sessions = cur->next;
  1272. }
  1273. ast_mutex_destroy(&s->lock);
  1274. ast_free(s);
  1275. } else {
  1276. ast_log(LOG_WARNING, "Trying to delete non-existent session %p?\n", s);
  1277. }
  1278. ast_mutex_unlock(&sessionlock);
  1279. return;
  1280. }
  1281. /* Return 1 if the session chained link was modified */
  1282. static int send_retransmit(struct unistimsession *pte)
  1283. {
  1284. int i;
  1285. ast_mutex_lock(&pte->lock);
  1286. if (++pte->nb_retransmit >= NB_MAX_RETRANSMIT) {
  1287. if (unistimdebug) {
  1288. ast_verb(0, "Too many retransmit - freeing client\n");
  1289. }
  1290. ast_mutex_unlock(&pte->lock);
  1291. close_client(pte);
  1292. return 1;
  1293. }
  1294. pte->timeout = get_tick_count() + RETRANSMIT_TIMER;
  1295. for (i = pte->last_buf_available - (pte->seq_server - pte->last_seq_ack);
  1296. i < pte->last_buf_available; i++) {
  1297. if (i < 0) {
  1298. ast_log(LOG_WARNING,
  1299. "Asked to retransmit an ACKed slot ! last_buf_available=%d, seq_server = #0x%04x last_seq_ack = #0x%04x\n",
  1300. pte->last_buf_available, (unsigned)pte->seq_server, (unsigned)pte->last_seq_ack);
  1301. continue;
  1302. }
  1303. if (unistimdebug) {
  1304. unsigned short *sbuf = (unsigned short *) pte->wsabufsend[i].buf;
  1305. unsigned short seq;
  1306. seq = ntohs(sbuf[1]);
  1307. ast_verb(0, "Retransmit slot #%d (seq=#0x%04x), last ack was #0x%04x\n", i,
  1308. (unsigned)seq, (unsigned)pte->last_seq_ack);
  1309. }
  1310. send_raw_client(pte->wsabufsend[i].len, pte->wsabufsend[i].buf, &pte->sin,
  1311. &pte->sout);
  1312. }
  1313. ast_mutex_unlock(&pte->lock);
  1314. return 0;
  1315. }
  1316. /* inverse : TEXT_INVERSE : yes, TEXT_NORMAL : no */
  1317. static void
  1318. send_text(unsigned char pos, unsigned char inverse, struct unistimsession *pte,
  1319. const char *text)
  1320. {
  1321. int i;
  1322. BUFFSEND;
  1323. if (!text) {
  1324. ast_log(LOG_ERROR, "Asked to display NULL text (pos %d, inverse flag %d)\n", pos, inverse);
  1325. return;
  1326. }
  1327. if (pte->device && pte->device->height == 1 && pos != TEXT_LINE0) {
  1328. return;
  1329. }
  1330. if (unistimdebug) {
  1331. ast_verb(0, "Sending text at pos %d, inverse flag %d\n", pos, inverse);
  1332. }
  1333. memcpy(buffsend + SIZE_HEADER, packet_send_text, sizeof(packet_send_text));
  1334. buffsend[10] = pos;
  1335. buffsend[11] = inverse;
  1336. i = strlen(text);
  1337. if (i > TEXT_LENGTH_MAX) {
  1338. i = TEXT_LENGTH_MAX;
  1339. }
  1340. memcpy(buffsend + 12, text, i);
  1341. send_client(SIZE_HEADER + sizeof(packet_send_text), buffsend, pte);
  1342. }
  1343. static void send_text_status(struct unistimsession *pte, const char *text)
  1344. {
  1345. BUFFSEND;
  1346. int i;
  1347. if (unistimdebug) {
  1348. ast_verb(0, "Sending status text\n");
  1349. }
  1350. if (pte->device) {
  1351. if (pte->device->status_method == 1) { /* For new firmware and i2050 soft phone */
  1352. int n = strlen(text);
  1353. /* Must send individual button separately */
  1354. int j;
  1355. for (i = 0, j = 0; i < 4; i++, j += 7) {
  1356. int pos = 0x08 + (i * 0x20);
  1357. memcpy(buffsend + SIZE_HEADER, packet_send_status2,
  1358. sizeof(packet_send_status2));
  1359. buffsend[9] = pos;
  1360. memcpy(buffsend + 10, (j < n) ? (text + j) : " ", 7);
  1361. send_client(SIZE_HEADER + sizeof(packet_send_status2), buffsend, pte);
  1362. }
  1363. return;
  1364. }
  1365. }
  1366. memcpy(buffsend + SIZE_HEADER, packet_send_status, sizeof(packet_send_status));
  1367. i = strlen(text);
  1368. if (i > STATUS_LENGTH_MAX) {
  1369. i = STATUS_LENGTH_MAX;
  1370. }
  1371. memcpy(buffsend + 10, text, i);
  1372. send_client(SIZE_HEADER + sizeof(packet_send_status), buffsend, pte);
  1373. }
  1374. /* led values in hexa : 0 = bar off, 1 = bar on, 2 = bar 1s on/1s off, 3 = bar 2.5s on/0.5s off
  1375. * 4 = bar 0.6s on/0.3s off, 5 = bar 0.5s on/0.5s off, 6 = bar 2s on/0.5s off
  1376. * 7 = bar off, 8 = speaker off, 9 = speaker on, 10 = headphone off, 11 = headphone on
  1377. * 18 = mute off, 19 mute on */
  1378. static void send_led_update(struct unistimsession *pte, unsigned char led)
  1379. {
  1380. BUFFSEND;
  1381. if (unistimdebug) {
  1382. ast_verb(0, "Sending led_update (%x)\n", (unsigned)led);
  1383. }
  1384. memcpy(buffsend + SIZE_HEADER, packet_send_led_update, sizeof(packet_send_led_update));
  1385. buffsend[9] = led;
  1386. send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
  1387. }
  1388. /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
  1389. * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
  1390. * mute = MUTE_OFF, MUTE_ON */
  1391. static void
  1392. send_select_output(struct unistimsession *pte, unsigned char output, unsigned char volume,
  1393. unsigned char mute)
  1394. {
  1395. BUFFSEND;
  1396. if (unistimdebug) {
  1397. ast_verb(0, "Sending select output packet output=%x volume=%x mute=%x\n",
  1398. (unsigned)output, (unsigned)volume, (unsigned)mute);
  1399. }
  1400. memcpy(buffsend + SIZE_HEADER, packet_send_select_output,
  1401. sizeof(packet_send_select_output));
  1402. buffsend[9] = output;
  1403. if (output == OUTPUT_SPEAKER) {
  1404. volume = VOLUME_LOW_SPEAKER;
  1405. } else {
  1406. volume = VOLUME_LOW;
  1407. }
  1408. buffsend[10] = volume;
  1409. if (mute == MUTE_ON_DISCRET) {
  1410. buffsend[11] = MUTE_ON;
  1411. } else {
  1412. buffsend[11] = mute;
  1413. }
  1414. send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
  1415. if (mute == MUTE_OFF) {
  1416. send_led_update(pte, 0x18);
  1417. } else if (mute == MUTE_ON) {
  1418. send_led_update(pte, 0x19);
  1419. }
  1420. pte->device->mute = mute;
  1421. if (output == OUTPUT_HANDSET) {
  1422. if (mute == MUTE_ON) {
  1423. change_favorite_icon(pte, FAV_ICON_ONHOLD_BLACK);
  1424. } else {
  1425. change_favorite_icon(pte, FAV_ICON_OFFHOOK_BLACK);
  1426. }
  1427. send_led_update(pte, 0x08);
  1428. send_led_update(pte, 0x10);
  1429. } else if (output == OUTPUT_HEADPHONE) {
  1430. if (mute == MUTE_ON) {
  1431. change_favorite_icon(pte, FAV_ICON_HEADPHONES_ONHOLD);
  1432. } else {
  1433. change_favorite_icon(pte, FAV_ICON_HEADPHONES);
  1434. }
  1435. send_led_update(pte, 0x08);
  1436. send_led_update(pte, 0x11);
  1437. } else if (output == OUTPUT_SPEAKER) {
  1438. send_led_update(pte, 0x10);
  1439. send_led_update(pte, 0x09);
  1440. if (pte->device->receiver_state == STATE_OFFHOOK) {
  1441. if (mute == MUTE_ON) {
  1442. change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
  1443. } else {
  1444. change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOOK_BLACK);
  1445. }
  1446. } else {
  1447. if (mute == MUTE_ON) {
  1448. change_favorite_icon(pte, FAV_ICON_SPEAKER_ONHOLD_BLACK);
  1449. } else {
  1450. change_favorite_icon(pte, FAV_ICON_SPEAKER_OFFHOOK_BLACK);
  1451. }
  1452. }
  1453. } else {
  1454. ast_log(LOG_WARNING, "Invalid output (%d)\n", output);
  1455. }
  1456. if (output != pte->device->output) {
  1457. pte->device->previous_output = pte->device->output;
  1458. }
  1459. pte->device->output = output;
  1460. }
  1461. static void send_ring(struct unistimsession *pte, char volume, char style)
  1462. {
  1463. BUFFSEND;
  1464. if (unistimdebug) {
  1465. ast_verb(0, "Sending ring packet\n");
  1466. }
  1467. memcpy(buffsend + SIZE_HEADER, packet_send_ring, sizeof(packet_send_ring));
  1468. buffsend[24] = style + 0x10;
  1469. buffsend[29] = volume * 0x10;
  1470. send_client(SIZE_HEADER + sizeof(packet_send_ring), buffsend, pte);
  1471. }
  1472. static void send_no_ring(struct unistimsession *pte)
  1473. {
  1474. BUFFSEND;
  1475. if (unistimdebug) {
  1476. ast_verb(0, "Sending no ring packet\n");
  1477. }
  1478. memcpy(buffsend + SIZE_HEADER, packet_send_no_ring, sizeof(packet_send_no_ring));
  1479. send_client(SIZE_HEADER + sizeof(packet_send_no_ring), buffsend, pte);
  1480. }
  1481. static void send_texttitle(struct unistimsession *pte, const char *text)
  1482. {
  1483. BUFFSEND;
  1484. int i;
  1485. if (unistimdebug) {
  1486. ast_verb(0, "Sending title text\n");
  1487. }
  1488. memcpy(buffsend + SIZE_HEADER, packet_send_title, sizeof(packet_send_title));
  1489. i = strlen(text);
  1490. if (i > 12) {
  1491. i = 12;
  1492. }
  1493. memcpy(buffsend + 10, text, i);
  1494. send_client(SIZE_HEADER + sizeof(packet_send_title), buffsend, pte);
  1495. }
  1496. static void send_idle_clock(struct unistimsession *pte)
  1497. {
  1498. send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
  1499. }
  1500. static void send_date_time(struct unistimsession *pte)
  1501. {
  1502. BUFFSEND;
  1503. struct timeval now = ast_tvnow();
  1504. struct ast_tm atm = { 0, };
  1505. if (unistimdebug) {
  1506. ast_verb(0, "Sending Time & Date\n");
  1507. }
  1508. memcpy(buffsend + SIZE_HEADER, packet_send_date_time, sizeof(packet_send_date_time));
  1509. ast_localtime(&now, &atm, NULL);
  1510. buffsend[10] = (unsigned char) atm.tm_mon + 1;
  1511. buffsend[11] = (unsigned char) atm.tm_mday;
  1512. buffsend[12] = (unsigned char) atm.tm_hour;
  1513. buffsend[13] = (unsigned char) atm.tm_min;
  1514. send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
  1515. }
  1516. static void send_date_time2(struct unistimsession *pte)
  1517. {
  1518. BUFFSEND;
  1519. struct timeval now = ast_tvnow();
  1520. struct ast_tm atm = { 0, };
  1521. if (unistimdebug) {
  1522. ast_verb(0, "Sending Time & Date #2\n");
  1523. }
  1524. memcpy(buffsend + SIZE_HEADER, packet_send_date_time2, sizeof(packet_send_date_time2));
  1525. ast_localtime(&now, &atm, NULL);
  1526. if (pte->device) {
  1527. buffsend[9] = pte->device->datetimeformat;
  1528. } else {
  1529. buffsend[9] = 61;
  1530. }
  1531. buffsend[14] = (unsigned char) atm.tm_mon + 1;
  1532. buffsend[15] = (unsigned char) atm.tm_mday;
  1533. buffsend[16] = (unsigned char) atm.tm_hour;
  1534. buffsend[17] = (unsigned char) atm.tm_min;
  1535. send_client(SIZE_HEADER + sizeof(packet_send_date_time2), buffsend, pte);
  1536. }
  1537. static void send_date_time3(struct unistimsession *pte)
  1538. {
  1539. BUFFSEND;
  1540. struct timeval now = ast_tvnow();
  1541. struct ast_tm atm = { 0, };
  1542. if (unistimdebug) {
  1543. ast_verb(0, "Sending Time & Date #3\n");
  1544. }
  1545. memcpy(buffsend + SIZE_HEADER, packet_send_date_time3, sizeof(packet_send_date_time3));
  1546. ast_localtime(&now, &atm, NULL);
  1547. buffsend[10] = (unsigned char) atm.tm_mon + 1;
  1548. buffsend[11] = (unsigned char) atm.tm_mday;
  1549. buffsend[12] = (unsigned char) atm.tm_hour;
  1550. buffsend[13] = (unsigned char) atm.tm_min;
  1551. send_client(SIZE_HEADER + sizeof(packet_send_date_time3), buffsend, pte);
  1552. }
  1553. static void send_blink_cursor(struct unistimsession *pte)
  1554. {
  1555. BUFFSEND;
  1556. if (unistimdebug) {
  1557. ast_verb(0, "Sending set blink\n");
  1558. }
  1559. memcpy(buffsend + SIZE_HEADER, packet_send_blink_cursor, sizeof(packet_send_blink_cursor));
  1560. send_client(SIZE_HEADER + sizeof(packet_send_blink_cursor), buffsend, pte);
  1561. return;
  1562. }
  1563. /* pos : 0xab (a=0/2/4 = line ; b = row) */
  1564. static void send_cursor_pos(struct unistimsession *pte, unsigned char pos)
  1565. {
  1566. BUFFSEND;
  1567. if (unistimdebug) {
  1568. ast_verb(0, "Sending set cursor position\n");
  1569. }
  1570. memcpy(buffsend + SIZE_HEADER, packet_send_set_pos_cursor,
  1571. sizeof(packet_send_set_pos_cursor));
  1572. buffsend[11] = pos;
  1573. send_client(SIZE_HEADER + sizeof(packet_send_set_pos_cursor), buffsend, pte);
  1574. return;
  1575. }
  1576. static void send_charset_update(struct unistimsession *pte, int charset)
  1577. {
  1578. const unsigned char* packet_send_charset;
  1579. int packet_size;
  1580. BUFFSEND;
  1581. if (unistimdebug) {
  1582. ast_verb(0, "Sending set default charset\n");
  1583. }
  1584. if (charset == LANG_DEFAULT) {
  1585. charset = options_languages[find_language(pte->device->language)].encoding;
  1586. }
  1587. switch (charset) {
  1588. case ISO_8859_2:
  1589. packet_send_charset = packet_send_charset_iso_8859_2;
  1590. packet_size = sizeof(packet_send_charset_iso_8859_2);
  1591. break;
  1592. case ISO_8859_4:
  1593. packet_send_charset = packet_send_charset_iso_8859_4;
  1594. packet_size = sizeof(packet_send_charset_iso_8859_4);
  1595. break;
  1596. case ISO_8859_5:
  1597. packet_send_charset = packet_send_charset_iso_8859_5;
  1598. packet_size = sizeof(packet_send_charset_iso_8859_5);
  1599. break;
  1600. case ISO_2022_JP:
  1601. packet_send_charset = packet_send_charset_iso_2022_jp;
  1602. packet_size = sizeof(packet_send_charset_iso_2022_jp);
  1603. break;
  1604. case ISO_8859_1:
  1605. default:
  1606. packet_send_charset = packet_send_charset_iso_8859_1;
  1607. packet_size = sizeof(packet_send_charset_iso_8859_1);
  1608. }
  1609. memcpy(buffsend + SIZE_HEADER, packet_send_charset, packet_size);
  1610. send_client(SIZE_HEADER + packet_size, buffsend, pte);
  1611. return;
  1612. }
  1613. static void rcv_resume_connection_with_server(struct unistimsession *pte)
  1614. {
  1615. BUFFSEND;
  1616. if (unistimdebug) {
  1617. ast_verb(0, "ResumeConnectionWithServer received\n");
  1618. ast_verb(0, "Sending packet_send_query_mac_address\n");
  1619. }
  1620. memcpy(buffsend + SIZE_HEADER, packet_send_query_mac_address,
  1621. sizeof(packet_send_query_mac_address));
  1622. send_client(SIZE_HEADER + sizeof(packet_send_query_mac_address), buffsend, pte);
  1623. return;
  1624. }
  1625. static int unistim_register(struct unistimsession *s)
  1626. {
  1627. struct unistim_device *d;
  1628. ast_mutex_lock(&devicelock);
  1629. d = devices;
  1630. while (d) {
  1631. if (!strcasecmp(s->macaddr, d->id)) {
  1632. /* XXX Deal with IP authentication */
  1633. s->device = d;
  1634. d->session = s;
  1635. d->codec_number = DEFAULT_CODEC;
  1636. d->missed_call = 0;
  1637. d->receiver_state = STATE_ONHOOK;
  1638. break;
  1639. }
  1640. d = d->next;
  1641. }
  1642. ast_mutex_unlock(&devicelock);
  1643. if (!d) {
  1644. return 0;
  1645. }
  1646. return 1;
  1647. }
  1648. static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
  1649. {
  1650. struct ast_format_cap *tmp = src->cap;
  1651. memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
  1652. src->cap = tmp;
  1653. ast_format_cap_copy(src->cap, dst->cap);
  1654. }
  1655. static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
  1656. {
  1657. if (!l) {
  1658. return NULL;
  1659. }
  1660. l->cap = ast_format_cap_destroy(l->cap);
  1661. ast_free(l);
  1662. return NULL;
  1663. }
  1664. static struct unistim_line *unistim_line_alloc(void)
  1665. {
  1666. struct unistim_line *l;
  1667. if (!(l = ast_calloc(1, sizeof(*l)))) {
  1668. return NULL;
  1669. }
  1670. if (!(l->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK))) {
  1671. ast_free(l);
  1672. return NULL;
  1673. }
  1674. return l;
  1675. }
  1676. static int unistim_free_sub(struct unistim_subchannel *sub) {
  1677. if (unistimdebug) {
  1678. ast_debug(1, "Released sub %u of channel %s@%s\n", sub->subtype, sub->parent->name, sub->parent->parent->name);
  1679. }
  1680. ast_mutex_destroy(&sub->lock);
  1681. ast_free(sub);
  1682. return 0;
  1683. }
  1684. static struct unistim_subchannel *unistim_alloc_sub(struct unistim_device *d, int x)
  1685. {
  1686. struct unistim_subchannel *sub;
  1687. if (!(sub = ast_calloc(1, sizeof(*sub)))) {
  1688. return NULL;
  1689. }
  1690. if (unistimdebug) {
  1691. ast_verb(3, "Allocating UNISTIM subchannel #%d on %s ptr=%p\n", x, d->name, sub);
  1692. }
  1693. sub->ss_thread = AST_PTHREADT_NULL;
  1694. sub->subtype = x;
  1695. AST_LIST_LOCK(&d->subs);
  1696. AST_LIST_INSERT_TAIL(&d->subs, sub, list);
  1697. AST_LIST_UNLOCK(&d->subs);
  1698. ast_mutex_init(&sub->lock);
  1699. return sub;
  1700. }
  1701. static int unistim_unalloc_sub(struct unistim_device *d, struct unistim_subchannel *sub)
  1702. {
  1703. struct unistim_subchannel *s;
  1704. AST_LIST_LOCK(&d->subs);
  1705. AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, s, list) {
  1706. if (!s) {
  1707. continue;
  1708. }
  1709. if (s != sub) {
  1710. continue;
  1711. }
  1712. AST_LIST_REMOVE_CURRENT(list);
  1713. unistim_free_sub(sub);
  1714. }
  1715. AST_LIST_TRAVERSE_SAFE_END;
  1716. AST_LIST_UNLOCK(&d->subs);
  1717. return 0;
  1718. }
  1719. static const char *subtype_tostr(const int type)
  1720. {
  1721. switch (type) {
  1722. case SUB_REAL:
  1723. return "REAL";
  1724. case SUB_ONHOLD:
  1725. return "ONHOLD";
  1726. case SUB_RING:
  1727. return "RINGING";
  1728. case SUB_THREEWAY:
  1729. return "THREEWAY";
  1730. }
  1731. return "UNKNOWN";
  1732. }
  1733. static const char *ptestate_tostr(const int type)
  1734. {
  1735. switch (type) {
  1736. case STATE_INIT:
  1737. return "INIT";
  1738. case STATE_AUTHDENY:
  1739. return "AUTHDENY";
  1740. case STATE_MAINPAGE:
  1741. return "MAINPAGE";
  1742. case STATE_EXTENSION:
  1743. return "EXTENSION";
  1744. case STATE_DIALPAGE:
  1745. return "DIALPAGE";
  1746. case STATE_RINGING:
  1747. return "RINGING";
  1748. case STATE_CALL:
  1749. return "CALL";
  1750. case STATE_SELECTOPTION:
  1751. return "SELECTOPTION";
  1752. case STATE_SELECTCODEC:
  1753. return "SELECTCODEC";
  1754. case STATE_SELECTLANGUAGE:
  1755. return "SELECTLANGUAGE";
  1756. case STATE_CLEANING:
  1757. return "CLEARING";
  1758. case STATE_HISTORY:
  1759. return "HISTORY";
  1760. }
  1761. return "UNKNOWN";
  1762. }
  1763. static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
  1764. {
  1765. BUFFSEND;
  1766. int tmp, i = 0;
  1767. char addrmac[19];
  1768. int res = 0;
  1769. for (tmp = 15; tmp < 15 + SIZE_HEADER; tmp++) {
  1770. sprintf(&addrmac[i], "%02hhx", buf[tmp]);
  1771. i += 2;
  1772. }
  1773. if (unistimdebug) {
  1774. ast_verb(0, "MAC Address received: %s\n", addrmac);
  1775. }
  1776. strcpy(pte->macaddr, addrmac);
  1777. res = unistim_register(pte);
  1778. if (!res) {
  1779. switch (autoprovisioning) {
  1780. case AUTOPROVISIONING_NO:
  1781. ast_log(LOG_WARNING, "No entry found for this phone : %s\n", addrmac);
  1782. pte->state = STATE_AUTHDENY;
  1783. break;
  1784. case AUTOPROVISIONING_YES:
  1785. {
  1786. struct unistim_device *d = NULL, *newd = NULL;
  1787. struct unistim_line *newl = NULL, *l = NULL;
  1788. if (unistimdebug) {
  1789. ast_verb(0, "New phone, autoprovisioning on\n");
  1790. }
  1791. /* First : locate the [template] section */
  1792. ast_mutex_lock(&devicelock);
  1793. d = devices;
  1794. while (d) {
  1795. if (strcasecmp(d->name, "template")) {
  1796. d = d->next;
  1797. continue;
  1798. }
  1799. /* Found, cloning this entry */
  1800. if (!(newd = ast_malloc(sizeof(*newd)))) {
  1801. ast_mutex_unlock(&devicelock);
  1802. return;
  1803. }
  1804. memcpy(newd, d, sizeof(*newd));
  1805. ast_mutex_init(&newd->lock);
  1806. newd->lines.first = NULL;
  1807. newd->lines.last = NULL;
  1808. AST_LIST_LOCK(&d->lines);
  1809. AST_LIST_TRAVERSE(&d->lines, l, list) {
  1810. if (!(newl = unistim_line_alloc())) {
  1811. break;
  1812. }
  1813. unistim_line_copy(l, newl);
  1814. newl->parent = newd;
  1815. ast_copy_string(newl->name, l->name, sizeof(newl->name));
  1816. snprintf(newl->fullname, sizeof(newl->fullname), "USTM/%s@%s",
  1817. newl->name, newd->name);
  1818. snprintf(l->name, sizeof(l->name), "%d", atoi(l->name) + 1);
  1819. AST_LIST_LOCK(&newd->lines);
  1820. AST_LIST_INSERT_TAIL(&newd->lines, newl, list);
  1821. AST_LIST_UNLOCK(&newd->lines);
  1822. }
  1823. AST_LIST_UNLOCK(&d->lines);
  1824. if (!newl) {
  1825. ast_free(newd);
  1826. ast_mutex_unlock(&devicelock);
  1827. }
  1828. /* Ok, now updating some fields */
  1829. ast_copy_string(newd->id, addrmac, sizeof(newd->id));
  1830. ast_copy_string(newd->name, addrmac, sizeof(newd->name));
  1831. if (newd->extension == EXTENSION_NONE) {
  1832. newd->extension = EXTENSION_ASK;
  1833. }
  1834. newd->receiver_state = STATE_ONHOOK;
  1835. newd->session = pte;
  1836. newd->language[0] = '\0';
  1837. newd->to_delete = -1;
  1838. newd->next = NULL;
  1839. pte->device = newd;
  1840. /* Go to the end of the linked chain */
  1841. while (d->next) {
  1842. d = d->next;
  1843. }
  1844. d->next = newd;
  1845. d = newd;
  1846. break;
  1847. }
  1848. ast_mutex_unlock(&devicelock);
  1849. if (!d) {
  1850. ast_log(LOG_WARNING, "No entry [template] found in unistim.conf\n");
  1851. pte->state = STATE_AUTHDENY;
  1852. }
  1853. }
  1854. break;
  1855. case AUTOPROVISIONING_TN:
  1856. pte->state = STATE_AUTHDENY;
  1857. break;
  1858. default:
  1859. ast_log(LOG_WARNING, "Internal error : unknown autoprovisioning value = %u\n",
  1860. autoprovisioning);
  1861. }
  1862. }
  1863. if (pte->state != STATE_AUTHDENY) {
  1864. struct unistim_line *line;
  1865. struct unistim_subchannel *sub;
  1866. ast_verb(3, "Device '%s' successfuly registered\n", pte->device->name);
  1867. AST_LIST_LOCK(&pte->device->subs);
  1868. AST_LIST_TRAVERSE_SAFE_BEGIN(&pte->device->subs, sub, list) {
  1869. if (sub) {
  1870. ast_log(LOG_ERROR, "Subchannel lost sice reboot. Hanged channel may apear!\n");
  1871. AST_LIST_REMOVE_CURRENT(list);
  1872. ast_free(sub);
  1873. }
  1874. }
  1875. AST_LIST_TRAVERSE_SAFE_END;
  1876. AST_LIST_UNLOCK(&pte->device->subs);
  1877. switch (pte->device->extension) {
  1878. case EXTENSION_NONE:
  1879. pte->state = STATE_MAINPAGE;
  1880. break;
  1881. case EXTENSION_ASK:
  1882. /* Checking if we already have an extension number */
  1883. if (ast_strlen_zero(pte->device->extension_number)) {
  1884. pte->state = STATE_EXTENSION;
  1885. } else {
  1886. /* Yes, because of a phone reboot. We don't ask again for the TN */
  1887. if (register_extension(pte)) {
  1888. pte->state = STATE_EXTENSION;
  1889. } else {
  1890. pte->state = STATE_MAINPAGE;
  1891. }
  1892. }
  1893. break;
  1894. case EXTENSION_LINE:
  1895. line = AST_LIST_FIRST(&pte->device->lines);
  1896. ast_copy_string(pte->device->extension_number, line->name,
  1897. sizeof(pte->device->extension_number));
  1898. if (register_extension(pte)) {
  1899. pte->state = STATE_EXTENSION;
  1900. } else {
  1901. pte->state = STATE_MAINPAGE;
  1902. }
  1903. break;
  1904. case EXTENSION_TN:
  1905. /* If we are here, it's because of a phone reboot */
  1906. pte->state = STATE_MAINPAGE;
  1907. break;
  1908. default:
  1909. ast_log(LOG_WARNING, "Internal error, extension value unknown : %u\n",
  1910. pte->device->extension);
  1911. pte->state = STATE_AUTHDENY;
  1912. break;
  1913. }
  1914. }
  1915. if (pte->state == STATE_EXTENSION) {
  1916. if (pte->device->extension != EXTENSION_TN) {
  1917. pte->device->extension = EXTENSION_ASK;
  1918. }
  1919. pte->device->extension_number[0] = '\0';
  1920. }
  1921. if (unistimdebug) {
  1922. ast_verb(0, "\nSending S1\n");
  1923. }
  1924. memcpy(buffsend + SIZE_HEADER, packet_send_S1, sizeof(packet_send_S1));
  1925. send_client(SIZE_HEADER + sizeof(packet_send_S1), buffsend, pte);
  1926. if (unistimdebug) {
  1927. ast_verb(0, "Sending query_basic_manager_04\n");
  1928. }
  1929. memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_04,
  1930. sizeof(packet_send_query_basic_manager_04));
  1931. send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_04), buffsend, pte);
  1932. if (unistimdebug) {
  1933. ast_verb(0, "Sending query_basic_manager_10\n");
  1934. }
  1935. memcpy(buffsend + SIZE_HEADER, packet_send_query_basic_manager_10,
  1936. sizeof(packet_send_query_basic_manager_10));
  1937. send_client(SIZE_HEADER + sizeof(packet_send_query_basic_manager_10), buffsend, pte);
  1938. send_date_time(pte);
  1939. return;
  1940. }
  1941. static int write_entry_history(struct unistimsession *pte, FILE * f, char c, char *line1)
  1942. {
  1943. if (fwrite(&c, 1, 1, f) != 1) {
  1944. display_last_error("Unable to write history log header.");
  1945. return -1;
  1946. }
  1947. if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
  1948. display_last_error("Unable to write history entry - date.");
  1949. return -1;
  1950. }
  1951. if (fwrite(pte->device->lst_cid, TEXT_LENGTH_MAX, 1, f) != 1) {
  1952. display_last_error("Unable to write history entry - callerid.");
  1953. return -1;
  1954. }
  1955. if (fwrite(pte->device->lst_cnm, TEXT_LENGTH_MAX, 1, f) != 1) {
  1956. display_last_error("Unable to write history entry - callername.");
  1957. return -1;
  1958. }
  1959. return 0;
  1960. }
  1961. static int write_history(struct unistimsession *pte, char way, char ismissed)
  1962. {
  1963. char tmp[AST_CONFIG_MAX_PATH], tmp2[AST_CONFIG_MAX_PATH];
  1964. char line1[TEXT_LENGTH_MAX + 1];
  1965. char count = 0, *histbuf;
  1966. int size;
  1967. FILE *f, *f2;
  1968. struct timeval now = ast_tvnow();
  1969. struct ast_tm atm = { 0, };
  1970. if (!pte->device) {
  1971. return -1;
  1972. }
  1973. if (!pte->device->callhistory) {
  1974. return 0;
  1975. }
  1976. if (strchr(pte->device->name, '/') || (pte->device->name[0] == '.')) {
  1977. ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n",
  1978. pte->device->name);
  1979. return -1;
  1980. }
  1981. snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, USTM_LOG_DIR);
  1982. if (ast_mkdir(tmp, 0770)) {
  1983. ast_log(LOG_WARNING, "Unable to create directory for history\n");
  1984. return -1;
  1985. }
  1986. ast_localtime(&now, &atm, NULL);
  1987. if (ismissed) {
  1988. if (way == 'i') {
  1989. ast_copy_string(tmp2, ustmtext("Miss", pte), sizeof(tmp2));
  1990. } else {
  1991. ast_copy_string(tmp2, ustmtext("Fail", pte), sizeof(tmp2));
  1992. }
  1993. } else {
  1994. ast_copy_string(tmp2, ustmtext("Answ", pte), sizeof(tmp2));
  1995. }
  1996. snprintf(line1, sizeof(line1), "%04d/%02d/%02d %02d:%02d:%02d %s",
  1997. atm.tm_year + 1900, atm.tm_mon + 1, atm.tm_mday, atm.tm_hour,
  1998. atm.tm_min, atm.tm_sec, tmp2);
  1999. snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
  2000. USTM_LOG_DIR, pte->device->name, way);
  2001. if ((f = fopen(tmp, "r"))) {
  2002. struct stat bufstat;
  2003. if (stat(tmp, &bufstat)) {
  2004. display_last_error("Unable to stat history log.");
  2005. fclose(f);
  2006. return -1;
  2007. }
  2008. size = 1 + (MAX_ENTRY_LOG * TEXT_LENGTH_MAX * 3);
  2009. if (bufstat.st_size != size) {
  2010. ast_log(LOG_WARNING,
  2011. "History file %s has an incorrect size (%d instead of %d). It will be replaced by a new one.",
  2012. tmp, (int) bufstat.st_size, size);
  2013. fclose(f);
  2014. f = NULL;
  2015. count = 1;
  2016. }
  2017. }
  2018. /* If we can't open the log file, we create a brand new one */
  2019. if (!f) {
  2020. char c = 1;
  2021. int i;
  2022. if ((errno != ENOENT) && (count == 0)) {
  2023. display_last_error("Unable to open history log.");
  2024. return -1;
  2025. }
  2026. f = fopen(tmp, "w");
  2027. if (!f) {
  2028. display_last_error("Unable to create history log.");
  2029. return -1;
  2030. }
  2031. if (write_entry_history(pte, f, c, line1)) {
  2032. fclose(f);
  2033. return -1;
  2034. }
  2035. memset(line1, ' ', TEXT_LENGTH_MAX);
  2036. for (i = 3; i < MAX_ENTRY_LOG * 3; i++) {
  2037. if (fwrite(line1, TEXT_LENGTH_MAX, 1, f) != 1) {
  2038. display_last_error("Unable to write history entry - stuffing.");
  2039. fclose(f);
  2040. return -1;
  2041. }
  2042. }
  2043. if (fclose(f)) {
  2044. display_last_error("Unable to close history - creation.");
  2045. }
  2046. return 0;
  2047. }
  2048. /* We can open the log file, we create a temporary one, we add our entry and copy the rest */
  2049. if (fread(&count, 1, 1, f) != 1) {
  2050. display_last_error("Unable to read history header.");
  2051. fclose(f);
  2052. return -1;
  2053. }
  2054. if (count > MAX_ENTRY_LOG) {
  2055. ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
  2056. count, MAX_ENTRY_LOG);
  2057. fclose(f);
  2058. return -1;
  2059. }
  2060. snprintf(tmp2, sizeof(tmp2), "%s/%s/%s-%c.csv.tmp", ast_config_AST_LOG_DIR,
  2061. USTM_LOG_DIR, pte->device->name, way);
  2062. if (!(f2 = fopen(tmp2, "w"))) {
  2063. display_last_error("Unable to create temporary history log.");
  2064. fclose(f);
  2065. return -1;
  2066. }
  2067. if (++count > MAX_ENTRY_LOG) {
  2068. count = MAX_ENTRY_LOG;
  2069. }
  2070. if (write_entry_history(pte, f2, count, line1)) {
  2071. fclose(f);
  2072. fclose(f2);
  2073. return -1;
  2074. }
  2075. size = (MAX_ENTRY_LOG - 1) * TEXT_LENGTH_MAX * 3;
  2076. if (!(histbuf = ast_malloc(size))) {
  2077. fclose(f);
  2078. fclose(f2);
  2079. return -1;
  2080. }
  2081. if (fread(histbuf, size, 1, f) != 1) {
  2082. ast_free(histbuf);
  2083. fclose(f);
  2084. fclose(f2);
  2085. display_last_error("Unable to read previous history entries.");
  2086. return -1;
  2087. }
  2088. if (fwrite(histbuf, size, 1, f2) != 1) {
  2089. ast_free(histbuf);
  2090. fclose(f);
  2091. fclose(f2);
  2092. display_last_error("Unable to write previous history entries.");
  2093. return -1;
  2094. }
  2095. ast_free(histbuf);
  2096. if (fclose(f)) {
  2097. display_last_error("Unable to close history log.");
  2098. }
  2099. if (fclose(f2)) {
  2100. display_last_error("Unable to close temporary history log.");
  2101. }
  2102. if (unlink(tmp)) {
  2103. display_last_error("Unable to remove old history log.");
  2104. }
  2105. if (rename(tmp2, tmp)) {
  2106. display_last_error("Unable to rename new history log.");
  2107. }
  2108. return 0;
  2109. }
  2110. static int attempt_transfer(struct unistim_subchannel *p1, struct unistim_subchannel *p2)
  2111. {
  2112. RAII_VAR(struct ast_channel *, chana, NULL, ast_channel_unref);
  2113. RAII_VAR(struct ast_channel *, chanb, NULL, ast_channel_unref);
  2114. if (!p1->owner || !p2->owner) {
  2115. ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
  2116. return -1;
  2117. }
  2118. chana = ast_channel_ref(p1->owner);
  2119. chanb = ast_channel_ref(p2->owner);
  2120. switch (ast_bridge_transfer_attended(chana, chanb)) {
  2121. case AST_BRIDGE_TRANSFER_INVALID:
  2122. ast_log(LOG_WARNING, "Transfer failed. Invalid bridge setup\n");
  2123. break;
  2124. case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
  2125. ast_log(LOG_WARNING, "Transfer not permitted\n");
  2126. break;
  2127. case AST_BRIDGE_TRANSFER_FAIL:
  2128. ast_log(LOG_WARNING, "Transfer encountered internal error\n");
  2129. break;
  2130. case AST_BRIDGE_TRANSFER_SUCCESS:
  2131. return 0;
  2132. }
  2133. /* Control only reaches this point if transfer has failed */
  2134. ast_softhangup_nolock(chana, AST_SOFTHANGUP_DEV);
  2135. ast_softhangup_nolock(chanb, AST_SOFTHANGUP_DEV);
  2136. return -1;
  2137. }
  2138. void change_callerid(struct unistimsession *pte, int type, char *callerid)
  2139. {
  2140. char *data;
  2141. int size;
  2142. if (type) {
  2143. data = pte->device->lst_cnm;
  2144. } else {
  2145. data = pte->device->lst_cid;
  2146. }
  2147. /* This is very nearly strncpy(), except that the remaining buffer
  2148. * is padded with ' ', instead of '\0' */
  2149. memset(data, ' ', TEXT_LENGTH_MAX);
  2150. size = strlen(callerid);
  2151. if (size > TEXT_LENGTH_MAX) {
  2152. size = TEXT_LENGTH_MAX;
  2153. }
  2154. memcpy(data, callerid, size);
  2155. }
  2156. static struct unistim_subchannel* get_sub(struct unistim_device *device, int type)
  2157. {
  2158. struct unistim_subchannel *sub = NULL;
  2159. AST_LIST_LOCK(&device->subs);
  2160. AST_LIST_TRAVERSE(&device->subs, sub, list) {
  2161. if (!sub) {
  2162. continue;
  2163. }
  2164. if (sub->subtype == type) {
  2165. break;
  2166. }
  2167. }
  2168. AST_LIST_UNLOCK(&device->subs);
  2169. return sub;
  2170. }
  2171. static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
  2172. {
  2173. /* Silence our channel */
  2174. if (!pte->device->silence_generator) {
  2175. pte->device->silence_generator =
  2176. ast_channel_start_silence_generator(sub->owner);
  2177. if (pte->device->silence_generator == NULL) {
  2178. ast_log(LOG_WARNING, "Unable to start a silence generator.\n");
  2179. } else if (unistimdebug) {
  2180. ast_verb(0, "Starting silence generator\n");
  2181. }
  2182. }
  2183. }
  2184. static void sub_stop_silence(struct unistimsession *pte, struct unistim_subchannel *sub)
  2185. {
  2186. /* Stop the silence generator */
  2187. if (pte->device->silence_generator) {
  2188. if (unistimdebug) {
  2189. ast_verb(0, "Stopping silence generator\n");
  2190. }
  2191. if (sub->owner) {
  2192. ast_channel_stop_silence_generator(sub->owner, pte->device->silence_generator);
  2193. } else {
  2194. ast_log(LOG_WARNING, "Trying to stop silence generator on a null channel!\n");
  2195. }
  2196. pte->device->silence_generator = NULL;
  2197. }
  2198. }
  2199. static void sub_hold(struct unistimsession *pte, struct unistim_subchannel *sub)
  2200. {
  2201. if (!sub) {
  2202. return;
  2203. }
  2204. sub->moh = 1;
  2205. sub->subtype = SUB_ONHOLD;
  2206. send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte);
  2207. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
  2208. send_stop_timer(pte);
  2209. if (sub->owner) {
  2210. ast_queue_hold(sub->owner, NULL);
  2211. send_end_call(pte);
  2212. }
  2213. return;
  2214. }
  2215. static void sub_unhold(struct unistimsession *pte, struct unistim_subchannel *sub)
  2216. {
  2217. struct unistim_subchannel *sub_real;
  2218. sub_real = get_sub(pte->device, SUB_REAL);
  2219. if (sub_real) {
  2220. sub_hold(pte, sub_real);
  2221. }
  2222. sub->moh = 0;
  2223. sub->subtype = SUB_REAL;
  2224. send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte);
  2225. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
  2226. send_start_timer(pte);
  2227. if (sub->owner) {
  2228. ast_queue_unhold(sub->owner);
  2229. if (sub->rtp) {
  2230. send_start_rtp(sub);
  2231. }
  2232. }
  2233. return;
  2234. }
  2235. static void close_call(struct unistimsession *pte)
  2236. {
  2237. struct unistim_subchannel *sub, *sub_transf;
  2238. sub = get_sub(pte->device, SUB_REAL);
  2239. sub_transf = get_sub(pte->device, SUB_THREEWAY);
  2240. send_stop_timer(pte);
  2241. if (!sub) {
  2242. ast_log(LOG_WARNING, "Close call without sub\n");
  2243. return;
  2244. }
  2245. send_favorite_short(sub->softkey, FAV_LINE_ICON, pte);
  2246. if (sub->owner) {
  2247. sub->alreadygone = 1;
  2248. if (sub_transf) {
  2249. sub_transf->alreadygone = 1;
  2250. if (attempt_transfer(sub, sub_transf) < 0) {
  2251. ast_verb(0, "attempt_transfer failed.\n");
  2252. }
  2253. } else {
  2254. ast_queue_hangup(sub->owner);
  2255. }
  2256. } else {
  2257. if (sub_transf) {
  2258. if (sub_transf->owner) {
  2259. ast_queue_hangup_with_cause(sub_transf->owner, AST_CAUSE_NORMAL_CLEARING);
  2260. } else {
  2261. ast_log(LOG_WARNING, "threeway sub without owner\n");
  2262. }
  2263. } else {
  2264. ast_verb(0, "USTM(%s@%s-%d) channel already destroyed\n", sub->parent->name,
  2265. pte->device->name, sub->softkey);
  2266. }
  2267. }
  2268. change_callerid(pte, 0, pte->device->redial_number);
  2269. change_callerid(pte, 1, "");
  2270. write_history(pte, 'o', pte->device->missed_call);
  2271. pte->device->missed_call = 0;
  2272. show_main_page(pte);
  2273. return;
  2274. }
  2275. static void ignore_call(struct unistimsession *pte)
  2276. {
  2277. send_no_ring(pte);
  2278. return;
  2279. }
  2280. static void discard_call(struct unistimsession *pte)
  2281. {
  2282. struct unistim_subchannel* sub;
  2283. sub = get_sub(pte->device, SUB_RING);
  2284. if (!sub) {
  2285. return;
  2286. }
  2287. ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
  2288. return;
  2289. }
  2290. static void *unistim_ss(void *data)
  2291. {
  2292. struct ast_channel *chan = data;
  2293. struct unistim_subchannel *sub = ast_channel_tech_pvt(chan);
  2294. struct unistim_line *l = sub->parent;
  2295. struct unistimsession *s = l->parent->session;
  2296. int res;
  2297. if (!s) {
  2298. return NULL;
  2299. }
  2300. ast_verb(3, "Starting switch on '%s@%s-%d' to %s\n", l->name, l->parent->name, sub->softkey, s->device->phone_number);
  2301. ast_channel_lock(chan);
  2302. ast_channel_exten_set(chan, s->device->phone_number);
  2303. ast_setstate(chan, AST_STATE_RING);
  2304. ast_channel_unlock(chan);
  2305. ast_copy_string(s->device->redial_number, s->device->phone_number,
  2306. sizeof(s->device->redial_number));
  2307. res = ast_pbx_run(chan);
  2308. if (res) {
  2309. ast_log(LOG_WARNING, "PBX exited non-zero\n");
  2310. send_tone(s, 1000, 0);
  2311. }
  2312. return NULL;
  2313. }
  2314. static int find_rtp_port(struct unistim_subchannel *s)
  2315. {
  2316. struct unistim_subchannel *sub = NULL;
  2317. int rtp_start = s->parent->parent->rtp_port;
  2318. struct ast_sockaddr us_tmp;
  2319. struct sockaddr_in us = { 0, };
  2320. AST_LIST_LOCK(&s->parent->parent->subs);
  2321. AST_LIST_TRAVERSE(&s->parent->parent->subs, sub, list) {
  2322. if (!sub) {
  2323. continue;
  2324. }
  2325. if (sub->rtp) {
  2326. ast_rtp_instance_get_remote_address(sub->rtp, &us_tmp);
  2327. ast_sockaddr_to_sin(&us_tmp, &us);
  2328. if (htons(us.sin_port)) {
  2329. rtp_start = htons(us.sin_port) + 1;
  2330. break;
  2331. }
  2332. }
  2333. }
  2334. AST_LIST_UNLOCK(&s->parent->parent->subs);
  2335. return rtp_start;
  2336. }
  2337. static void send_start_rtp(struct unistim_subchannel *sub)
  2338. {
  2339. BUFFSEND;
  2340. int codec;
  2341. struct sockaddr_in public = { 0, };
  2342. struct sockaddr_in us = { 0, };
  2343. struct sockaddr_in sin = { 0, };
  2344. struct ast_sockaddr us_tmp;
  2345. struct ast_sockaddr sin_tmp;
  2346. struct unistimsession *pte;
  2347. ast_rtp_instance_get_local_address(sub->rtp, &us_tmp);
  2348. ast_sockaddr_to_sin(&us_tmp, &us);
  2349. ast_rtp_instance_get_remote_address(sub->rtp, &sin_tmp);
  2350. ast_sockaddr_to_sin(&sin_tmp, &sin);
  2351. /* Setting up RTP of the phone */
  2352. if (public_ip.sin_family == 0) { /* NAT IP override ? */
  2353. memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */
  2354. } else {
  2355. memcpy(&public, &public_ip, sizeof(public)); /* override */
  2356. }
  2357. if (unistimdebug) {
  2358. ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
  2359. ast_inet_ntoa(us.sin_addr),
  2360. htons(us.sin_port), ast_getformatname(ast_channel_readformat(sub->owner)));
  2361. ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
  2362. ast_inet_ntoa(public.sin_addr));
  2363. }
  2364. pte = sub->parent->parent->session;
  2365. codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, ast_channel_readformat(sub->owner), 0);
  2366. if ((ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) ||
  2367. (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW)) {
  2368. if (unistimdebug) {
  2369. ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
  2370. }
  2371. memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
  2372. sizeof(packet_send_rtp_packet_size));
  2373. buffsend[10] = (int) codec & 0xffffffffLL;
  2374. send_client(SIZE_HEADER + sizeof(packet_send_rtp_packet_size), buffsend, pte);
  2375. }
  2376. if (unistimdebug) {
  2377. ast_verb(0, "Sending Jitter Buffer Parameters Configuration\n");
  2378. }
  2379. memcpy(buffsend + SIZE_HEADER, packet_send_jitter_buffer_conf,
  2380. sizeof(packet_send_jitter_buffer_conf));
  2381. send_client(SIZE_HEADER + sizeof(packet_send_jitter_buffer_conf), buffsend, pte);
  2382. if (pte->device->rtp_method != 0) {
  2383. uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
  2384. if (unistimdebug) {
  2385. ast_verb(0, "Sending OpenAudioStreamTX using method #%d\n", pte->device->rtp_method);
  2386. }
  2387. if (pte->device->rtp_method == 3) {
  2388. memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx3,
  2389. sizeof(packet_send_open_audio_stream_tx3));
  2390. } else {
  2391. memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_tx,
  2392. sizeof(packet_send_open_audio_stream_tx));
  2393. }
  2394. if (pte->device->rtp_method != 2) {
  2395. memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
  2396. buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
  2397. buffsend[21] = (htons(sin.sin_port) & 0x00ff);
  2398. buffsend[23] = (rtcpsin_port & 0x00ff);
  2399. buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
  2400. buffsend[25] = (us.sin_port & 0xff00) >> 8;
  2401. buffsend[24] = (us.sin_port & 0x00ff);
  2402. buffsend[27] = (rtcpsin_port & 0x00ff);
  2403. buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
  2404. } else {
  2405. memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
  2406. buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
  2407. buffsend[16] = (htons(sin.sin_port) & 0x00ff);
  2408. buffsend[20] = (us.sin_port & 0xff00) >> 8;
  2409. buffsend[19] = (us.sin_port & 0x00ff);
  2410. }
  2411. buffsend[11] = codec; /* rx */
  2412. buffsend[12] = codec; /* tx */
  2413. send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_tx), buffsend, pte);
  2414. if (unistimdebug) {
  2415. ast_verb(0, "Sending OpenAudioStreamRX\n");
  2416. }
  2417. if (pte->device->rtp_method == 3) {
  2418. memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx3,
  2419. sizeof(packet_send_open_audio_stream_rx3));
  2420. } else {
  2421. memcpy(buffsend + SIZE_HEADER, packet_send_open_audio_stream_rx,
  2422. sizeof(packet_send_open_audio_stream_rx));
  2423. }
  2424. if (pte->device->rtp_method != 2) {
  2425. memcpy(buffsend + 28, &public.sin_addr, sizeof(public.sin_addr));
  2426. buffsend[20] = (htons(sin.sin_port) & 0xff00) >> 8;
  2427. buffsend[21] = (htons(sin.sin_port) & 0x00ff);
  2428. buffsend[23] = (rtcpsin_port & 0x00ff);
  2429. buffsend[22] = (rtcpsin_port & 0xff00) >> 8;
  2430. buffsend[25] = (us.sin_port & 0xff00) >> 8;
  2431. buffsend[24] = (us.sin_port & 0x00ff);
  2432. buffsend[27] = (rtcpsin_port & 0x00ff);
  2433. buffsend[26] = (rtcpsin_port & 0xff00) >> 8;
  2434. } else {
  2435. memcpy(buffsend + 23, &public.sin_addr, sizeof(public.sin_addr));
  2436. buffsend[15] = (htons(sin.sin_port) & 0xff00) >> 8;
  2437. buffsend[16] = (htons(sin.sin_port) & 0x00ff);
  2438. buffsend[20] = (us.sin_port & 0xff00) >> 8;
  2439. buffsend[19] = (us.sin_port & 0x00ff);
  2440. }
  2441. buffsend[11] = codec; /* rx */
  2442. buffsend[12] = codec; /* tx */
  2443. send_client(SIZE_HEADER + sizeof(packet_send_open_audio_stream_rx), buffsend, pte);
  2444. } else {
  2445. uint16_t rtcpsin_port = htons(us.sin_port) + 1; /* RTCP port is RTP + 1 */
  2446. if (unistimdebug) {
  2447. ast_verb(0, "Sending packet_send_call default method\n");
  2448. }
  2449. memcpy(buffsend + SIZE_HEADER, packet_send_call, sizeof(packet_send_call));
  2450. memcpy(buffsend + 53, &public.sin_addr, sizeof(public.sin_addr));
  2451. /* Destination port when sending RTP */
  2452. buffsend[49] = (us.sin_port & 0x00ff);
  2453. buffsend[50] = (us.sin_port & 0xff00) >> 8;
  2454. /* Destination port when sending RTCP */
  2455. buffsend[52] = (rtcpsin_port & 0x00ff);
  2456. buffsend[51] = (rtcpsin_port & 0xff00) >> 8;
  2457. /* Codec */
  2458. buffsend[40] = codec;
  2459. buffsend[41] = codec;
  2460. if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ULAW) {
  2461. buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
  2462. } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_ALAW) {
  2463. buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
  2464. } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G723_1) {
  2465. buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
  2466. } else if (ast_channel_readformat(sub->owner)->id == AST_FORMAT_G729A) {
  2467. buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
  2468. } else {
  2469. ast_log(LOG_WARNING, "Unsupported codec %s!\n",
  2470. ast_getformatname(ast_channel_readformat(sub->owner)));
  2471. }
  2472. /* Source port for transmit RTP and Destination port for receiving RTP */
  2473. buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
  2474. buffsend[46] = (htons(sin.sin_port) & 0x00ff);
  2475. buffsend[47] = (rtcpsin_port & 0xff00) >> 8;
  2476. buffsend[48] = (rtcpsin_port & 0x00ff);
  2477. send_client(SIZE_HEADER + sizeof(packet_send_call), buffsend, pte);
  2478. }
  2479. }
  2480. static void start_rtp(struct unistim_subchannel *sub)
  2481. {
  2482. struct sockaddr_in sin = { 0, };
  2483. struct sockaddr_in sout = { 0, };
  2484. struct ast_sockaddr sin_tmp;
  2485. struct ast_sockaddr sout_tmp;
  2486. /* Sanity checks */
  2487. if (!sub) {
  2488. ast_log(LOG_WARNING, "start_rtp with a null subchannel !\n");
  2489. return;
  2490. }
  2491. if (!sub->parent) {
  2492. ast_log(LOG_WARNING, "start_rtp with a null line!\n");
  2493. return;
  2494. }
  2495. if (!sub->parent->parent) {
  2496. ast_log(LOG_WARNING, "start_rtp with a null device!\n");
  2497. return;
  2498. }
  2499. if (!sub->parent->parent->session) {
  2500. ast_log(LOG_WARNING, "start_rtp with a null session!\n");
  2501. return;
  2502. }
  2503. if (!sub->owner) {
  2504. ast_log(LOG_WARNING, "start_rtp with a null asterisk channel!\n");
  2505. return;
  2506. }
  2507. sout = sub->parent->parent->session->sout;
  2508. ast_mutex_lock(&sub->lock);
  2509. /* Allocate the RTP */
  2510. if (unistimdebug) {
  2511. ast_verb(0, "Starting RTP. Bind on %s\n", ast_inet_ntoa(sout.sin_addr));
  2512. }
  2513. ast_sockaddr_from_sin(&sout_tmp, &sout);
  2514. sub->rtp = ast_rtp_instance_new("asterisk", sched, &sout_tmp, NULL);
  2515. if (!sub->rtp) {
  2516. ast_log(LOG_WARNING, "Unable to create RTP session: %s binaddr=%s\n",
  2517. strerror(errno), ast_inet_ntoa(sout.sin_addr));
  2518. ast_mutex_unlock(&sub->lock);
  2519. return;
  2520. }
  2521. ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_RTCP, 1);
  2522. ast_rtp_instance_set_channel_id(sub->rtp, ast_channel_uniqueid(sub->owner));
  2523. ast_channel_internal_fd_set(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
  2524. ast_channel_internal_fd_set(sub->owner, 1, ast_rtp_instance_fd(sub->rtp, 1));
  2525. ast_rtp_instance_set_qos(sub->rtp, qos.tos_audio, qos.cos_audio, "UNISTIM RTP");
  2526. ast_rtp_instance_set_prop(sub->rtp, AST_RTP_PROPERTY_NAT, sub->parent->parent->nat);
  2527. /* Create the RTP connection */
  2528. sin.sin_family = AF_INET;
  2529. /* Setting up RTP for our side */
  2530. memcpy(&sin.sin_addr, &sub->parent->parent->session->sin.sin_addr,
  2531. sizeof(sin.sin_addr));
  2532. sin.sin_port = htons(find_rtp_port(sub));
  2533. ast_sockaddr_from_sin(&sin_tmp, &sin);
  2534. ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
  2535. if (!ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), ast_channel_readformat(sub->owner))) {
  2536. struct ast_format tmpfmt;
  2537. char tmp[256];
  2538. ast_best_codec(ast_channel_nativeformats(sub->owner), &tmpfmt);
  2539. ast_log(LOG_WARNING,
  2540. "Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
  2541. ast_getformatname(ast_channel_readformat(sub->owner)),
  2542. ast_getformatname(&tmpfmt),
  2543. ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(sub->owner)));
  2544. ast_format_copy(ast_channel_readformat(sub->owner), &tmpfmt);
  2545. ast_format_copy(ast_channel_writeformat(sub->owner), &tmpfmt);
  2546. }
  2547. send_start_rtp(sub);
  2548. ast_mutex_unlock(&sub->lock);
  2549. }
  2550. static void send_dial_tone(struct unistimsession *pte)
  2551. {
  2552. struct ast_tone_zone_sound *ts = NULL;
  2553. struct ast_tone_zone_part tone_data;
  2554. char *s = NULL;
  2555. char *ind;
  2556. if ((ts = ast_get_indication_tone(pte->device->tz, "dial"))) {
  2557. ind = ast_strdupa(ts->data);
  2558. s = strsep(&ind, ",");
  2559. ast_tone_zone_part_parse(s, &tone_data);
  2560. send_tone(pte, tone_data.freq1, tone_data.freq2);
  2561. if (unistimdebug) {
  2562. ast_verb(0, "Country code found (%s), freq1=%u freq2=%u\n",
  2563. pte->device->tz->country, tone_data.freq1, tone_data.freq2);
  2564. }
  2565. ts = ast_tone_zone_sound_unref(ts);
  2566. }
  2567. }
  2568. static void show_phone_number(struct unistimsession *pte)
  2569. {
  2570. char tmp[TEXT_LENGTH_MAX + 1];
  2571. const char *tmp_number = ustmtext("Number:", pte);
  2572. int line, tmp_copy, offset = 0, i;
  2573. pte->device->phone_number[pte->device->size_phone_number] = '\0';
  2574. if (pte->device->size_phone_number > MAX_SCREEN_NUMBER) {
  2575. offset = pte->device->size_phone_number - MAX_SCREEN_NUMBER - 1;
  2576. if (offset > strlen(tmp_number)) {
  2577. offset = strlen(tmp_number);
  2578. }
  2579. tmp_copy = strlen(tmp_number) - offset + 1;
  2580. if (tmp_copy > sizeof(tmp)) {
  2581. tmp_copy = sizeof(tmp);
  2582. }
  2583. memcpy(tmp, tmp_number + offset, tmp_copy);
  2584. } else {
  2585. ast_copy_string(tmp, tmp_number, sizeof(tmp));
  2586. }
  2587. offset = (pte->device->size_phone_number >= TEXT_LENGTH_MAX) ? (pte->device->size_phone_number - TEXT_LENGTH_MAX +1) : 0;
  2588. if (pte->device->size_phone_number) {
  2589. memcpy(tmp + strlen(tmp), pte->device->phone_number + offset, pte->device->size_phone_number - offset + 1);
  2590. }
  2591. offset = strlen(tmp);
  2592. for (i = strlen(tmp); i < TEXT_LENGTH_MAX; i++) {
  2593. tmp[i] = '.';
  2594. }
  2595. tmp[i] = '\0';
  2596. line = (pte->device->height == 1) ? TEXT_LINE0 : TEXT_LINE2;
  2597. send_text(line, TEXT_NORMAL, pte, tmp);
  2598. send_blink_cursor(pte);
  2599. send_cursor_pos(pte, (unsigned char) (line + offset));
  2600. send_led_update(pte, 0);
  2601. }
  2602. static void handle_dial_page(struct unistimsession *pte)
  2603. {
  2604. pte->state = STATE_DIALPAGE;
  2605. if (pte->device->call_forward[0] == -1) {
  2606. send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
  2607. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Enter forward", pte));
  2608. send_text_status(pte, ustmtext("Fwd Cancel BackSp Erase", pte));
  2609. if (pte->device->call_forward[1] != 0) {
  2610. ast_copy_string(pte->device->phone_number, pte->device->call_forward + 1,
  2611. sizeof(pte->device->phone_number));
  2612. show_phone_number(pte);
  2613. send_led_update(pte, 0);
  2614. return;
  2615. }
  2616. } else {
  2617. if ((pte->device->output == OUTPUT_HANDSET) &&
  2618. (pte->device->receiver_state == STATE_ONHOOK)) {
  2619. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  2620. } else {
  2621. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
  2622. }
  2623. send_dial_tone(pte);
  2624. if (pte->device->height > 1) {
  2625. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Enter the number to dial", pte));
  2626. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("and press Call", pte));
  2627. }
  2628. if (ast_strlen_zero(pte->device->redial_number)) {
  2629. send_text_status(pte, ustmtext("Call BackSp Erase", pte));
  2630. } else {
  2631. send_text_status(pte, ustmtext("Call Redial BackSp Erase", pte));
  2632. }
  2633. }
  2634. pte->device->size_phone_number = 0;
  2635. pte->device->phone_number[0] = 0;
  2636. show_phone_number(pte);
  2637. change_favorite_icon(pte, FAV_ICON_PHONE_BLACK);
  2638. send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
  2639. pte->device->missed_call = 0;
  2640. send_led_update(pte, 0);
  2641. pte->device->lastmsgssent = -1;
  2642. return;
  2643. }
  2644. static void swap_subs(struct unistim_subchannel *a, struct unistim_subchannel *b)
  2645. {
  2646. struct ast_rtp_instance *rtp;
  2647. int fds;
  2648. if (unistimdebug) {
  2649. ast_verb(0, "Swapping %p and %p\n", a, b);
  2650. }
  2651. if ((!a->owner) || (!b->owner)) {
  2652. ast_log(LOG_WARNING,
  2653. "Attempted to swap subchannels with a null owner : sub #%p=%p sub #%p=%p\n",
  2654. a, a->owner, b, b->owner);
  2655. return;
  2656. }
  2657. rtp = a->rtp;
  2658. a->rtp = b->rtp;
  2659. b->rtp = rtp;
  2660. fds = ast_channel_fd(a->owner, 0);
  2661. ast_channel_internal_fd_set(a->owner, 0, ast_channel_fd(b->owner, 0));
  2662. ast_channel_internal_fd_set(b->owner, 0, fds);
  2663. fds = ast_channel_fd(a->owner, 1);
  2664. ast_channel_internal_fd_set(a->owner, 1, ast_channel_fd(b->owner, 1));
  2665. ast_channel_internal_fd_set(b->owner, 1, fds);
  2666. }
  2667. /* Step 1 : Music On Hold for peer, Dialing screen for us */
  2668. static void transfer_call_step1(struct unistimsession *pte)
  2669. {
  2670. struct unistim_subchannel *sub /*, *sub_trans */;
  2671. struct unistim_device *d = pte->device;
  2672. sub = get_sub(d, SUB_REAL);
  2673. /* sub_trans = get_sub(d, SUB_THREEWAY); */
  2674. if (!sub || !sub->owner) {
  2675. ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
  2676. return;
  2677. }
  2678. /* Start music on hold if appropriate */
  2679. if (sub->moh) {
  2680. ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
  2681. } else {
  2682. ast_queue_hold(sub->owner, sub->parent->musicclass);
  2683. sub->moh = 1;
  2684. sub->subtype = SUB_THREEWAY;
  2685. }
  2686. sub_start_silence(pte, sub);
  2687. handle_dial_page(pte);
  2688. }
  2689. static void transfer_cancel_step2(struct unistimsession *pte)
  2690. {
  2691. struct unistim_subchannel *sub, *sub_trans;
  2692. struct unistim_device *d = pte->device;
  2693. sub = get_sub(d, SUB_REAL);
  2694. sub_trans = get_sub(d, SUB_THREEWAY);
  2695. if (!sub || !sub->owner) {
  2696. ast_log(LOG_WARNING, "Unable to find subchannel for music on hold\n");
  2697. return;
  2698. }
  2699. if (sub_trans) {
  2700. if (unistimdebug) {
  2701. ast_verb(0, "Transfer canceled, hangup our threeway channel\n");
  2702. }
  2703. if (sub->owner) {
  2704. swap_subs(sub, sub_trans);
  2705. ast_queue_unhold(sub_trans->owner);
  2706. sub_trans->moh = 0;
  2707. sub_trans->subtype = SUB_REAL;
  2708. sub->subtype = SUB_THREEWAY;
  2709. ast_queue_hangup_with_cause(sub->owner, AST_CAUSE_NORMAL_CLEARING);
  2710. } else {
  2711. ast_log(LOG_WARNING, "Canceling a threeway channel without owner\n");
  2712. }
  2713. return;
  2714. }
  2715. }
  2716. /* From phone to PBX */
  2717. static void handle_call_outgoing(struct unistimsession *s)
  2718. {
  2719. struct ast_channel *c;
  2720. struct unistim_subchannel *sub;
  2721. int softkey;
  2722. s->state = STATE_CALL;
  2723. sub = get_sub(s->device, SUB_THREEWAY);
  2724. if (sub) {
  2725. /* If sub for threway call created than we use transfer behaviuor */
  2726. struct unistim_subchannel *sub_trans = NULL;
  2727. struct unistim_device *d = s->device;
  2728. sub_trans = get_sub(d, SUB_REAL);
  2729. if (sub_trans) {
  2730. ast_log(LOG_WARNING, "Can't transfer while active subchannel exists!\n");
  2731. return;
  2732. }
  2733. if (!sub->owner) {
  2734. ast_log(LOG_WARNING, "Unable to find subchannel with music on hold\n");
  2735. return;
  2736. }
  2737. sub_trans = unistim_alloc_sub(d, SUB_REAL);
  2738. if (!sub_trans) {
  2739. ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
  2740. return;
  2741. }
  2742. sub_trans->parent = sub->parent;
  2743. sub_stop_silence(s, sub);
  2744. send_tone(s, 0, 0);
  2745. /* Make new channel */
  2746. c = unistim_new(sub_trans, AST_STATE_DOWN, NULL, NULL);
  2747. if (!c) {
  2748. ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent);
  2749. return;
  2750. }
  2751. /* Swap things around between the three-way and real call */
  2752. swap_subs(sub, sub_trans);
  2753. send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
  2754. if (s->device->height == 1) {
  2755. send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
  2756. } else {
  2757. send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling (pre-transfer)", s));
  2758. send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
  2759. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
  2760. }
  2761. send_text_status(s, ustmtext("TransfrCancel", s));
  2762. if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
  2763. ast_log(LOG_WARNING, "Unable to start simple switch on channel %p\n", c);
  2764. sub->ss_thread = AST_PTHREADT_NULL;
  2765. ast_hangup(c);
  2766. return;
  2767. }
  2768. if (unistimdebug) {
  2769. ast_verb(0, "Started three way call on channel %p (%s) subchan %u\n",
  2770. sub_trans->owner, ast_channel_name(sub_trans->owner), sub_trans->subtype);
  2771. }
  2772. return;
  2773. }
  2774. softkey = get_avail_softkey(s, NULL);
  2775. if (softkey == -1) {
  2776. ast_log(LOG_WARNING, "Have no avail softkey for calling\n");
  2777. return;
  2778. }
  2779. sub = get_sub(s->device, SUB_REAL);
  2780. if (sub) { /* have already call assigned */
  2781. sub_hold(s, sub); /* Need to put on hold */
  2782. }
  2783. if (!(sub = unistim_alloc_sub(s->device, SUB_REAL))) {
  2784. ast_log(LOG_WARNING, "Unable to allocate subchannel!\n");
  2785. return;
  2786. }
  2787. sub->parent = s->device->sline[softkey];
  2788. s->device->ssub[softkey] = sub;
  2789. sub->softkey = softkey;
  2790. if (unistimdebug) {
  2791. ast_verb(0, "Using softkey %d, line %p\n", sub->softkey, sub->parent);
  2792. }
  2793. send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
  2794. s->device->selected = -1;
  2795. if (!sub->owner) { /* A call is already in progress ? */
  2796. RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
  2797. const char *pickupexten;
  2798. c = unistim_new(sub, AST_STATE_DOWN, NULL, NULL); /* No, starting a new one */
  2799. if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
  2800. start_rtp(sub);
  2801. }
  2802. if (c) {
  2803. ast_channel_lock(c);
  2804. pickup_cfg = ast_get_chan_features_pickup_config(c);
  2805. if (!pickup_cfg) {
  2806. ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
  2807. pickupexten = "";
  2808. } else {
  2809. pickupexten = ast_strdupa(pickup_cfg->pickupexten);
  2810. }
  2811. ast_channel_unlock(c);
  2812. }
  2813. if (c && !strcmp(s->device->phone_number, pickupexten)) {
  2814. if (unistimdebug) {
  2815. ast_verb(0, "Try to pickup in unistim_new\n");
  2816. }
  2817. send_text(TEXT_LINE0, TEXT_NORMAL, s, "");
  2818. send_text_status(s, ustmtext(" Transf Hangup", s));
  2819. send_start_timer(s);
  2820. if (ast_pickup_call(c)) {
  2821. ast_log(LOG_NOTICE, "Nothing to pick up\n");
  2822. ast_channel_hangupcause_set(c, AST_CAUSE_CALL_REJECTED);
  2823. } else {
  2824. ast_channel_hangupcause_set(c, AST_CAUSE_NORMAL_CLEARING);
  2825. }
  2826. ast_hangup(c);
  2827. c = NULL;
  2828. } else if (c) {
  2829. send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
  2830. send_tone(s, 0, 0); /* Dialing empty number should also stop dial tone */
  2831. if (s->device->height == 1) {
  2832. if (strlen(s->device->phone_number) > 0) {
  2833. send_text(TEXT_LINE0, TEXT_NORMAL, s, s->device->phone_number);
  2834. } else {
  2835. send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling...", s));
  2836. }
  2837. } else {
  2838. send_text(TEXT_LINE0, TEXT_NORMAL, s, ustmtext("Calling :", s));
  2839. send_text(TEXT_LINE1, TEXT_NORMAL, s, s->device->phone_number);
  2840. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Dialing...", s));
  2841. }
  2842. send_text_status(s, ustmtext(" Hangup", s));
  2843. /* start switch */
  2844. if (ast_pthread_create(&sub->ss_thread, NULL, unistim_ss, c)) {
  2845. ast_log(LOG_WARNING, "Unable to create switch thread\n");
  2846. sub->ss_thread = AST_PTHREADT_NULL;
  2847. ast_queue_hangup_with_cause(c, AST_CAUSE_SWITCH_CONGESTION);
  2848. }
  2849. } else
  2850. ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n",
  2851. sub->parent->name, s->device->name);
  2852. } else {
  2853. ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
  2854. }
  2855. return;
  2856. }
  2857. /* From PBX to phone */
  2858. static void handle_call_incoming(struct unistimsession *s)
  2859. {
  2860. struct unistim_subchannel *sub = NULL;
  2861. int i;
  2862. s->state = STATE_CALL;
  2863. s->device->missed_call = 0;
  2864. send_no_ring(s);
  2865. sub = get_sub(s->device, SUB_RING); /* Put other SUB_REAL call on hold */
  2866. if (!sub) {
  2867. ast_log(LOG_WARNING, "No ringing lines on: %s\n", s->device->name);
  2868. return;
  2869. }
  2870. /* Change icons for all ringing keys */
  2871. for (i = 0; i < FAVNUM; i++) {
  2872. if (!s->device->ssub[i]) { /* No sub assigned - skip */
  2873. continue;
  2874. }
  2875. if (s->device->ssub[i]->subtype == SUB_REAL) {
  2876. sub_hold(s, s->device->ssub[i]);
  2877. }
  2878. if (s->device->ssub[i] != sub) {
  2879. continue;
  2880. }
  2881. if (sub->softkey == i) { /* If softkey assigned at this moment - do not erase */
  2882. continue;
  2883. }
  2884. if (sub->softkey < 0) { /* If softkey not defined - first one used */
  2885. sub->softkey = i;
  2886. continue;
  2887. }
  2888. send_favorite_short(i, FAV_LINE_ICON, s);
  2889. s->device->ssub[i] = NULL;
  2890. }
  2891. if (sub->softkey < 0) {
  2892. ast_log(LOG_WARNING, "Can not assign softkey for incoming call on: %s\n", s->device->name);
  2893. return;
  2894. }
  2895. send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
  2896. sub->parent = s->device->sline[sub->softkey];
  2897. sub->subtype = SUB_REAL;
  2898. if (unistimdebug) {
  2899. ast_verb(0, "Handle Call Incoming for %s@%s\n", sub->parent->name,
  2900. s->device->name);
  2901. }
  2902. start_rtp(sub);
  2903. if (!sub->rtp) {
  2904. ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", sub->parent->name, s->device->name);
  2905. return;
  2906. }
  2907. if (sub->owner) {
  2908. ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
  2909. }
  2910. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
  2911. send_text_status(s, ustmtext(" Transf Hangup", s));
  2912. send_start_timer(s);
  2913. if ((s->device->output == OUTPUT_HANDSET) &&
  2914. (s->device->receiver_state == STATE_ONHOOK)) {
  2915. send_select_output(s, OUTPUT_SPEAKER, s->device->volume, MUTE_OFF);
  2916. } else {
  2917. send_select_output(s, s->device->output, s->device->volume, MUTE_OFF);
  2918. }
  2919. write_history(s, 'i', 0);
  2920. return;
  2921. }
  2922. static int unistim_do_senddigit(struct unistimsession *pte, char digit)
  2923. {
  2924. struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = digit, .src = "unistim" };
  2925. struct unistim_subchannel *sub;
  2926. int row, col;
  2927. sub = get_sub(pte->device, SUB_REAL);
  2928. if (!sub || !sub->owner || sub->alreadygone) {
  2929. ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit\n");
  2930. return -1;
  2931. }
  2932. /* Send DTMF indication _before_ playing sounds */
  2933. ast_queue_frame(sub->owner, &f);
  2934. if (unistimdebug) {
  2935. ast_verb(0, "Send Digit %c\n", digit);
  2936. }
  2937. row = (digit - '1') % 3;
  2938. col = (digit - '1' - row) / 3;
  2939. if (digit >= '1' && digit <='9') {
  2940. send_tone(pte, dtmf_row[row], dtmf_col[col]);
  2941. } else if (digit >= 'A' && digit <= 'D') {
  2942. send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]);
  2943. } else if (digit == '*') {
  2944. send_tone(pte, dtmf_row[3], dtmf_col[0]);
  2945. } else if (digit == '0') {
  2946. send_tone(pte, dtmf_row[3], dtmf_col[1]);
  2947. } else if (digit == '#') {
  2948. send_tone(pte, dtmf_row[3], dtmf_col[2]);
  2949. } else {
  2950. send_tone(pte, 500, 2000);
  2951. }
  2952. usleep(150000); /* XXX Less than perfect, blocking an important thread is not a good idea */
  2953. send_tone(pte, 0, 0);
  2954. return 0;
  2955. }
  2956. static void handle_key_fav(struct unistimsession *pte, char keycode)
  2957. {
  2958. int keynum = keycode - KEY_FAV0;
  2959. struct unistim_subchannel *sub;
  2960. sub = get_sub(pte->device, SUB_REAL);
  2961. /* Make an action on selected favorite key */
  2962. if (!pte->device->ssub[keynum]) { /* Key have no assigned call */
  2963. send_favorite_selected(FAV_LINE_ICON, pte);
  2964. if (is_key_line(pte->device, keynum)) {
  2965. if (unistimdebug) {
  2966. ast_verb(0, "Handle line w/o sub - dialpage\n");
  2967. }
  2968. pte->device->selected = keynum;
  2969. sub_hold(pte, sub); /* Put active call on hold */
  2970. send_stop_timer(pte);
  2971. handle_dial_page(pte);
  2972. } else if (is_key_favorite(pte->device, keynum)) {
  2973. /* Put active call on hold in handle_call_outgoing function, after preparation and
  2974. checking if lines available for calling */
  2975. if (unistimdebug) {
  2976. ast_verb(0, "Handle favorite w/o sub - dialing\n");
  2977. }
  2978. if ((pte->device->output == OUTPUT_HANDSET) &&
  2979. (pte->device->receiver_state == STATE_ONHOOK)) {
  2980. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  2981. } else {
  2982. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
  2983. }
  2984. key_favorite(pte, keycode);
  2985. }
  2986. } else {
  2987. sub = pte->device->ssub[keynum];
  2988. /* Favicon have assigned sub, activate it and put current on hold */
  2989. if (sub->subtype == SUB_REAL) {
  2990. sub_hold(pte, sub);
  2991. show_main_page(pte);
  2992. } else if (sub->subtype == SUB_RING) {
  2993. sub->softkey = keynum;
  2994. handle_call_incoming(pte);
  2995. } else if (sub->subtype == SUB_ONHOLD) {
  2996. if (pte->state == STATE_DIALPAGE){
  2997. send_tone(pte, 0, 0);
  2998. }
  2999. send_callerid_screen(pte, sub);
  3000. sub_unhold(pte, sub);
  3001. pte->state = STATE_CALL;
  3002. }
  3003. }
  3004. }
  3005. static void key_call(struct unistimsession *pte, char keycode)
  3006. {
  3007. struct unistim_subchannel *sub = get_sub(pte->device, SUB_REAL);
  3008. struct unistim_subchannel *sub_3way = get_sub(pte->device, SUB_THREEWAY);
  3009. if (!sub) {
  3010. return;
  3011. }
  3012. if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
  3013. if (keycode == KEY_SHARP) {
  3014. keycode = '#';
  3015. } else if (keycode == KEY_STAR) {
  3016. keycode = '*';
  3017. } else {
  3018. keycode -= 0x10;
  3019. }
  3020. unistim_do_senddigit(pte, keycode);
  3021. return;
  3022. }
  3023. switch (keycode) {
  3024. case KEY_FUNC1:
  3025. if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_UP) {
  3026. if (sub_3way) {
  3027. close_call(pte);
  3028. }
  3029. }
  3030. break;
  3031. case KEY_FUNC2:
  3032. if (sub_3way) {
  3033. transfer_cancel_step2(pte);
  3034. } else if (ast_channel_state(sub->owner) == AST_STATE_UP) {
  3035. transfer_call_step1(pte);
  3036. }
  3037. break;
  3038. case KEY_HANGUP:
  3039. case KEY_FUNC4:
  3040. if (!sub_3way) {
  3041. close_call(pte);
  3042. }
  3043. break;
  3044. case KEY_FAV0:
  3045. case KEY_FAV1:
  3046. case KEY_FAV2:
  3047. case KEY_FAV3:
  3048. case KEY_FAV4:
  3049. case KEY_FAV5:
  3050. handle_key_fav(pte, keycode);
  3051. break;
  3052. case KEY_HEADPHN:
  3053. if (pte->device->output == OUTPUT_HEADPHONE) {
  3054. send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
  3055. } else {
  3056. send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
  3057. }
  3058. break;
  3059. case KEY_LOUDSPK:
  3060. if (pte->device->output != OUTPUT_SPEAKER)
  3061. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  3062. else
  3063. send_select_output(pte, pte->device->previous_output, pte->device->volume,
  3064. MUTE_OFF);
  3065. break;
  3066. case KEY_MUTE:
  3067. if (!sub->owner) {
  3068. ast_log(LOG_WARNING, "Unable to find channel for music on hold\n");
  3069. return;
  3070. }
  3071. if (!sub->moh) {
  3072. if (pte->device->mute == MUTE_ON) {
  3073. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
  3074. } else {
  3075. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
  3076. }
  3077. break;
  3078. }
  3079. break;
  3080. case KEY_ONHOLD:
  3081. if (!sub) {
  3082. if(pte->device->ssub[pte->device->selected]) {
  3083. sub_hold(pte, pte->device->ssub[pte->device->selected]);
  3084. }
  3085. } else {
  3086. sub_hold(pte, sub);
  3087. }
  3088. break;
  3089. }
  3090. return;
  3091. }
  3092. static void key_ringing(struct unistimsession *pte, char keycode)
  3093. {
  3094. switch (keycode) {
  3095. case KEY_FAV0:
  3096. case KEY_FAV1:
  3097. case KEY_FAV2:
  3098. case KEY_FAV3:
  3099. case KEY_FAV4:
  3100. case KEY_FAV5:
  3101. handle_key_fav(pte, keycode);
  3102. break;
  3103. case KEY_FUNC3:
  3104. ignore_call(pte);
  3105. break;
  3106. case KEY_HANGUP:
  3107. case KEY_FUNC4:
  3108. discard_call(pte);
  3109. break;
  3110. case KEY_LOUDSPK:
  3111. pte->device->output = OUTPUT_SPEAKER;
  3112. handle_call_incoming(pte);
  3113. break;
  3114. case KEY_HEADPHN:
  3115. pte->device->output = OUTPUT_HEADPHONE;
  3116. handle_call_incoming(pte);
  3117. break;
  3118. case KEY_FUNC1:
  3119. handle_call_incoming(pte);
  3120. break;
  3121. }
  3122. return;
  3123. }
  3124. static void key_favorite(struct unistimsession *pte, char keycode)
  3125. {
  3126. int fav = keycode - KEY_FAV0;
  3127. if (!is_key_favorite(pte->device, fav)) {
  3128. ast_log(LOG_WARNING, "It's not a favorite key\n");
  3129. return;
  3130. }
  3131. ast_copy_string(pte->device->phone_number, pte->device->softkeynumber[fav],
  3132. sizeof(pte->device->phone_number));
  3133. handle_call_outgoing(pte);
  3134. return;
  3135. }
  3136. static void key_dial_page(struct unistimsession *pte, char keycode)
  3137. {
  3138. struct unistim_subchannel *sub = get_sub(pte->device, SUB_THREEWAY);
  3139. pte->device->nextdial = 0;
  3140. if (keycode == KEY_FUNC3) {
  3141. if (pte->device->size_phone_number <= 1) {
  3142. keycode = KEY_FUNC4;
  3143. } else {
  3144. pte->device->size_phone_number -= 2;
  3145. keycode = pte->device->phone_number[pte->device->size_phone_number] + 0x10;
  3146. }
  3147. }
  3148. if (keycode == KEY_SHARP && pte->device->sharp_dial == 1) {
  3149. keycode = KEY_FUNC1;
  3150. }
  3151. if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
  3152. int i = pte->device->size_phone_number;
  3153. if (pte->device->size_phone_number == 0) {
  3154. send_tone(pte, 0, 0);
  3155. }
  3156. if (keycode == KEY_SHARP) {
  3157. keycode = '#';
  3158. } else if (keycode == KEY_STAR) {
  3159. keycode = '*';
  3160. } else {
  3161. keycode -= 0x10;
  3162. }
  3163. pte->device->phone_number[i] = keycode;
  3164. pte->device->size_phone_number++;
  3165. pte->device->phone_number[i + 1] = 0;
  3166. show_phone_number(pte);
  3167. if (ast_exists_extension(NULL, pte->device->context, pte->device->phone_number, 1, NULL) &&
  3168. !ast_matchmore_extension(NULL, pte->device->context, pte->device->phone_number, 1, NULL)) {
  3169. keycode = KEY_FUNC1;
  3170. } else {
  3171. if (pte->device->interdigit_timer) {
  3172. pte->device->nextdial = get_tick_count() + pte->device->interdigit_timer;
  3173. }
  3174. }
  3175. }
  3176. if (keycode == KEY_FUNC4) {
  3177. pte->device->size_phone_number = 0;
  3178. show_phone_number(pte);
  3179. return;
  3180. }
  3181. if (pte->device->call_forward[0] == -1) {
  3182. if (keycode == KEY_FUNC1) {
  3183. ast_copy_string(pte->device->call_forward, pte->device->phone_number,
  3184. sizeof(pte->device->call_forward));
  3185. show_main_page(pte);
  3186. } else if ((keycode == KEY_FUNC2) || (keycode == KEY_HANGUP)) {
  3187. pte->device->call_forward[0] = '\0';
  3188. send_led_update(pte, 0x08);
  3189. send_led_update(pte, 0x10);
  3190. show_main_page(pte);
  3191. }
  3192. return;
  3193. }
  3194. switch (keycode) {
  3195. case KEY_FUNC2:
  3196. if (ast_strlen_zero(pte->device->redial_number)) {
  3197. break;
  3198. }
  3199. ast_copy_string(pte->device->phone_number, pte->device->redial_number,
  3200. sizeof(pte->device->phone_number));
  3201. case KEY_FUNC1:
  3202. handle_call_outgoing(pte);
  3203. break;
  3204. case KEY_HANGUP:
  3205. if (sub && sub->owner) {
  3206. sub_stop_silence(pte, sub);
  3207. send_tone(pte, 0, 0);
  3208. ast_queue_unhold(sub->owner);
  3209. sub->moh = 0;
  3210. sub->subtype = SUB_REAL;
  3211. pte->state = STATE_CALL;
  3212. send_text_status(pte, ustmtext(" Transf Hangup", pte));
  3213. send_callerid_screen(pte, sub);
  3214. } else {
  3215. send_led_update(pte, 0x08);
  3216. send_led_update(pte, 0x10);
  3217. show_main_page(pte);
  3218. }
  3219. break;
  3220. case KEY_FAV0:
  3221. case KEY_FAV1:
  3222. case KEY_FAV2:
  3223. case KEY_FAV3:
  3224. case KEY_FAV4:
  3225. case KEY_FAV5:
  3226. send_favorite_selected(FAV_LINE_ICON, pte);
  3227. pte->device->selected = -1;
  3228. handle_key_fav(pte, keycode);
  3229. break;
  3230. case KEY_LOUDSPK:
  3231. if (pte->device->output == OUTPUT_SPEAKER) {
  3232. if (pte->device->receiver_state == STATE_OFFHOOK) {
  3233. send_select_output(pte, pte->device->previous_output, pte->device->volume,
  3234. MUTE_OFF);
  3235. } else {
  3236. show_main_page(pte);
  3237. }
  3238. } else {
  3239. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  3240. }
  3241. break;
  3242. case KEY_HEADPHN:
  3243. if (pte->device->output == OUTPUT_HEADPHONE) {
  3244. if (pte->device->receiver_state == STATE_OFFHOOK) {
  3245. send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
  3246. } else {
  3247. show_main_page(pte);
  3248. }
  3249. } else {
  3250. send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
  3251. }
  3252. break;
  3253. }
  3254. return;
  3255. }
  3256. static void handle_select_option(struct unistimsession *pte)
  3257. {
  3258. char tmp[128];
  3259. if (pte->state != STATE_SELECTOPTION) {
  3260. pte->state = STATE_SELECTOPTION;
  3261. pte->size_buff_entry = 1;
  3262. pte->buff_entry[0] = 0; /* Position in menu */
  3263. }
  3264. snprintf(tmp, sizeof(tmp), "%d. %s", pte->buff_entry[0] + 1, ustmtext(options_menu[(int)pte->buff_entry[0]].label, pte));
  3265. send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp);
  3266. send_text_status(pte, ustmtext("Select Cancel", pte));
  3267. return;
  3268. }
  3269. static void key_select_option(struct unistimsession *pte, char keycode)
  3270. {
  3271. switch (keycode) {
  3272. case KEY_DOWN:
  3273. pte->buff_entry[0]++;
  3274. if (options_menu[(int)pte->buff_entry[0]].label == NULL) {
  3275. pte->buff_entry[0]--;
  3276. }
  3277. break;
  3278. case KEY_UP:
  3279. if (pte->buff_entry[0] > 0) {
  3280. pte->buff_entry[0]--;
  3281. }
  3282. break;
  3283. case KEY_FUNC1:
  3284. options_menu[(int)pte->buff_entry[0]].handle_option(pte);
  3285. return;
  3286. case KEY_HANGUP:
  3287. case KEY_FUNC4:
  3288. show_main_page(pte);
  3289. return;
  3290. }
  3291. handle_select_option(pte);
  3292. return;
  3293. }
  3294. #define SELECTCODEC_START_ENTRY_POS 15
  3295. #define SELECTCODEC_MAX_LENGTH 2
  3296. #define SELECTCODEC_MSG "Codec number : .."
  3297. static void handle_select_codec(struct unistimsession *pte)
  3298. {
  3299. char buf[30], buf2[5];
  3300. pte->state = STATE_SELECTCODEC;
  3301. ast_copy_string(buf, ustmtext("Using codec", pte), sizeof(buf));
  3302. snprintf(buf2, sizeof(buf2), " %d", pte->device->codec_number);
  3303. strcat(buf, buf2);
  3304. strcat(buf, " (G711u=0,");
  3305. send_text(TEXT_LINE0, TEXT_NORMAL, pte, buf);
  3306. send_text(TEXT_LINE1, TEXT_NORMAL, pte, "G723=4,G711a=8,G729A=18)");
  3307. send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
  3308. send_blink_cursor(pte);
  3309. send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
  3310. pte->size_buff_entry = 0;
  3311. send_text_status(pte, ustmtext("Select BackSp Erase Cancel", pte));
  3312. return;
  3313. }
  3314. static void key_select_codec(struct unistimsession *pte, char keycode)
  3315. {
  3316. if (keycode == KEY_FUNC2) {
  3317. if (pte->size_buff_entry <= 1) {
  3318. keycode = KEY_FUNC3;
  3319. } else {
  3320. pte->size_buff_entry -= 2;
  3321. keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
  3322. }
  3323. }
  3324. if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
  3325. char tmpbuf[] = SELECTCODEC_MSG;
  3326. int i = 0;
  3327. if (pte->size_buff_entry >= SELECTCODEC_MAX_LENGTH) {
  3328. return;
  3329. }
  3330. while (i < pte->size_buff_entry) {
  3331. tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = pte->buff_entry[i];
  3332. i++;
  3333. }
  3334. tmpbuf[i + SELECTCODEC_START_ENTRY_POS] = keycode - 0x10;
  3335. pte->buff_entry[i] = keycode - 0x10;
  3336. pte->size_buff_entry++;
  3337. send_text(TEXT_LINE2, TEXT_INVERSE, pte, tmpbuf);
  3338. send_blink_cursor(pte);
  3339. send_cursor_pos(pte,
  3340. (unsigned char) (TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS + 1 + i));
  3341. return;
  3342. }
  3343. switch (keycode) {
  3344. case KEY_FUNC1:
  3345. if (pte->size_buff_entry == 1) {
  3346. pte->device->codec_number = pte->buff_entry[0] - 48;
  3347. } else if (pte->size_buff_entry == 2) {
  3348. pte->device->codec_number =
  3349. ((pte->buff_entry[0] - 48) * 10) + (pte->buff_entry[1] - 48);
  3350. }
  3351. show_main_page(pte);
  3352. break;
  3353. case KEY_FUNC3:
  3354. pte->size_buff_entry = 0;
  3355. send_text(TEXT_LINE2, TEXT_INVERSE, pte, SELECTCODEC_MSG);
  3356. send_blink_cursor(pte);
  3357. send_cursor_pos(pte, TEXT_LINE2 + SELECTCODEC_START_ENTRY_POS);
  3358. break;
  3359. case KEY_HANGUP:
  3360. case KEY_FUNC4:
  3361. show_main_page(pte);
  3362. break;
  3363. }
  3364. return;
  3365. }
  3366. static int find_language(const char* lang)
  3367. {
  3368. int i = 0;
  3369. while (options_languages[i].lang_short != NULL) {
  3370. if(!strcmp(options_languages[i].lang_short, lang)) {
  3371. return i;
  3372. }
  3373. i++;
  3374. }
  3375. return 0;
  3376. }
  3377. static void handle_select_language(struct unistimsession *pte)
  3378. {
  3379. char tmp_language[40];
  3380. struct unistim_languages lang;
  3381. if (pte->state != STATE_SELECTLANGUAGE) {
  3382. pte->state = STATE_SELECTLANGUAGE;
  3383. pte->size_buff_entry = 1;
  3384. pte->buff_entry[0] = find_language(pte->device->language);
  3385. }
  3386. lang = options_languages[(int)pte->buff_entry[0]];
  3387. ast_copy_string(tmp_language, pte->device->language, sizeof(tmp_language));
  3388. ast_copy_string(pte->device->language, lang.lang_short, sizeof(pte->device->language));
  3389. send_charset_update(pte, lang.encoding);
  3390. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext(lang.label, pte));
  3391. ast_copy_string(pte->device->language, tmp_language, sizeof(pte->device->language));
  3392. lang = options_languages[find_language(pte->device->language)];
  3393. send_charset_update(pte, lang.encoding);
  3394. send_text_status(pte, ustmtext("Select Cancel", pte));
  3395. return;
  3396. }
  3397. static void key_select_language(struct unistimsession *pte, char keycode)
  3398. {
  3399. switch (keycode) {
  3400. case KEY_DOWN:
  3401. pte->buff_entry[0]++;
  3402. if (options_languages[(int)pte->buff_entry[0]].label == NULL) {
  3403. pte->buff_entry[0]--;
  3404. }
  3405. break;
  3406. case KEY_UP:
  3407. if (pte->buff_entry[0] > 0) {
  3408. pte->buff_entry[0]--;
  3409. }
  3410. break;
  3411. case KEY_FUNC1:
  3412. ast_copy_string(pte->device->language, options_languages[(int)pte->buff_entry[0]].lang_short, sizeof(pte->device->language));
  3413. send_charset_update(pte, options_languages[(int)pte->buff_entry[0]].encoding);
  3414. refresh_all_favorite(pte);
  3415. show_main_page(pte);
  3416. return;
  3417. case KEY_HANGUP:
  3418. case KEY_FUNC4:
  3419. handle_select_option(pte);
  3420. return;
  3421. }
  3422. handle_select_language(pte);
  3423. return;
  3424. }
  3425. #define SELECTEXTENSION_START_ENTRY_POS 0
  3426. #define SELECTEXTENSION_MAX_LENGTH 10
  3427. #define SELECTEXTENSION_MSG ".........."
  3428. static void show_extension_page(struct unistimsession *pte)
  3429. {
  3430. pte->state = STATE_EXTENSION;
  3431. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Please enter a Terminal", pte));
  3432. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Number (TN) :", pte));
  3433. send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
  3434. send_blink_cursor(pte);
  3435. send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
  3436. send_text_status(pte, ustmtext("Enter BackSpcErase", pte));
  3437. pte->size_buff_entry = 0;
  3438. return;
  3439. }
  3440. static void key_select_extension(struct unistimsession *pte, char keycode)
  3441. {
  3442. if (keycode == KEY_FUNC2) {
  3443. if (pte->size_buff_entry <= 1) {
  3444. keycode = KEY_FUNC3;
  3445. } else {
  3446. pte->size_buff_entry -= 2;
  3447. keycode = pte->buff_entry[pte->size_buff_entry] + 0x10;
  3448. }
  3449. }
  3450. if ((keycode >= KEY_0) && (keycode <= KEY_9)) {
  3451. char tmpbuf[] = SELECTEXTENSION_MSG;
  3452. int i = 0;
  3453. if (pte->size_buff_entry >= SELECTEXTENSION_MAX_LENGTH) {
  3454. return;
  3455. }
  3456. while (i < pte->size_buff_entry) {
  3457. tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = pte->buff_entry[i];
  3458. i++;
  3459. }
  3460. tmpbuf[i + SELECTEXTENSION_START_ENTRY_POS] = keycode - 0x10;
  3461. pte->buff_entry[i] = keycode - 0x10;
  3462. pte->size_buff_entry++;
  3463. send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
  3464. send_blink_cursor(pte);
  3465. send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS + 1 + i));
  3466. return;
  3467. }
  3468. switch (keycode) {
  3469. case KEY_FUNC1:
  3470. if (pte->size_buff_entry < 1) {
  3471. return;
  3472. }
  3473. if (autoprovisioning == AUTOPROVISIONING_TN) {
  3474. struct unistim_device *d;
  3475. /* First step : looking for this TN in our device list */
  3476. ast_mutex_lock(&devicelock);
  3477. d = devices;
  3478. pte->buff_entry[pte->size_buff_entry] = '\0';
  3479. while (d) {
  3480. if (d->id[0] == 'T') { /* It's a TN device ? */
  3481. /* It's the TN we're looking for ? */
  3482. if (!strcmp((d->id) + 1, pte->buff_entry)) {
  3483. pte->device = d;
  3484. d->session = pte;
  3485. d->codec_number = DEFAULT_CODEC;
  3486. d->missed_call = 0;
  3487. d->receiver_state = STATE_ONHOOK;
  3488. strcpy(d->id, pte->macaddr);
  3489. pte->device->extension_number[0] = 'T';
  3490. pte->device->extension = EXTENSION_TN;
  3491. ast_copy_string((pte->device->extension_number) + 1,
  3492. pte->buff_entry, pte->size_buff_entry + 1);
  3493. ast_mutex_unlock(&devicelock);
  3494. show_main_page(pte);
  3495. refresh_all_favorite(pte);
  3496. return;
  3497. }
  3498. }
  3499. d = d->next;
  3500. }
  3501. ast_mutex_unlock(&devicelock);
  3502. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid Terminal Number.", pte));
  3503. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
  3504. send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS +
  3505. pte->size_buff_entry));
  3506. send_blink_cursor(pte);
  3507. } else {
  3508. ast_copy_string(pte->device->extension_number, pte->buff_entry,
  3509. pte->size_buff_entry + 1);
  3510. if (register_extension(pte)) {
  3511. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Invalid extension.", pte));
  3512. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("Please try again :", pte));
  3513. send_cursor_pos(pte, (unsigned char) (TEXT_LINE2 +
  3514. SELECTEXTENSION_START_ENTRY_POS +
  3515. pte->size_buff_entry));
  3516. send_blink_cursor(pte);
  3517. } else
  3518. show_main_page(pte);
  3519. }
  3520. break;
  3521. case KEY_FUNC3:
  3522. pte->size_buff_entry = 0;
  3523. send_text(TEXT_LINE2, TEXT_NORMAL, pte, SELECTEXTENSION_MSG);
  3524. send_blink_cursor(pte);
  3525. send_cursor_pos(pte, TEXT_LINE2 + SELECTEXTENSION_START_ENTRY_POS);
  3526. break;
  3527. }
  3528. return;
  3529. }
  3530. static void show_entry_history(struct unistimsession *pte, FILE ** f)
  3531. {
  3532. char line[TEXT_LENGTH_MAX + 1], status[STATUS_LENGTH_MAX + 1], func1[10], func2[10],
  3533. func3[10];
  3534. /* Display date/time and call status */
  3535. if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
  3536. display_last_error("Can't read history date entry");
  3537. fclose(*f);
  3538. return;
  3539. }
  3540. line[sizeof(line) - 1] = '\0';
  3541. if (pte->device->height == 1) {
  3542. if (pte->buff_entry[3] == 1) {
  3543. send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
  3544. }
  3545. } else {
  3546. send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
  3547. }
  3548. /* Display number */
  3549. if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
  3550. display_last_error("Can't read callerid entry");
  3551. fclose(*f);
  3552. return;
  3553. }
  3554. line[sizeof(line) - 1] = '\0';
  3555. ast_copy_string(pte->device->lst_cid, line, sizeof(pte->device->lst_cid));
  3556. ast_trim_blanks(pte->device->lst_cid);
  3557. if (pte->device->height == 1) {
  3558. if (pte->buff_entry[3] == 2) {
  3559. send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
  3560. }
  3561. } else {
  3562. send_text(TEXT_LINE1, TEXT_NORMAL, pte, line);
  3563. }
  3564. /* Display name */
  3565. if (fread(line, TEXT_LENGTH_MAX, 1, *f) != 1) {
  3566. display_last_error("Can't read callername entry");
  3567. fclose(*f);
  3568. return;
  3569. }
  3570. line[sizeof(line) - 1] = '\0';
  3571. if (pte->device->height == 1) {
  3572. if (pte->buff_entry[3] == 3) {
  3573. send_text(TEXT_LINE0, TEXT_NORMAL, pte, line);
  3574. }
  3575. } else {
  3576. send_text(TEXT_LINE2, TEXT_NORMAL, pte, line);
  3577. }
  3578. fclose(*f);
  3579. snprintf(line, sizeof(line), "%s %03d/%03d", ustmtext("Call", pte), pte->buff_entry[2],
  3580. pte->buff_entry[1]);
  3581. send_texttitle(pte, line);
  3582. if (pte->buff_entry[2] == 1) {
  3583. ast_copy_string(func1, " ", sizeof(func1));
  3584. } else {
  3585. ast_copy_string(func1, ustmtext("Prev ", pte), sizeof(func1));
  3586. }
  3587. if (pte->buff_entry[2] >= pte->buff_entry[1]) {
  3588. ast_copy_string(func2, " ", sizeof(func2));
  3589. } else {
  3590. ast_copy_string(func2, ustmtext("Next ", pte), sizeof(func2));
  3591. }
  3592. if (strlen(pte->device->lst_cid)) {
  3593. ast_copy_string(func3, ustmtext("Redial ", pte), sizeof(func3));
  3594. } else {
  3595. ast_copy_string(func3, " ", sizeof(func3));
  3596. }
  3597. snprintf(status, sizeof(status), "%s%s%s%s", func1, func2, func3, ustmtext("Cancel", pte));
  3598. send_text_status(pte, status);
  3599. }
  3600. static char open_history(struct unistimsession *pte, char way, FILE ** f)
  3601. {
  3602. char tmp[AST_CONFIG_MAX_PATH];
  3603. char count;
  3604. snprintf(tmp, sizeof(tmp), "%s/%s/%s-%c.csv", ast_config_AST_LOG_DIR,
  3605. USTM_LOG_DIR, pte->device->name, way);
  3606. *f = fopen(tmp, "r");
  3607. if (!*f) {
  3608. display_last_error("Unable to open history file");
  3609. return 0;
  3610. }
  3611. if (fread(&count, 1, 1, *f) != 1) {
  3612. display_last_error("Unable to read history header - display.");
  3613. fclose(*f);
  3614. *f = NULL;
  3615. return 0;
  3616. }
  3617. if (count > MAX_ENTRY_LOG) {
  3618. ast_log(LOG_WARNING, "Invalid count in history header of %s (%d max %d)\n", tmp,
  3619. count, MAX_ENTRY_LOG);
  3620. fclose(*f);
  3621. *f = NULL;
  3622. return 0;
  3623. }
  3624. return count;
  3625. }
  3626. static void show_history(struct unistimsession *pte, char way)
  3627. {
  3628. FILE *f;
  3629. char count;
  3630. if (!pte->device) {
  3631. return;
  3632. }
  3633. if (!pte->device->callhistory) {
  3634. return;
  3635. }
  3636. count = open_history(pte, way, &f);
  3637. if (!count) {
  3638. return;
  3639. }
  3640. pte->buff_entry[0] = way;
  3641. pte->buff_entry[1] = count;
  3642. pte->buff_entry[2] = 1;
  3643. pte->buff_entry[3] = 1;
  3644. show_entry_history(pte, &f);
  3645. pte->state = STATE_HISTORY;
  3646. }
  3647. static void show_main_page(struct unistimsession *pte)
  3648. {
  3649. char tmpbuf[TEXT_LENGTH_MAX + 1];
  3650. const char *text;
  3651. if ((pte->device->extension == EXTENSION_ASK) &&
  3652. (ast_strlen_zero(pte->device->extension_number))) {
  3653. show_extension_page(pte);
  3654. return;
  3655. }
  3656. pte->state = STATE_MAINPAGE;
  3657. send_led_update(pte, 0);
  3658. pte->device->lastmsgssent = -1;
  3659. send_tone(pte, 0, 0);
  3660. send_stop_timer(pte); /* case of holding call */
  3661. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON_DISCRET);
  3662. send_led_update(pte, 0x08);
  3663. send_led_update(pte, 0x10);
  3664. if (!ast_strlen_zero(pte->device->call_forward)) {
  3665. if (pte->device->height == 1) {
  3666. char tmp_field[100];
  3667. snprintf(tmp_field, sizeof(tmp_field), "%s %s", ustmtext("Fwd to:", pte), pte->device->call_forward);
  3668. send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmp_field);
  3669. } else {
  3670. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Call forwarded to :", pte));
  3671. send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->call_forward);
  3672. }
  3673. send_icon(TEXT_LINE0, FAV_ICON_REFLECT + FAV_BLINK_SLOW, pte);
  3674. if (ast_strlen_zero(pte->device->redial_number)) {
  3675. send_text_status(pte, ustmtext("Dial NoFwd ", pte));
  3676. } else {
  3677. send_text_status(pte, ustmtext("Dial Redial NoFwd ", pte));
  3678. }
  3679. } else {
  3680. if ((pte->device->extension == EXTENSION_ASK) || (pte->device->extension == EXTENSION_TN)) {
  3681. if (ast_strlen_zero(pte->device->redial_number)) {
  3682. send_text_status(pte, ustmtext("Dial Fwd Unregis", pte));
  3683. } else {
  3684. send_text_status(pte, ustmtext("Dial Redial Fwd Unregis", pte));
  3685. }
  3686. } else {
  3687. if (ast_strlen_zero(pte->device->redial_number)) {
  3688. send_text_status(pte, ustmtext("Dial Fwd Pickup", pte));
  3689. } else {
  3690. send_text_status(pte, ustmtext("Dial Redial Fwd Pickup", pte));
  3691. }
  3692. }
  3693. send_text(TEXT_LINE1, TEXT_NORMAL, pte, pte->device->maintext1);
  3694. if (pte->device->missed_call == 0) {
  3695. send_date_time2(pte);
  3696. send_idle_clock(pte);
  3697. if (strlen(pte->device->maintext0)) {
  3698. send_text(TEXT_LINE0, TEXT_NORMAL, pte, pte->device->maintext0);
  3699. }
  3700. } else {
  3701. if (pte->device->missed_call == 1) {
  3702. text = ustmtext("unanswered call", pte);
  3703. } else {
  3704. text = ustmtext("unanswered calls", pte);
  3705. }
  3706. snprintf(tmpbuf, sizeof(tmpbuf), "%d %s", pte->device->missed_call, text);
  3707. send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpbuf);
  3708. send_icon(TEXT_LINE0, FAV_ICON_CALL_CENTER + FAV_BLINK_SLOW, pte);
  3709. }
  3710. }
  3711. if (pte->device->height > 1) {
  3712. if (ast_strlen_zero(pte->device->maintext2)) {
  3713. strcpy(tmpbuf, "IP : ");
  3714. strcat(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
  3715. send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmpbuf);
  3716. } else {
  3717. send_text(TEXT_LINE2, TEXT_NORMAL, pte, pte->device->maintext2);
  3718. }
  3719. }
  3720. send_texttitle(pte, pte->device->titledefault);
  3721. change_favorite_icon(pte, FAV_LINE_ICON);
  3722. }
  3723. static void key_main_page(struct unistimsession *pte, char keycode)
  3724. {
  3725. if (pte->device->missed_call) {
  3726. send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
  3727. pte->device->missed_call = 0;
  3728. }
  3729. if ((keycode >= KEY_0) && (keycode <= KEY_SHARP)) {
  3730. handle_dial_page(pte);
  3731. key_dial_page(pte, keycode);
  3732. return;
  3733. }
  3734. switch (keycode) {
  3735. case KEY_FUNC1:
  3736. pte->device->selected = get_avail_softkey(pte, NULL);
  3737. handle_dial_page(pte);
  3738. break;
  3739. case KEY_FUNC2:
  3740. if (ast_strlen_zero(pte->device->redial_number)) {
  3741. break;
  3742. }
  3743. if ((pte->device->output == OUTPUT_HANDSET) &&
  3744. (pte->device->receiver_state == STATE_ONHOOK)) {
  3745. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  3746. } else {
  3747. send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
  3748. }
  3749. ast_copy_string(pte->device->phone_number, pte->device->redial_number,
  3750. sizeof(pte->device->phone_number));
  3751. handle_call_outgoing(pte);
  3752. break;
  3753. case KEY_FUNC3:
  3754. if (!ast_strlen_zero(pte->device->call_forward)) {
  3755. /* Cancel call forwarding */
  3756. memmove(pte->device->call_forward + 1, pte->device->call_forward,
  3757. sizeof(pte->device->call_forward) - 1);
  3758. pte->device->call_forward[0] = '\0';
  3759. send_icon(TEXT_LINE0, FAV_ICON_NONE, pte);
  3760. pte->device->output = OUTPUT_HANDSET; /* Seems to be reseted somewhere */
  3761. show_main_page(pte);
  3762. break;
  3763. }
  3764. pte->device->call_forward[0] = -1;
  3765. handle_dial_page(pte);
  3766. break;
  3767. case KEY_FUNC4:
  3768. if (pte->device->extension == EXTENSION_ASK) {
  3769. unregister_extension(pte);
  3770. pte->device->extension_number[0] = '\0';
  3771. show_extension_page(pte);
  3772. } else if (pte->device->extension == EXTENSION_TN) {
  3773. ast_mutex_lock(&devicelock);
  3774. strcpy(pte->device->id, pte->device->extension_number);
  3775. pte->buff_entry[0] = '\0';
  3776. pte->size_buff_entry = 0;
  3777. pte->device->session = NULL;
  3778. pte->device = NULL;
  3779. ast_mutex_unlock(&devicelock);
  3780. show_extension_page(pte);
  3781. } else { /* Pickup function */
  3782. /* XXX Is there a way to get a specific channel here? */
  3783. RAII_VAR(struct ast_features_pickup_config *, pickup_cfg,
  3784. ast_get_chan_features_pickup_config(NULL), ao2_cleanup);
  3785. if (!pickup_cfg) {
  3786. ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
  3787. break;
  3788. }
  3789. pte->device->selected = -1;
  3790. ast_copy_string(pte->device->phone_number, pickup_cfg->pickupexten,
  3791. sizeof(pte->device->phone_number));
  3792. handle_call_outgoing(pte);
  3793. }
  3794. break;
  3795. case KEY_FAV0:
  3796. case KEY_FAV1:
  3797. case KEY_FAV2:
  3798. case KEY_FAV3:
  3799. case KEY_FAV4:
  3800. case KEY_FAV5:
  3801. handle_key_fav(pte, keycode);
  3802. break;
  3803. case KEY_CONF:
  3804. handle_select_option(pte);
  3805. break;
  3806. case KEY_LOUDSPK:
  3807. send_select_output(pte, OUTPUT_SPEAKER, pte->device->volume, MUTE_OFF);
  3808. handle_dial_page(pte);
  3809. break;
  3810. case KEY_HEADPHN:
  3811. send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
  3812. handle_dial_page(pte);
  3813. break;
  3814. case KEY_SNDHIST:
  3815. show_history(pte, 'o');
  3816. break;
  3817. case KEY_RCVHIST:
  3818. show_history(pte, 'i');
  3819. break;
  3820. }
  3821. return;
  3822. }
  3823. static void key_history(struct unistimsession *pte, char keycode)
  3824. {
  3825. FILE *f;
  3826. char count;
  3827. long offset;
  3828. int flag = 0;
  3829. switch (keycode) {
  3830. case KEY_LEFT:
  3831. if (pte->device->height == 1) {
  3832. if (pte->buff_entry[3] <= 1) {
  3833. return;
  3834. }
  3835. pte->buff_entry[3]--;
  3836. flag = 1;
  3837. break;
  3838. }
  3839. case KEY_UP:
  3840. case KEY_FUNC1:
  3841. if (pte->buff_entry[2] <= 1) {
  3842. return;
  3843. }
  3844. pte->buff_entry[2]--;
  3845. flag = 1;
  3846. break;
  3847. case KEY_RIGHT:
  3848. if (pte->device->height == 1) {
  3849. if (pte->buff_entry[3] == 3) {
  3850. return;
  3851. }
  3852. pte->buff_entry[3]++;
  3853. flag = 1;
  3854. break;
  3855. }
  3856. case KEY_DOWN:
  3857. case KEY_FUNC2:
  3858. if (pte->buff_entry[2] >= pte->buff_entry[1]) {
  3859. return;
  3860. }
  3861. pte->buff_entry[2]++;
  3862. flag = 1;
  3863. break;
  3864. case KEY_FUNC3:
  3865. if (ast_strlen_zero(pte->device->lst_cid)) {
  3866. break;
  3867. }
  3868. ast_copy_string(pte->device->redial_number, pte->device->lst_cid,
  3869. sizeof(pte->device->redial_number));
  3870. key_main_page(pte, KEY_FUNC2);
  3871. break;
  3872. case KEY_FUNC4:
  3873. case KEY_HANGUP:
  3874. show_main_page(pte);
  3875. break;
  3876. case KEY_SNDHIST:
  3877. if (pte->buff_entry[0] == 'i') {
  3878. show_history(pte, 'o');
  3879. } else {
  3880. show_main_page(pte);
  3881. }
  3882. break;
  3883. case KEY_RCVHIST:
  3884. if (pte->buff_entry[0] == 'i') {
  3885. show_main_page(pte);
  3886. } else {
  3887. show_history(pte, 'i');
  3888. }
  3889. break;
  3890. }
  3891. if (flag) {
  3892. count = open_history(pte, pte->buff_entry[0], &f);
  3893. if (!count) {
  3894. return;
  3895. }
  3896. offset = ((pte->buff_entry[2] - 1) * TEXT_LENGTH_MAX * 3);
  3897. if (fseek(f, offset, SEEK_CUR)) {
  3898. display_last_error("Unable to seek history entry.");
  3899. fclose(f);
  3900. return;
  3901. }
  3902. show_entry_history(pte, &f);
  3903. }
  3904. return;
  3905. }
  3906. static void init_phone_step2(struct unistimsession *pte)
  3907. {
  3908. BUFFSEND;
  3909. if (unistimdebug) {
  3910. ast_verb(0, "Sending S4\n");
  3911. }
  3912. memcpy(buffsend + SIZE_HEADER, packet_send_s4, sizeof(packet_send_s4));
  3913. send_client(SIZE_HEADER + sizeof(packet_send_s4), buffsend, pte);
  3914. send_date_time2(pte);
  3915. send_date_time3(pte);
  3916. if (unistimdebug) {
  3917. ast_verb(0, "Sending S7\n");
  3918. }
  3919. memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
  3920. send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
  3921. if (unistimdebug) {
  3922. ast_verb(0, "Sending Contrast\n");
  3923. }
  3924. memcpy(buffsend + SIZE_HEADER, packet_send_Contrast, sizeof(packet_send_Contrast));
  3925. if (pte->device != NULL) {
  3926. buffsend[9] = pte->device->contrast;
  3927. }
  3928. send_client(SIZE_HEADER + sizeof(packet_send_Contrast), buffsend, pte);
  3929. if (unistimdebug) {
  3930. ast_verb(0, "Sending S9\n");
  3931. }
  3932. memcpy(buffsend + SIZE_HEADER, packet_send_s9, sizeof(packet_send_s9));
  3933. send_client(SIZE_HEADER + sizeof(packet_send_s9), buffsend, pte);
  3934. send_no_ring(pte);
  3935. if (unistimdebug) {
  3936. ast_verb(0, "Sending S7\n");
  3937. }
  3938. memcpy(buffsend + SIZE_HEADER, packet_send_S7, sizeof(packet_send_S7));
  3939. send_client(SIZE_HEADER + sizeof(packet_send_S7), buffsend, pte);
  3940. send_led_update(pte, 0);
  3941. send_ping(pte);
  3942. if (unistimdebug) {
  3943. ast_verb(0, "Sending init language\n");
  3944. }
  3945. if (pte->device) {
  3946. send_charset_update(pte, options_languages[find_language(pte->device->language)].encoding);
  3947. }
  3948. if (pte->state < STATE_MAINPAGE) {
  3949. if (autoprovisioning == AUTOPROVISIONING_TN) {
  3950. show_extension_page(pte);
  3951. return;
  3952. } else {
  3953. int i;
  3954. char tmp[30];
  3955. for (i = 1; i < FAVNUM; i++) {
  3956. send_favorite(i, 0, pte, "");
  3957. }
  3958. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Phone is not registered", pte));
  3959. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext("in unistim.conf", pte));
  3960. strcpy(tmp, "MAC = ");
  3961. strcat(tmp, pte->macaddr);
  3962. send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
  3963. send_text_status(pte, "");
  3964. send_texttitle(pte, "UNISTIM for*");
  3965. return;
  3966. }
  3967. }
  3968. show_main_page(pte);
  3969. refresh_all_favorite(pte);
  3970. if (unistimdebug) {
  3971. ast_verb(0, "Sending arrow\n");
  3972. }
  3973. memcpy(buffsend + SIZE_HEADER, packet_send_arrow, sizeof(packet_send_arrow));
  3974. send_client(SIZE_HEADER + sizeof(packet_send_arrow), buffsend, pte);
  3975. return;
  3976. }
  3977. static void process_request(int size, unsigned char *buf, struct unistimsession *pte)
  3978. {
  3979. char tmpbuf[255];
  3980. if (memcmp
  3981. (buf + SIZE_HEADER, packet_recv_resume_connection_with_server,
  3982. sizeof(packet_recv_resume_connection_with_server)) == 0) {
  3983. rcv_resume_connection_with_server(pte);
  3984. return;
  3985. }
  3986. if (memcmp(buf + SIZE_HEADER, packet_recv_firm_version, sizeof(packet_recv_firm_version)) == 0) {
  3987. buf[size] = 0;
  3988. if (unistimdebug) {
  3989. ast_verb(0, "Got the firmware version : '%s'\n", buf + 13);
  3990. }
  3991. ast_copy_string(pte->firmware, (char *) (buf + 13), sizeof(pte->firmware));
  3992. init_phone_step2(pte);
  3993. return;
  3994. }
  3995. if (memcmp(buf + SIZE_HEADER, packet_recv_it_type, sizeof(packet_recv_it_type)) == 0) {
  3996. char type = buf[13];
  3997. if (unistimdebug) {
  3998. ast_verb(0, "Got the equipment type: '%d'\n", type);
  3999. }
  4000. switch (type) {
  4001. case 0x03: /* i2002 */
  4002. if (pte->device) {
  4003. pte->device->height = 1;
  4004. }
  4005. break;
  4006. }
  4007. return;
  4008. }
  4009. if (memcmp(buf + SIZE_HEADER, packet_recv_mac_addr, sizeof(packet_recv_mac_addr)) == 0) {
  4010. rcv_mac_addr(pte, buf);
  4011. return;
  4012. }
  4013. if (memcmp(buf + SIZE_HEADER, packet_recv_r2, sizeof(packet_recv_r2)) == 0) {
  4014. if (unistimdebug) {
  4015. ast_verb(0, "R2 received\n");
  4016. }
  4017. return;
  4018. }
  4019. if (pte->state < STATE_MAINPAGE) {
  4020. if (unistimdebug) {
  4021. ast_verb(0, "Request not authorized in this state\n");
  4022. }
  4023. return;
  4024. }
  4025. if (!memcmp(buf + SIZE_HEADER, packet_recv_pressed_key, sizeof(packet_recv_pressed_key))) {
  4026. char keycode = buf[13];
  4027. if (unistimdebug) {
  4028. ast_verb(0, "Key pressed: keycode = 0x%02hhx - current state: %s\n", (unsigned char)keycode,
  4029. ptestate_tostr(pte->state));
  4030. }
  4031. switch (pte->state) {
  4032. case STATE_INIT:
  4033. if (unistimdebug) {
  4034. ast_verb(0, "No keys allowed in the init state\n");
  4035. }
  4036. break;
  4037. case STATE_AUTHDENY:
  4038. if (unistimdebug) {
  4039. ast_verb(0, "No keys allowed in authdeny state\n");
  4040. }
  4041. break;
  4042. case STATE_MAINPAGE:
  4043. key_main_page(pte, keycode);
  4044. break;
  4045. case STATE_DIALPAGE:
  4046. key_dial_page(pte, keycode);
  4047. break;
  4048. case STATE_RINGING:
  4049. key_ringing(pte, keycode);
  4050. break;
  4051. case STATE_CALL:
  4052. key_call(pte, keycode);
  4053. break;
  4054. case STATE_EXTENSION:
  4055. key_select_extension(pte, keycode);
  4056. break;
  4057. case STATE_SELECTOPTION:
  4058. key_select_option(pte, keycode);
  4059. break;
  4060. case STATE_SELECTCODEC:
  4061. key_select_codec(pte, keycode);
  4062. break;
  4063. case STATE_SELECTLANGUAGE:
  4064. key_select_language(pte, keycode);
  4065. break;
  4066. case STATE_HISTORY:
  4067. key_history(pte, keycode);
  4068. break;
  4069. default:
  4070. ast_log(LOG_WARNING, "Key : Unknown state\n");
  4071. }
  4072. return;
  4073. }
  4074. if (memcmp(buf + SIZE_HEADER, packet_recv_pick_up, sizeof(packet_recv_pick_up)) == 0) {
  4075. if (unistimdebug) {
  4076. ast_verb(0, "Handset off hook, current state: %s\n", ptestate_tostr(pte->state));
  4077. }
  4078. if (!pte->device) { /* We are not yet registered (asking for a TN in AUTOPROVISIONING_TN) */
  4079. return;
  4080. }
  4081. pte->device->receiver_state = STATE_OFFHOOK;
  4082. if (pte->device->output == OUTPUT_HEADPHONE) {
  4083. send_select_output(pte, OUTPUT_HEADPHONE, pte->device->volume, MUTE_OFF);
  4084. } else {
  4085. send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
  4086. }
  4087. if (pte->state == STATE_RINGING) {
  4088. handle_call_incoming(pte);
  4089. } else if ((pte->state == STATE_DIALPAGE) || (pte->state == STATE_CALL)) {
  4090. send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
  4091. } else if (pte->state == STATE_EXTENSION) { /* We must have a TN before calling */
  4092. return;
  4093. } else {
  4094. pte->device->selected = get_avail_softkey(pte, NULL);
  4095. send_select_output(pte, OUTPUT_HANDSET, pte->device->volume, MUTE_OFF);
  4096. handle_dial_page(pte);
  4097. }
  4098. return;
  4099. }
  4100. if (memcmp(buf + SIZE_HEADER, packet_recv_hangup, sizeof(packet_recv_hangup)) == 0) {
  4101. if (unistimdebug) {
  4102. ast_verb(0, "Handset on hook, current state: %s\n", ptestate_tostr(pte->state));
  4103. }
  4104. if (!pte->device) {
  4105. return;
  4106. }
  4107. pte->device->receiver_state = STATE_ONHOOK;
  4108. if (pte->state == STATE_CALL) {
  4109. if (pte->device->output != OUTPUT_SPEAKER) {
  4110. close_call(pte);
  4111. }
  4112. } else if (pte->state == STATE_EXTENSION) {
  4113. return;
  4114. } else {
  4115. pte->device->nextdial = 0;
  4116. show_main_page(pte);
  4117. }
  4118. return;
  4119. }
  4120. strcpy(tmpbuf, ast_inet_ntoa(pte->sin.sin_addr));
  4121. strcat(tmpbuf, " Unknown request packet\n");
  4122. if (unistimdebug) {
  4123. ast_debug(1, "%s", tmpbuf);
  4124. }
  4125. return;
  4126. }
  4127. static void parsing(int size, unsigned char *buf, struct unistimsession *pte,
  4128. struct sockaddr_in *addr_from)
  4129. {
  4130. unsigned short *sbuf = (unsigned short *) buf;
  4131. unsigned short seq;
  4132. char tmpbuf[255];
  4133. strcpy(tmpbuf, ast_inet_ntoa(addr_from->sin_addr));
  4134. if (size < 10) {
  4135. if (size == 0) {
  4136. ast_log(LOG_WARNING, "%s Read error\n", tmpbuf);
  4137. } else {
  4138. ast_log(LOG_NOTICE, "%s Packet too short - ignoring\n", tmpbuf);
  4139. }
  4140. return;
  4141. }
  4142. if (sbuf[0] == 0xffff) { /* Starting with 0xffff ? *//* Yes, discovery packet ? */
  4143. if (size != sizeof(packet_rcv_discovery)) {
  4144. ast_log(LOG_NOTICE, "%s Invalid size of a discovery packet\n", tmpbuf);
  4145. } else {
  4146. if (memcmp(buf, packet_rcv_discovery, sizeof(packet_rcv_discovery)) == 0) {
  4147. if (unistimdebug) {
  4148. ast_verb(0, "Discovery packet received - Sending Discovery ACK\n");
  4149. }
  4150. if (pte) { /* A session was already active for this IP ? */
  4151. if (pte->state == STATE_INIT) { /* Yes, but it's a dupe */
  4152. if (unistimdebug) {
  4153. ast_verb(1, "Duplicated Discovery packet\n");
  4154. }
  4155. send_raw_client(sizeof(packet_send_discovery_ack),
  4156. packet_send_discovery_ack, addr_from, &pte->sout);
  4157. pte->seq_phone = (short) 0x0000; /* reset sequence number */
  4158. } else { /* No, probably a reboot, phone side */
  4159. close_client(pte); /* Cleanup the previous session */
  4160. if (create_client(addr_from)) {
  4161. send_raw_client(sizeof(packet_send_discovery_ack),
  4162. packet_send_discovery_ack, addr_from, &pte->sout);
  4163. }
  4164. }
  4165. } else {
  4166. /* Creating new entry in our phone list */
  4167. if ((pte = create_client(addr_from))) {
  4168. send_raw_client(sizeof(packet_send_discovery_ack),
  4169. packet_send_discovery_ack, addr_from, &pte->sout);
  4170. }
  4171. }
  4172. return;
  4173. }
  4174. ast_log(LOG_NOTICE, "%s Invalid discovery packet\n", tmpbuf);
  4175. }
  4176. return;
  4177. }
  4178. if (!pte) {
  4179. if (unistimdebug) {
  4180. ast_verb(0, "%s Not a discovery packet from an unknown source : ignoring\n", tmpbuf);
  4181. }
  4182. return;
  4183. }
  4184. if (sbuf[0] != 0) { /* Starting with something else than 0x0000 ? */
  4185. ast_log(LOG_NOTICE, "Unknown packet received - ignoring\n");
  4186. return;
  4187. }
  4188. if (buf[5] != 2) {
  4189. ast_log(LOG_NOTICE, "%s Wrong direction : got 0x%02hhx expected 0x02\n", tmpbuf, buf[5]);
  4190. return;
  4191. }
  4192. seq = ntohs(sbuf[1]);
  4193. if (buf[4] == 1) {
  4194. ast_mutex_lock(&pte->lock);
  4195. if (unistimdebug) {
  4196. ast_verb(6, "ACK received for packet #0x%04x\n", (unsigned)seq);
  4197. }
  4198. pte->nb_retransmit = 0;
  4199. if ((pte->last_seq_ack) + 1 == seq) {
  4200. pte->last_seq_ack++;
  4201. check_send_queue(pte);
  4202. ast_mutex_unlock(&pte->lock);
  4203. return;
  4204. }
  4205. if (pte->last_seq_ack > seq) {
  4206. if (pte->last_seq_ack == 0xffff) {
  4207. ast_verb(0, "ACK at 0xffff, restarting counter.\n");
  4208. pte->last_seq_ack = 0;
  4209. } else {
  4210. ast_log(LOG_NOTICE,
  4211. "%s Warning : ACK received for an already ACKed packet : #0x%04x we are at #0x%04x\n",
  4212. tmpbuf, (unsigned)seq, (unsigned)pte->last_seq_ack);
  4213. }
  4214. ast_mutex_unlock(&pte->lock);
  4215. return;
  4216. }
  4217. if (pte->seq_server < seq) {
  4218. ast_log(LOG_NOTICE,
  4219. "%s Error : ACK received for a non-existent packet : #0x%04x\n",
  4220. tmpbuf, (unsigned)pte->seq_server);
  4221. ast_mutex_unlock(&pte->lock);
  4222. return;
  4223. }
  4224. if (unistimdebug) {
  4225. ast_verb(0, "%s ACK gap : Received ACK #0x%04x, previous was #0x%04x\n",
  4226. tmpbuf, (unsigned)seq, (unsigned)pte->last_seq_ack);
  4227. }
  4228. pte->last_seq_ack = seq;
  4229. check_send_queue(pte);
  4230. ast_mutex_unlock(&pte->lock);
  4231. return;
  4232. }
  4233. if (buf[4] == 2) {
  4234. if (unistimdebug) {
  4235. ast_verb(0, "Request received\n");
  4236. }
  4237. if (pte->seq_phone == seq) {
  4238. /* Send ACK */
  4239. buf[4] = 1;
  4240. buf[5] = 1;
  4241. send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
  4242. pte->seq_phone++;
  4243. process_request(size, buf, pte);
  4244. return;
  4245. }
  4246. if (pte->seq_phone > seq) {
  4247. ast_log(LOG_NOTICE,
  4248. "%s Warning : received a retransmitted packet : #0x%04x (we are at #0x%04x)\n",
  4249. tmpbuf, (unsigned)seq, (unsigned)pte->seq_phone);
  4250. /* BUG ? pte->device->seq_phone = seq; */
  4251. /* Send ACK */
  4252. buf[4] = 1;
  4253. buf[5] = 1;
  4254. send_raw_client(SIZE_HEADER, buf, addr_from, &pte->sout);
  4255. return;
  4256. }
  4257. ast_log(LOG_NOTICE,
  4258. "%s Warning : we lost a packet : received #0x%04x (we are at #0x%04x)\n",
  4259. tmpbuf, (unsigned)seq, (unsigned)pte->seq_phone);
  4260. return;
  4261. }
  4262. if (buf[4] == 0) {
  4263. ast_log(LOG_NOTICE, "%s Retransmit request for packet #0x%04x\n", tmpbuf, (unsigned)seq);
  4264. if (pte->last_seq_ack > seq) {
  4265. ast_log(LOG_NOTICE,
  4266. "%s Error : received a request for an already ACKed packet : #0x%04x\n",
  4267. tmpbuf, (unsigned)pte->last_seq_ack);
  4268. return;
  4269. }
  4270. if (pte->seq_server < seq) {
  4271. ast_log(LOG_NOTICE,
  4272. "%s Error : received a request for a non-existent packet : #0x%04x\n",
  4273. tmpbuf, (unsigned)pte->seq_server);
  4274. return;
  4275. }
  4276. send_retransmit(pte);
  4277. return;
  4278. }
  4279. ast_log(LOG_NOTICE, "%s Unknown request : got 0x%02hhx expected 0x00,0x01 or 0x02\n", tmpbuf, buf[4]);
  4280. return;
  4281. }
  4282. static struct unistimsession *channel_to_session(struct ast_channel *ast)
  4283. {
  4284. struct unistim_subchannel *sub;
  4285. if (!ast) {
  4286. ast_log(LOG_WARNING, "Unistim callback function called with a null channel\n");
  4287. return NULL;
  4288. }
  4289. if (!ast_channel_tech_pvt(ast)) {
  4290. ast_log(LOG_WARNING, "Unistim callback function called without a tech_pvt\n");
  4291. return NULL;
  4292. }
  4293. sub = ast_channel_tech_pvt(ast);
  4294. if (!sub->parent) {
  4295. ast_log(LOG_WARNING, "Unistim callback function called without a line\n");
  4296. return NULL;
  4297. }
  4298. if (!sub->parent->parent) {
  4299. ast_log(LOG_WARNING, "Unistim callback function called without a device\n");
  4300. return NULL;
  4301. }
  4302. ast_mutex_lock(&sub->parent->parent->lock);
  4303. if (!sub->parent->parent->session) {
  4304. ast_log(LOG_WARNING, "Unistim callback function called without a session\n");
  4305. ast_mutex_unlock(&sub->parent->parent->lock);
  4306. return NULL;
  4307. }
  4308. ast_mutex_unlock(&sub->parent->parent->lock);
  4309. return sub->parent->parent->session;
  4310. }
  4311. static void send_callerid_screen(struct unistimsession *pte, struct unistim_subchannel *sub)
  4312. {
  4313. char *cidname_str;
  4314. char *cidnum_str;
  4315. if (!sub) {
  4316. return;
  4317. }
  4318. if (sub->owner) {
  4319. if (ast_channel_connected(sub->owner)->id.number.valid && ast_channel_connected(sub->owner)->id.number.str) {
  4320. cidnum_str = ast_channel_connected(sub->owner)->id.number.str;
  4321. } else {
  4322. cidnum_str = DEFAULTCALLERID;
  4323. }
  4324. change_callerid(pte, 0, cidnum_str);
  4325. if (strlen(cidnum_str) == 0) {
  4326. cidnum_str = DEFAULTCALLERID;
  4327. }
  4328. if (ast_channel_connected(sub->owner)->id.name.valid && ast_channel_connected(sub->owner)->id.name.str) {
  4329. cidname_str = ast_channel_connected(sub->owner)->id.name.str;
  4330. } else {
  4331. cidname_str = DEFAULTCALLERNAME;
  4332. }
  4333. change_callerid(pte, 1, cidname_str);
  4334. if (strlen(cidname_str) == 0) {
  4335. cidname_str = DEFAULTCALLERNAME;
  4336. }
  4337. if (pte->device->height == 1) {
  4338. char tmpstr[256];
  4339. snprintf(tmpstr, sizeof(tmpstr), "%s %s", cidnum_str, ustmtext(cidname_str, pte));
  4340. send_text(TEXT_LINE0, TEXT_NORMAL, pte, tmpstr);
  4341. } else {
  4342. send_text(TEXT_LINE0, TEXT_NORMAL, pte, cidname_str);
  4343. send_text(TEXT_LINE1, TEXT_NORMAL, pte, ustmtext(cidnum_str, pte));
  4344. }
  4345. }
  4346. }
  4347. /*--- unistim_call: Initiate UNISTIM call from PBX ---*/
  4348. /* used from the dial() application */
  4349. static int unistim_call(struct ast_channel *ast, const char *dest, int timeout)
  4350. {
  4351. int res = 0, i;
  4352. struct unistim_subchannel *sub, *sub_real;
  4353. struct unistimsession *session;
  4354. char ringstyle, ringvolume;
  4355. session = channel_to_session(ast);
  4356. if (!session) {
  4357. ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
  4358. return -1;
  4359. }
  4360. sub = ast_channel_tech_pvt(ast);
  4361. sub_real = get_sub(session->device, SUB_REAL);
  4362. if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
  4363. ast_log(LOG_WARNING, "unistim_call called on %s, neither down nor reserved\n",
  4364. ast_channel_name(ast));
  4365. return -1;
  4366. }
  4367. if (unistimdebug) {
  4368. ast_verb(3, "unistim_call(%s)\n", ast_channel_name(ast));
  4369. }
  4370. session->state = STATE_RINGING;
  4371. send_callerid_screen(session, sub);
  4372. if (ast_strlen_zero(ast_channel_call_forward(ast))) { /* Send ring only if no call forward, otherwise short ring will apear */
  4373. send_text(TEXT_LINE2, TEXT_NORMAL, session, ustmtext("is calling you.", session));
  4374. send_text_status(session, ustmtext("Accept Ignore Hangup", session));
  4375. if (sub_real) {
  4376. ringstyle = session->device->cwstyle;
  4377. ringvolume = session->device->cwvolume;
  4378. } else {
  4379. ringstyle = (sub->ringstyle == -1) ? session->device->ringstyle : sub->ringstyle;
  4380. ringvolume = (sub->ringvolume == -1) ? session->device->ringvolume : sub->ringvolume;
  4381. }
  4382. send_ring(session, ringvolume, ringstyle);
  4383. change_favorite_icon(session, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST);
  4384. /* Send call identification to all */
  4385. for (i = 0; i < FAVNUM; i++) {
  4386. if (!soft_key_visible(session->device, i)) {
  4387. continue;
  4388. }
  4389. if (session->device->ssub[i]) {
  4390. continue;
  4391. }
  4392. if (is_key_line(session->device, i) && !strcmp(sub->parent->name, session->device->sline[i]->name)) {
  4393. if (unistimdebug) {
  4394. ast_verb(0, "Found softkey %d for line %s\n", i, sub->parent->name);
  4395. }
  4396. send_favorite_short(i, FAV_ICON_SPEAKER_ONHOOK_BLACK + FAV_BLINK_FAST, session);
  4397. session->device->ssub[i] = sub;
  4398. }
  4399. }
  4400. }
  4401. ast_setstate(ast, AST_STATE_RINGING);
  4402. ast_queue_control(ast, AST_CONTROL_RINGING);
  4403. return res;
  4404. }
  4405. static int unistim_hangup_clean(struct ast_channel *ast, struct unistim_subchannel *sub) {
  4406. ast_mutex_lock(&sub->lock);
  4407. ast_channel_tech_pvt_set(ast, NULL);
  4408. unistim_set_owner(sub, NULL);
  4409. sub->alreadygone = 0;
  4410. ast_mutex_unlock(&sub->lock);
  4411. if (sub->rtp) {
  4412. if (unistimdebug) {
  4413. ast_verb(0, "Destroying RTP session\n");
  4414. }
  4415. ast_rtp_instance_destroy(sub->rtp);
  4416. sub->rtp = NULL;
  4417. }
  4418. return 0;
  4419. }
  4420. /*--- unistim_hangup: Hangup UNISTIM call */
  4421. static int unistim_hangup(struct ast_channel *ast)
  4422. {
  4423. struct unistim_subchannel *sub = NULL, *sub_real = NULL, *sub_trans = NULL;
  4424. struct unistim_line *l;
  4425. struct unistim_device *d;
  4426. struct unistimsession *s;
  4427. int i,end_call = 1;
  4428. s = channel_to_session(ast);
  4429. sub = ast_channel_tech_pvt(ast);
  4430. l = sub->parent;
  4431. d = l->parent;
  4432. if (!s) {
  4433. ast_debug(1, "Asked to hangup channel not connected\n");
  4434. unistim_hangup_clean(ast, sub);
  4435. return 0;
  4436. }
  4437. if (unistimdebug) {
  4438. ast_verb(0, "unistim_hangup(%s) on %s@%s (STATE_%s)\n", ast_channel_name(ast), l->name, l->parent->name, ptestate_tostr(s->state));
  4439. }
  4440. sub_trans = get_sub(d, SUB_THREEWAY);
  4441. sub_real = get_sub(d, SUB_REAL);
  4442. if (sub_trans && (sub_trans->owner) && (sub->subtype == SUB_REAL)) { /* 3rd party busy or congested and transfer_cancel_step2 does not called */
  4443. if (unistimdebug) {
  4444. ast_verb(0, "Threeway call disconnected, switching to real call\n");
  4445. }
  4446. ast_queue_unhold(sub_trans->owner);
  4447. sub_trans->moh = 0;
  4448. sub_trans->subtype = SUB_REAL;
  4449. swap_subs(sub_trans, sub);
  4450. send_text_status(s, ustmtext(" Transf Hangup", s));
  4451. send_callerid_screen(s, sub_trans);
  4452. unistim_hangup_clean(ast, sub);
  4453. unistim_unalloc_sub(d, sub);
  4454. return 0;
  4455. }
  4456. if (sub_real && (sub_real->owner) && (sub->subtype == SUB_THREEWAY) && (s->state == STATE_CALL)) { /* 3way call cancelled by softkey pressed */
  4457. if (unistimdebug) {
  4458. ast_verb(0, "Real call disconnected, stay in call\n");
  4459. }
  4460. send_text_status(s, ustmtext(" Transf Hangup", s));
  4461. send_callerid_screen(s, sub_real);
  4462. unistim_hangup_clean(ast, sub);
  4463. unistim_unalloc_sub(d, sub);
  4464. return 0;
  4465. }
  4466. if (sub->subtype == SUB_REAL) {
  4467. sub_stop_silence(s, sub);
  4468. } else if (sub->subtype == SUB_RING) {
  4469. send_no_ring(s);
  4470. for (i = 0; i < FAVNUM; i++) {
  4471. if (!soft_key_visible(s->device, i)) {
  4472. continue;
  4473. }
  4474. if (d->ssub[i] != sub) {
  4475. if (d->ssub[i] != NULL) { /* Found other subchannel active other then hangup'ed one */
  4476. end_call = 0;
  4477. }
  4478. continue;
  4479. }
  4480. if (is_key_line(d, i) && !strcmp(l->name, d->sline[i]->name)) {
  4481. send_favorite_short(i, FAV_LINE_ICON, s);
  4482. d->ssub[i] = NULL;
  4483. continue;
  4484. }
  4485. }
  4486. }
  4487. if (end_call) {
  4488. send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */
  4489. }
  4490. sub->moh = 0;
  4491. if (sub->softkey >= 0) {
  4492. send_favorite_short(sub->softkey, FAV_LINE_ICON, s);
  4493. }
  4494. /* Delete assign sub to softkey */
  4495. for (i = 0; i < FAVNUM; i++) {
  4496. if (d->ssub[i] == sub) {
  4497. d->ssub[i] = NULL;
  4498. break;
  4499. }
  4500. }
  4501. /*refresh_all_favorite(s); */ /* TODO: Update favicons in case of DND keys */
  4502. if (s->state == STATE_RINGING && sub->subtype == SUB_RING) {
  4503. send_no_ring(s);
  4504. if (ast_channel_hangupcause(ast) != AST_CAUSE_ANSWERED_ELSEWHERE) {
  4505. d->missed_call++;
  4506. write_history(s, 'i', 1);
  4507. }
  4508. if (!sub_real) {
  4509. show_main_page(s);
  4510. } else { /* hangup on a ringing line: reset status to reflect that we're still on an active call */
  4511. s->state = STATE_CALL;
  4512. send_callerid_screen(s, sub_real);
  4513. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is on-line", s));
  4514. send_text_status(s, ustmtext(" Transf Hangup", s));
  4515. send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, s);
  4516. }
  4517. }
  4518. if (s->state == STATE_CALL && sub->subtype == SUB_REAL) {
  4519. close_call(s);
  4520. }
  4521. sub->softkey = -1;
  4522. unistim_hangup_clean(ast, sub);
  4523. unistim_unalloc_sub(d, sub);
  4524. return 0;
  4525. }
  4526. /*--- unistim_answer: Answer UNISTIM call */
  4527. static int unistim_answer(struct ast_channel *ast)
  4528. {
  4529. int res = 0;
  4530. struct unistim_subchannel *sub;
  4531. struct unistim_line *l;
  4532. struct unistim_device *d;
  4533. struct unistimsession *s;
  4534. s = channel_to_session(ast);
  4535. if (!s) {
  4536. ast_log(LOG_WARNING, "unistim_answer on a disconnected device ?\n");
  4537. return -1;
  4538. }
  4539. sub = ast_channel_tech_pvt(ast);
  4540. l = sub->parent;
  4541. d = l->parent;
  4542. if (unistimdebug) {
  4543. ast_verb(0, "unistim_answer(%s) on %s@%s-%d\n", ast_channel_name(ast), l->name,
  4544. l->parent->name, sub->softkey);
  4545. }
  4546. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("is now on-line", s));
  4547. if (get_sub(d, SUB_THREEWAY)) {
  4548. send_text_status(s, ustmtext("Transf Cancel", s));
  4549. } else {
  4550. send_text_status(s, ustmtext(" Transf Hangup", s));
  4551. }
  4552. send_start_timer(s);
  4553. if (ast_channel_state(ast) != AST_STATE_UP)
  4554. ast_setstate(ast, AST_STATE_UP);
  4555. return res;
  4556. }
  4557. /*--- unistimsock_read: Read data from UNISTIM socket ---*/
  4558. /* Successful messages is connected to UNISTIM call and forwarded to parsing() */
  4559. static int unistimsock_read(int *id, int fd, short events, void *ignore)
  4560. {
  4561. struct sockaddr_in addr_from = { 0, };
  4562. struct unistimsession *cur = NULL;
  4563. int found = 0;
  4564. int tmp = 0;
  4565. int dw_num_bytes_rcvd;
  4566. unsigned int size_addr_from;
  4567. #ifdef DUMP_PACKET
  4568. int dw_num_bytes_rcvdd;
  4569. #endif
  4570. size_addr_from = sizeof(addr_from);
  4571. dw_num_bytes_rcvd =
  4572. recvfrom(unistimsock, buff, SIZE_PAGE, 0, (struct sockaddr *) &addr_from,
  4573. &size_addr_from);
  4574. if (dw_num_bytes_rcvd == -1) {
  4575. if (errno == EAGAIN) {
  4576. ast_log(LOG_NOTICE, "UNISTIM: Received packet with bad UDP checksum\n");
  4577. } else if (errno != ECONNREFUSED) {
  4578. ast_log(LOG_WARNING, "Recv error %d (%s)\n", errno, strerror(errno));
  4579. }
  4580. return 1;
  4581. }
  4582. /* Looking in the phone list if we already have a registration for him */
  4583. ast_mutex_lock(&sessionlock);
  4584. cur = sessions;
  4585. while (cur) {
  4586. if (cur->sin.sin_addr.s_addr == addr_from.sin_addr.s_addr) {
  4587. found = 1;
  4588. break;
  4589. }
  4590. tmp++;
  4591. cur = cur->next;
  4592. }
  4593. ast_mutex_unlock(&sessionlock);
  4594. #ifdef DUMP_PACKET
  4595. if (unistimdebug)
  4596. ast_verb(0, "\n*** Dump %d bytes from %s - phone_table[%d] ***\n",
  4597. dw_num_bytes_rcvd, ast_inet_ntoa(addr_from.sin_addr), tmp);
  4598. for (dw_num_bytes_rcvdd = 0; dw_num_bytes_rcvdd < dw_num_bytes_rcvd;
  4599. dw_num_bytes_rcvdd++)
  4600. ast_verb(0, "%02hhx ", buff[dw_num_bytes_rcvdd]);
  4601. ast_verb(0, "\n******************************************\n");
  4602. #endif
  4603. if (!found) {
  4604. if (unistimdebug) {
  4605. ast_verb(0, "Received a packet from an unknown source\n");
  4606. }
  4607. parsing(dw_num_bytes_rcvd, buff, NULL, (struct sockaddr_in *) &addr_from);
  4608. } else {
  4609. parsing(dw_num_bytes_rcvd, buff, cur, (struct sockaddr_in *) &addr_from);
  4610. }
  4611. return 1;
  4612. }
  4613. static struct ast_frame *unistim_rtp_read(const struct ast_channel *ast,
  4614. const struct unistim_subchannel *sub)
  4615. {
  4616. /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */
  4617. struct ast_frame *f;
  4618. if (!ast) {
  4619. ast_log(LOG_WARNING, "Channel NULL while reading\n");
  4620. return &ast_null_frame;
  4621. }
  4622. if (!sub->rtp) {
  4623. ast_log(LOG_WARNING, "RTP handle NULL while reading on subchannel %u\n",
  4624. sub->subtype);
  4625. return &ast_null_frame;
  4626. }
  4627. switch (ast_channel_fdno(ast)) {
  4628. case 0:
  4629. f = ast_rtp_instance_read(sub->rtp, 0); /* RTP Audio */
  4630. break;
  4631. case 1:
  4632. f = ast_rtp_instance_read(sub->rtp, 1); /* RTCP Control Channel */
  4633. break;
  4634. default:
  4635. f = &ast_null_frame;
  4636. }
  4637. if (sub->owner) {
  4638. /* We already hold the channel lock */
  4639. if (f->frametype == AST_FRAME_VOICE) {
  4640. if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), &f->subclass.format))) {
  4641. char tmp[256];
  4642. ast_debug(1,
  4643. "Oooh, format changed from %s to %s\n",
  4644. ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(sub->owner)),
  4645. ast_getformatname(&f->subclass.format));
  4646. ast_format_cap_set(ast_channel_nativeformats(sub->owner), &f->subclass.format);
  4647. ast_set_read_format(sub->owner, ast_channel_readformat(sub->owner));
  4648. ast_set_write_format(sub->owner, ast_channel_writeformat(sub->owner));
  4649. }
  4650. }
  4651. }
  4652. return f;
  4653. }
  4654. static struct ast_frame *unistim_read(struct ast_channel *ast)
  4655. {
  4656. struct ast_frame *fr;
  4657. struct unistim_subchannel *sub = ast_channel_tech_pvt(ast);
  4658. ast_mutex_lock(&sub->lock);
  4659. fr = unistim_rtp_read(ast, sub);
  4660. ast_mutex_unlock(&sub->lock);
  4661. return fr;
  4662. }
  4663. static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
  4664. {
  4665. struct unistim_subchannel *sub = ast_channel_tech_pvt(ast);
  4666. int res = 0;
  4667. if (frame->frametype != AST_FRAME_VOICE) {
  4668. if (frame->frametype == AST_FRAME_IMAGE) {
  4669. return 0;
  4670. } else {
  4671. ast_log(LOG_WARNING, "Can't send %u type frames with unistim_write\n",
  4672. frame->frametype);
  4673. return 0;
  4674. }
  4675. } else {
  4676. if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
  4677. char tmp[256];
  4678. ast_log(LOG_WARNING,
  4679. "Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
  4680. ast_getformatname(&frame->subclass.format),
  4681. ast_getformatname_multiple(tmp, sizeof(tmp), ast_channel_nativeformats(ast)),
  4682. ast_getformatname(ast_channel_readformat(ast)),
  4683. ast_getformatname(ast_channel_writeformat(ast)));
  4684. return -1;
  4685. }
  4686. }
  4687. if (sub) {
  4688. ast_mutex_lock(&sub->lock);
  4689. if (sub->rtp) {
  4690. res = ast_rtp_instance_write(sub->rtp, frame);
  4691. }
  4692. ast_mutex_unlock(&sub->lock);
  4693. }
  4694. return res;
  4695. }
  4696. static int unistim_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
  4697. {
  4698. struct unistim_subchannel *p = ast_channel_tech_pvt(newchan);
  4699. struct unistim_line *l = p->parent;
  4700. ast_mutex_lock(&p->lock);
  4701. ast_debug(1, "New owner for channel USTM/%s@%s-%u is %s\n", l->name,
  4702. l->parent->name, p->subtype, ast_channel_name(newchan));
  4703. if (p->owner != oldchan) {
  4704. ast_log(LOG_WARNING, "old channel wasn't %s (%p) but was %s (%p)\n",
  4705. ast_channel_name(oldchan), oldchan, ast_channel_name(p->owner), p->owner);
  4706. ast_mutex_unlock(&p->lock);
  4707. return -1;
  4708. }
  4709. unistim_set_owner(p, newchan);
  4710. ast_mutex_unlock(&p->lock);
  4711. return 0;
  4712. }
  4713. static char *control2str(int ind)
  4714. {
  4715. switch (ind) {
  4716. case AST_CONTROL_HANGUP:
  4717. return "Other end has hungup";
  4718. case AST_CONTROL_RING:
  4719. return "Local ring";
  4720. case AST_CONTROL_RINGING:
  4721. return "Remote end is ringing";
  4722. case AST_CONTROL_ANSWER:
  4723. return "Remote end has answered";
  4724. case AST_CONTROL_BUSY:
  4725. return "Remote end is busy";
  4726. case AST_CONTROL_TAKEOFFHOOK:
  4727. return "Make it go off hook";
  4728. case AST_CONTROL_OFFHOOK:
  4729. return "Line is off hook";
  4730. case AST_CONTROL_CONGESTION:
  4731. return "Congestion (circuits busy)";
  4732. case AST_CONTROL_FLASH:
  4733. return "Flash hook";
  4734. case AST_CONTROL_WINK:
  4735. return "Wink";
  4736. case AST_CONTROL_OPTION:
  4737. return "Set a low-level option";
  4738. case AST_CONTROL_RADIO_KEY:
  4739. return "Key Radio";
  4740. case AST_CONTROL_RADIO_UNKEY:
  4741. return "Un-Key Radio";
  4742. case AST_CONTROL_CONNECTED_LINE:
  4743. return "Remote end changed";
  4744. case AST_CONTROL_SRCCHANGE:
  4745. return "RTP source updated";
  4746. case AST_CONTROL_SRCUPDATE:
  4747. return "Source of media changed";
  4748. case -1:
  4749. return "Stop tone";
  4750. }
  4751. return "UNKNOWN";
  4752. }
  4753. static void in_band_indication(struct ast_channel *ast, const struct ast_tone_zone *tz,
  4754. const char *indication)
  4755. {
  4756. struct ast_tone_zone_sound *ts = NULL;
  4757. if ((ts = ast_get_indication_tone(tz, indication))) {
  4758. ast_playtones_start(ast, 0, ts->data, 1);
  4759. ts = ast_tone_zone_sound_unref(ts);
  4760. } else {
  4761. ast_log(LOG_WARNING, "Unable to get indication tone for %s\n", indication);
  4762. }
  4763. }
  4764. static int unistim_indicate(struct ast_channel *ast, int ind, const void *data,
  4765. size_t datalen)
  4766. {
  4767. struct unistim_subchannel *sub;
  4768. struct unistim_line *l;
  4769. struct unistimsession *s;
  4770. if (unistimdebug) {
  4771. ast_verb(3, "Asked to indicate '%s' (%d) condition on channel %s\n",
  4772. control2str(ind), ind, ast_channel_name(ast));
  4773. }
  4774. s = channel_to_session(ast);
  4775. if (!s) {
  4776. return -1;
  4777. }
  4778. sub = ast_channel_tech_pvt(ast);
  4779. l = sub->parent;
  4780. switch (ind) {
  4781. case AST_CONTROL_RINGING:
  4782. if (ast_channel_state(ast) != AST_STATE_UP) {
  4783. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Ringing...", s));
  4784. in_band_indication(ast, l->parent->tz, "ring");
  4785. s->device->missed_call = -1;
  4786. break;
  4787. }
  4788. return -1;
  4789. case AST_CONTROL_BUSY:
  4790. if (ast_channel_state(ast) != AST_STATE_UP) {
  4791. sub->alreadygone = 1;
  4792. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Busy", s));
  4793. in_band_indication(ast, l->parent->tz, "busy");
  4794. s->device->missed_call = -1;
  4795. break;
  4796. }
  4797. return -1;
  4798. case AST_CONTROL_INCOMPLETE:
  4799. /* Overlapped dialing is not currently supported for UNIStim. Treat an indication
  4800. * of incomplete as congestion
  4801. */
  4802. case AST_CONTROL_CONGESTION:
  4803. if (ast_channel_state(ast) != AST_STATE_UP) {
  4804. sub->alreadygone = 1;
  4805. send_text(TEXT_LINE2, TEXT_NORMAL, s, ustmtext("Congestion", s));
  4806. in_band_indication(ast, l->parent->tz, "congestion");
  4807. s->device->missed_call = -1;
  4808. break;
  4809. }
  4810. return -1;
  4811. case AST_CONTROL_HOLD:
  4812. ast_moh_start(ast, data, NULL);
  4813. break;
  4814. case AST_CONTROL_UNHOLD:
  4815. ast_moh_stop(ast);
  4816. break;
  4817. case AST_CONTROL_PROGRESS:
  4818. case AST_CONTROL_SRCUPDATE:
  4819. case AST_CONTROL_PROCEEDING:
  4820. break;
  4821. case -1:
  4822. ast_playtones_stop(ast);
  4823. s->device->missed_call = 0;
  4824. break;
  4825. case AST_CONTROL_CONNECTED_LINE:
  4826. ast_log(LOG_NOTICE, "Connected party is now %s <%s>\n",
  4827. S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
  4828. S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
  4829. if (sub->subtype == SUB_REAL) {
  4830. send_callerid_screen(s, sub);
  4831. }
  4832. case AST_CONTROL_UPDATE_RTP_PEER:
  4833. break;
  4834. case AST_CONTROL_SRCCHANGE:
  4835. if (sub->rtp) {
  4836. ast_rtp_instance_change_source(sub->rtp);
  4837. }
  4838. break;
  4839. default:
  4840. ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
  4841. /* fallthrough */
  4842. case AST_CONTROL_PVT_CAUSE_CODE:
  4843. case AST_CONTROL_MASQUERADE_NOTIFY:
  4844. return -1;
  4845. }
  4846. return 0;
  4847. }
  4848. static struct unistim_subchannel *find_subchannel_by_name(const char *dest)
  4849. {
  4850. struct unistim_line *l;
  4851. struct unistim_device *d;
  4852. struct unistim_subchannel *sub = NULL;
  4853. char line[256];
  4854. char *at;
  4855. char *device;
  4856. ast_copy_string(line, dest, sizeof(line));
  4857. at = strchr(line, '@');
  4858. if (!at) {
  4859. ast_log(LOG_NOTICE, "Device '%s' has no @ (at) sign!\n", dest);
  4860. return NULL;
  4861. }
  4862. *at = '\0';
  4863. at++;
  4864. device = at;
  4865. ast_mutex_lock(&devicelock);
  4866. d = devices;
  4867. at = strchr(device, '/'); /* Extra options ? */
  4868. if (at) {
  4869. *at = '\0';
  4870. }
  4871. while (d) {
  4872. if (!strcasecmp(d->name, device)) {
  4873. if (unistimdebug) {
  4874. ast_verb(0, "Found device: %s\n", d->name);
  4875. }
  4876. /* Found the device */
  4877. AST_LIST_LOCK(&d->lines);
  4878. AST_LIST_TRAVERSE(&d->lines, l, list) {
  4879. /* Search for the right line */
  4880. if (!strcasecmp(l->name, line)) {
  4881. if (unistimdebug) {
  4882. ast_verb(0, "Found line: %s\n", l->name);
  4883. }
  4884. sub = get_sub(d, SUB_REAL);
  4885. if (!sub) {
  4886. sub = unistim_alloc_sub(d, SUB_REAL);
  4887. }
  4888. if (sub->owner) {
  4889. /* Allocate additional channel if asterisk channel already here */
  4890. sub = unistim_alloc_sub(d, SUB_ONHOLD);
  4891. }
  4892. sub->ringvolume = -1;
  4893. sub->ringstyle = -1;
  4894. if (at) { /* Other options ? */
  4895. at++; /* Skip slash */
  4896. if (*at == 'r') { /* distinctive ring */
  4897. at++;
  4898. if ((*at < '0') || (*at > '7')) { /* ring style */
  4899. ast_log(LOG_WARNING, "Invalid ring selection (%s)", at);
  4900. } else {
  4901. char ring_volume = -1;
  4902. char ring_style = *at - '0';
  4903. at++;
  4904. if ((*at >= '0') && (*at <= '3')) { /* ring volume */
  4905. ring_volume = *at - '0';
  4906. }
  4907. if (unistimdebug) {
  4908. ast_verb(0, "Distinctive ring: style #%d volume %d\n",
  4909. ring_style, ring_volume);
  4910. }
  4911. sub->ringvolume = ring_volume;
  4912. sub->ringstyle = ring_style;
  4913. }
  4914. }
  4915. }
  4916. sub->parent = l;
  4917. break;
  4918. }
  4919. }
  4920. AST_LIST_UNLOCK(&d->lines);
  4921. if (sub) {
  4922. ast_mutex_unlock(&devicelock);
  4923. return sub;
  4924. }
  4925. }
  4926. d = d->next;
  4927. }
  4928. /* Device not found */
  4929. ast_mutex_unlock(&devicelock);
  4930. return NULL;
  4931. }
  4932. static int unistim_senddigit_begin(struct ast_channel *ast, char digit)
  4933. {
  4934. struct unistimsession *pte = channel_to_session(ast);
  4935. if (!pte) {
  4936. return -1;
  4937. }
  4938. return unistim_do_senddigit(pte, digit);
  4939. }
  4940. static int unistim_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
  4941. {
  4942. struct unistimsession *pte = channel_to_session(ast);
  4943. struct ast_frame f = { 0, };
  4944. struct unistim_subchannel *sub;
  4945. sub = get_sub(pte->device, SUB_REAL);
  4946. if (!sub || !sub->owner || sub->alreadygone) {
  4947. ast_log(LOG_WARNING, "Unable to find subchannel in dtmf senddigit_end\n");
  4948. return -1;
  4949. }
  4950. if (unistimdebug) {
  4951. ast_verb(0, "Send Digit off %c\n", digit);
  4952. }
  4953. if (!pte) {
  4954. return -1;
  4955. }
  4956. send_tone(pte, 0, 0);
  4957. f.frametype = AST_FRAME_DTMF;
  4958. f.subclass.integer = digit;
  4959. f.src = "unistim";
  4960. ast_queue_frame(sub->owner, &f);
  4961. return 0;
  4962. }
  4963. /*--- unistim_sendtext: Display a text on the phone screen ---*/
  4964. /* Called from PBX core text message functions */
  4965. static int unistim_sendtext(struct ast_channel *ast, const char *text)
  4966. {
  4967. struct unistimsession *pte = channel_to_session(ast);
  4968. int size;
  4969. char tmp[TEXT_LENGTH_MAX + 1];
  4970. if (unistimdebug) {
  4971. ast_verb(0, "unistim_sendtext called\n");
  4972. }
  4973. if (!text) {
  4974. ast_log(LOG_WARNING, "unistim_sendtext called with a null text\n");
  4975. return -1;
  4976. }
  4977. if (!pte) {
  4978. return -1;
  4979. }
  4980. size = strlen(text);
  4981. if (text[0] == '@') {
  4982. int pos = 0, i = 1, tok = 0, sz = 0;
  4983. char label[11];
  4984. char number[16];
  4985. char icon = '\0';
  4986. char cur = '\0';
  4987. memset(label, 0, 11);
  4988. memset(number, 0, 16);
  4989. while (text[i]) {
  4990. cur = text[i++];
  4991. switch (tok) {
  4992. case 0:
  4993. if ((cur < '0') && (cur > '5')) {
  4994. ast_log(LOG_WARNING,
  4995. "sendtext failed : position must be a number beetween 0 and 5\n");
  4996. return 1;
  4997. }
  4998. pos = cur - '0';
  4999. tok = 1;
  5000. continue;
  5001. case 1:
  5002. if (cur != '@') {
  5003. ast_log(LOG_WARNING, "sendtext failed : invalid position\n");
  5004. return 1;
  5005. }
  5006. tok = 2;
  5007. continue;
  5008. case 2:
  5009. if ((cur < '3') && (cur > '6')) {
  5010. ast_log(LOG_WARNING,
  5011. "sendtext failed : icon must be a number beetween 32 and 63 (first digit invalid)\n");
  5012. return 1;
  5013. }
  5014. icon = (cur - '0') * 10;
  5015. tok = 3;
  5016. continue;
  5017. case 3:
  5018. if ((cur < '0') && (cur > '9')) {
  5019. ast_log(LOG_WARNING,
  5020. "sendtext failed : icon must be a number beetween 32 and 63 (second digit invalid)\n");
  5021. return 1;
  5022. }
  5023. icon += (cur - '0');
  5024. tok = 4;
  5025. continue;
  5026. case 4:
  5027. if (cur != '@') {
  5028. ast_log(LOG_WARNING,
  5029. "sendtext failed : icon must be a number beetween 32 and 63 (too many digits)\n");
  5030. return 1;
  5031. }
  5032. tok = 5;
  5033. continue;
  5034. case 5:
  5035. if (cur == '@') {
  5036. tok = 6;
  5037. sz = 0;
  5038. continue;
  5039. }
  5040. if (sz > 10) {
  5041. continue;
  5042. }
  5043. label[sz] = cur;
  5044. sz++;
  5045. continue;
  5046. case 6:
  5047. if (sz > 15) {
  5048. ast_log(LOG_WARNING,
  5049. "sendtext failed : extension too long = %d (15 car max)\n",
  5050. sz);
  5051. return 1;
  5052. }
  5053. number[sz] = cur;
  5054. sz++;
  5055. continue;
  5056. }
  5057. }
  5058. if (tok != 6) {
  5059. ast_log(LOG_WARNING, "sendtext failed : incomplet command\n");
  5060. return 1;
  5061. }
  5062. if (!pte->device) {
  5063. ast_log(LOG_WARNING, "sendtext failed : no device ?\n");
  5064. return 1;
  5065. }
  5066. strcpy(pte->device->softkeylabel[pos], label);
  5067. strcpy(pte->device->softkeynumber[pos], number);
  5068. pte->device->softkeyicon[pos] = icon;
  5069. send_favorite(pos, icon, pte, label);
  5070. return 0;
  5071. }
  5072. if (size <= TEXT_LENGTH_MAX * 2) {
  5073. if (pte->device->height == 1) {
  5074. send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
  5075. } else {
  5076. send_text(TEXT_LINE0, TEXT_NORMAL, pte, ustmtext("Message :", pte));
  5077. send_text(TEXT_LINE1, TEXT_NORMAL, pte, text);
  5078. }
  5079. if (size <= TEXT_LENGTH_MAX) {
  5080. send_text(TEXT_LINE2, TEXT_NORMAL, pte, "");
  5081. return 0;
  5082. }
  5083. memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
  5084. tmp[sizeof(tmp) - 1] = '\0';
  5085. send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
  5086. return 0;
  5087. }
  5088. send_text(TEXT_LINE0, TEXT_NORMAL, pte, text);
  5089. memcpy(tmp, text + TEXT_LENGTH_MAX, TEXT_LENGTH_MAX);
  5090. tmp[sizeof(tmp) - 1] = '\0';
  5091. send_text(TEXT_LINE1, TEXT_NORMAL, pte, tmp);
  5092. memcpy(tmp, text + TEXT_LENGTH_MAX * 2, TEXT_LENGTH_MAX);
  5093. tmp[sizeof(tmp) - 1] = '\0';
  5094. send_text(TEXT_LINE2, TEXT_NORMAL, pte, tmp);
  5095. return 0;
  5096. }
  5097. /*--- unistim_send_mwi_to_peer: Send message waiting indication ---*/
  5098. static int unistim_send_mwi_to_peer(struct unistim_line *peer, unsigned int tick)
  5099. {
  5100. int new;
  5101. RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
  5102. msg = stasis_cache_get(ast_mwi_state_cache(), ast_mwi_state_type(), peer->mailbox);
  5103. if (msg) {
  5104. struct ast_mwi_state *mwi_state = stasis_message_data(msg);
  5105. new = mwi_state->new_msgs;
  5106. } else { /* Fall back on checking the mailbox directly */
  5107. new = ast_app_has_voicemail(peer->mailbox, NULL);
  5108. }
  5109. ast_debug(3, "MWI Status for mailbox %s is %d, lastmsgsent:%d\n",
  5110. peer->mailbox, new, peer->parent->lastmsgssent);
  5111. peer->parent->nextmsgcheck = tick + TIMER_MWI;
  5112. /* Return now if it's the same thing we told them last time */
  5113. if ((peer->parent->session->state != STATE_MAINPAGE) || (new == peer->parent->lastmsgssent)) {
  5114. return 0;
  5115. }
  5116. peer->parent->lastmsgssent = new;
  5117. send_led_update(peer->parent->session, (new > 0));
  5118. return 0;
  5119. }
  5120. /*--- unistim_new: Initiate a call in the UNISTIM channel */
  5121. /* called from unistim_request (calls from the pbx ) */
  5122. static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
  5123. {
  5124. struct ast_channel *tmp;
  5125. struct unistim_line *l;
  5126. struct ast_format tmpfmt;
  5127. if (!sub) {
  5128. ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
  5129. return NULL;
  5130. }
  5131. if (!sub->parent) {
  5132. ast_log(LOG_WARNING, "no line for subchannel %p\n", sub);
  5133. return NULL;
  5134. }
  5135. l = sub->parent;
  5136. tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
  5137. l->parent->context, assignedids, requestor, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
  5138. if (unistimdebug) {
  5139. ast_verb(0, "unistim_new sub=%u (%p) chan=%p line=%s\n", sub->subtype, sub, tmp, l->name);
  5140. }
  5141. if (!tmp) {
  5142. ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
  5143. return NULL;
  5144. }
  5145. ast_channel_stage_snapshot(tmp);
  5146. ast_format_cap_copy(ast_channel_nativeformats(tmp), l->cap);
  5147. if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
  5148. ast_format_cap_copy(ast_channel_nativeformats(tmp), global_cap);
  5149. }
  5150. ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
  5151. if (unistimdebug) {
  5152. char tmp1[256], tmp2[256], tmp3[256];
  5153. ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
  5154. ast_getformatname(&tmpfmt),
  5155. ast_getformatname_multiple(tmp1, sizeof(tmp1), ast_channel_nativeformats(tmp)),
  5156. ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
  5157. ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
  5158. }
  5159. if ((sub->rtp) && (sub->subtype == 0)) {
  5160. if (unistimdebug) {
  5161. ast_verb(0, "New unistim channel with a previous rtp handle ?\n");
  5162. }
  5163. ast_channel_internal_fd_set(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
  5164. ast_channel_internal_fd_set(tmp, 1, ast_rtp_instance_fd(sub->rtp, 1));
  5165. }
  5166. if (sub->rtp) {
  5167. ast_jb_configure(tmp, &global_jbconf);
  5168. }
  5169. /* tmp->type = type; */
  5170. ast_setstate(tmp, state);
  5171. if (state == AST_STATE_RING) {
  5172. ast_channel_rings_set(tmp, 1);
  5173. }
  5174. ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
  5175. ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
  5176. ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
  5177. ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
  5178. ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
  5179. ast_channel_tech_pvt_set(tmp, sub);
  5180. ast_channel_tech_set(tmp, &unistim_tech);
  5181. if (!ast_strlen_zero(l->parent->language)) {
  5182. ast_channel_language_set(tmp, l->parent->language);
  5183. }
  5184. unistim_set_owner(sub, tmp);
  5185. ast_update_use_count();
  5186. ast_channel_callgroup_set(tmp, l->callgroup);
  5187. ast_channel_pickupgroup_set(tmp, l->pickupgroup);
  5188. ast_channel_call_forward_set(tmp, l->parent->call_forward);
  5189. if (!ast_strlen_zero(l->cid_num)) {
  5190. char *name, *loc, *instr;
  5191. instr = ast_strdup(l->cid_num);
  5192. if (instr) {
  5193. ast_callerid_parse(instr, &name, &loc);
  5194. ast_channel_caller(tmp)->id.number.valid = 1;
  5195. ast_free(ast_channel_caller(tmp)->id.number.str);
  5196. ast_channel_caller(tmp)->id.number.str = ast_strdup(loc);
  5197. ast_channel_caller(tmp)->id.name.valid = 1;
  5198. ast_free(ast_channel_caller(tmp)->id.name.str);
  5199. ast_channel_caller(tmp)->id.name.str = ast_strdup(name);
  5200. ast_free(instr);
  5201. }
  5202. }
  5203. ast_channel_priority_set(tmp, 1);
  5204. ast_channel_stage_snapshot_done(tmp);
  5205. ast_channel_unlock(tmp);
  5206. if (state != AST_STATE_DOWN) {
  5207. if (unistimdebug) {
  5208. ast_verb(0, "Starting pbx in unistim_new\n");
  5209. }
  5210. if (ast_pbx_start(tmp)) {
  5211. ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
  5212. ast_hangup(tmp);
  5213. tmp = NULL;
  5214. }
  5215. }
  5216. return tmp;
  5217. }
  5218. static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan)
  5219. {
  5220. sub->owner = chan;
  5221. if (sub->rtp) {
  5222. ast_rtp_instance_set_channel_id(sub->rtp, sub->owner ? ast_channel_uniqueid(sub->owner) : "");
  5223. }
  5224. }
  5225. static void *do_monitor(void *data)
  5226. {
  5227. struct unistimsession *cur = NULL;
  5228. unsigned int dw_timeout = 0;
  5229. unsigned int tick;
  5230. int res;
  5231. int reloading;
  5232. /* Add an I/O event to our UDP socket */
  5233. if (unistimsock > -1) {
  5234. ast_io_add(io, unistimsock, unistimsock_read, AST_IO_IN, NULL);
  5235. }
  5236. /* This thread monitors our UDP socket and timers */
  5237. for (;;) {
  5238. /* This loop is executed at least every IDLE_WAITus (1s) or every time a packet is received */
  5239. /* Looking for the smallest time-out value */
  5240. tick = get_tick_count();
  5241. dw_timeout = UINT_MAX;
  5242. ast_mutex_lock(&sessionlock);
  5243. cur = sessions;
  5244. DEBUG_TIMER("checking timeout for session %p with tick = %u\n", cur, tick);
  5245. while (cur) {
  5246. DEBUG_TIMER("checking timeout for session %p timeout = %u\n", cur,
  5247. cur->timeout);
  5248. /* Check if we have miss something */
  5249. if (cur->timeout <= tick) {
  5250. DEBUG_TIMER("Event for session %p\n", cur);
  5251. /* If the queue is empty, send a ping */
  5252. if (cur->last_buf_available == 0) {
  5253. send_ping(cur);
  5254. } else {
  5255. if (send_retransmit(cur)) {
  5256. DEBUG_TIMER("The chained link was modified, restarting...\n");
  5257. cur = sessions;
  5258. dw_timeout = UINT_MAX;
  5259. continue;
  5260. }
  5261. }
  5262. }
  5263. if (dw_timeout > cur->timeout - tick) {
  5264. dw_timeout = cur->timeout - tick;
  5265. }
  5266. /* Checking if the phone is logged on for a new MWI */
  5267. if (cur->device) {
  5268. struct unistim_line *l;
  5269. AST_LIST_LOCK(&cur->device->lines);
  5270. AST_LIST_TRAVERSE(&cur->device->lines, l, list) {
  5271. if ((!ast_strlen_zero(l->mailbox)) && (tick >= l->parent->nextmsgcheck)) {
  5272. DEBUG_TIMER("Checking mailbox for MWI\n");
  5273. unistim_send_mwi_to_peer(l, tick);
  5274. break;
  5275. }
  5276. }
  5277. AST_LIST_UNLOCK(&cur->device->lines);
  5278. if (cur->device->nextdial && tick >= cur->device->nextdial) {
  5279. handle_call_outgoing(cur);
  5280. cur->device->nextdial = 0;
  5281. }
  5282. }
  5283. cur = cur->next;
  5284. }
  5285. ast_mutex_unlock(&sessionlock);
  5286. DEBUG_TIMER("Waiting for %dus\n", dw_timeout);
  5287. res = dw_timeout;
  5288. /* We should not wait more than IDLE_WAIT */
  5289. if ((res < 0) || (res > IDLE_WAIT)) {
  5290. res = IDLE_WAIT;
  5291. }
  5292. /* Wait for UDP messages for a maximum of res us */
  5293. res = ast_io_wait(io, res); /* This function will call unistimsock_read if a packet is received */
  5294. /* Check for a reload request */
  5295. ast_mutex_lock(&unistim_reload_lock);
  5296. reloading = unistim_reloading;
  5297. unistim_reloading = 0;
  5298. ast_mutex_unlock(&unistim_reload_lock);
  5299. if (reloading) {
  5300. ast_verb(1, "Reloading unistim.conf...\n");
  5301. reload_config();
  5302. }
  5303. pthread_testcancel();
  5304. }
  5305. /* Never reached */
  5306. return NULL;
  5307. }
  5308. /*--- restart_monitor: Start the channel monitor thread ---*/
  5309. static int restart_monitor(void)
  5310. {
  5311. pthread_attr_t attr;
  5312. /* If we're supposed to be stopped -- stay stopped */
  5313. if (monitor_thread == AST_PTHREADT_STOP) {
  5314. return 0;
  5315. }
  5316. if (ast_mutex_lock(&monlock)) {
  5317. ast_log(LOG_WARNING, "Unable to lock monitor\n");
  5318. return -1;
  5319. }
  5320. if (monitor_thread == pthread_self()) {
  5321. ast_mutex_unlock(&monlock);
  5322. ast_log(LOG_WARNING, "Cannot kill myself\n");
  5323. return -1;
  5324. }
  5325. if (monitor_thread != AST_PTHREADT_NULL) {
  5326. /* Wake up the thread */
  5327. pthread_kill(monitor_thread, SIGURG);
  5328. } else {
  5329. pthread_attr_init(&attr);
  5330. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  5331. /* Start a new monitor */
  5332. if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
  5333. ast_mutex_unlock(&monlock);
  5334. ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
  5335. return -1;
  5336. }
  5337. }
  5338. ast_mutex_unlock(&monlock);
  5339. return 0;
  5340. }
  5341. /*--- unistim_request: PBX interface function ---*/
  5342. /* UNISTIM calls initiated by the PBX arrive here */
  5343. static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest,
  5344. int *cause)
  5345. {
  5346. struct unistim_subchannel *sub, *sub_ring, *sub_trans;
  5347. struct unistim_device *d;
  5348. struct ast_channel *tmpc = NULL;
  5349. char tmp[256];
  5350. char tmp2[256];
  5351. if (!(ast_format_cap_has_joint(cap, global_cap))) {
  5352. ast_log(LOG_NOTICE,
  5353. "Asked to get a channel of unsupported format %s while capability is %s\n",
  5354. ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
  5355. return NULL;
  5356. }
  5357. ast_copy_string(tmp, dest, sizeof(tmp));
  5358. if (ast_strlen_zero(tmp)) {
  5359. ast_log(LOG_NOTICE, "Unistim channels require a device\n");
  5360. return NULL;
  5361. }
  5362. sub = find_subchannel_by_name(tmp);
  5363. if (!sub) {
  5364. ast_log(LOG_NOTICE, "No available lines on: %s\n", dest);
  5365. *cause = AST_CAUSE_CONGESTION;
  5366. return NULL;
  5367. }
  5368. d = sub->parent->parent;
  5369. sub_ring = get_sub(d, SUB_RING);
  5370. sub_trans = get_sub(d, SUB_THREEWAY);
  5371. /* Another request already in progress */
  5372. if (!d->session) {
  5373. unistim_unalloc_sub(d, sub);
  5374. *cause = AST_CAUSE_CONGESTION;
  5375. return NULL;
  5376. }
  5377. if (sub_ring || sub_trans) {
  5378. if (unistimdebug) {
  5379. ast_verb(0, "Can't create channel, request already in progress: Busy!\n");
  5380. }
  5381. unistim_unalloc_sub(d, sub);
  5382. *cause = AST_CAUSE_BUSY;
  5383. return NULL;
  5384. }
  5385. if (d->session->state == STATE_DIALPAGE) {
  5386. if (unistimdebug) {
  5387. ast_verb(0, "Can't create channel, user on dialpage: Busy!\n");
  5388. }
  5389. unistim_unalloc_sub(d, sub);
  5390. *cause = AST_CAUSE_BUSY;
  5391. return NULL;
  5392. }
  5393. if (get_avail_softkey(d->session, sub->parent->name) == -1) {
  5394. if (unistimdebug) {
  5395. ast_verb(0, "Can't create channel for line %s, all lines busy\n", sub->parent->name);
  5396. }
  5397. unistim_unalloc_sub(d, sub);
  5398. *cause = AST_CAUSE_BUSY;
  5399. return NULL;
  5400. }
  5401. sub->subtype = SUB_RING;
  5402. sub->softkey = -1;
  5403. ast_format_cap_copy(sub->parent->cap, cap);
  5404. tmpc = unistim_new(sub, AST_STATE_DOWN, assignedids, requestor);
  5405. if (!tmpc) {
  5406. ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
  5407. }
  5408. if (unistimdebug) {
  5409. ast_verb(0, "unistim_request owner = %p\n", sub->owner);
  5410. }
  5411. restart_monitor();
  5412. /* and finish */
  5413. return tmpc;
  5414. }
  5415. static char *unistim_show_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  5416. {
  5417. struct unistim_device *device = devices;
  5418. struct unistim_line *line;
  5419. struct unistim_subchannel *sub;
  5420. struct unistimsession *s;
  5421. switch (cmd) {
  5422. case CLI_INIT:
  5423. e->command = "unistim show info";
  5424. e->usage =
  5425. "Usage: unistim show info\n"
  5426. " Dump internal structures.\n\n"
  5427. " device\n"
  5428. " ->line\n"
  5429. " -->sub\n"
  5430. " ==>key\n";
  5431. return NULL;
  5432. case CLI_GENERATE:
  5433. return NULL; /* no completion */
  5434. }
  5435. if (a->argc != e->args) {
  5436. return CLI_SHOWUSAGE;
  5437. }
  5438. ast_cli(a->fd, "Dumping internal structures:\n");
  5439. ast_mutex_lock(&devicelock);
  5440. while (device) {
  5441. int i;
  5442. ast_cli(a->fd, "\nname=%s id=%s ha=%p sess=%p device=%p selected=%d height=%d\n",
  5443. device->name, device->id, device->ha, device->session,
  5444. device, device->selected, device->height);
  5445. AST_LIST_LOCK(&device->lines);
  5446. AST_LIST_TRAVERSE(&device->lines,line,list) {
  5447. char tmp2[256];
  5448. ast_cli(a->fd,
  5449. "->name=%s fullname=%s exten=%s callid=%s cap=%s line=%p\n",
  5450. line->name, line->fullname, line->exten, line->cid_num,
  5451. ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line);
  5452. }
  5453. AST_LIST_UNLOCK(&device->lines);
  5454. AST_LIST_LOCK(&device->subs);
  5455. AST_LIST_TRAVERSE(&device->subs, sub, list) {
  5456. if (!sub) {
  5457. continue;
  5458. }
  5459. ast_cli(a->fd,
  5460. "-->subtype=%s chan=%p rtp=%p line=%p alreadygone=%d softkey=%d\n",
  5461. subtype_tostr(sub->subtype), sub->owner, sub->rtp, sub->parent,
  5462. sub->alreadygone, sub->softkey);
  5463. }
  5464. AST_LIST_UNLOCK(&device->subs);
  5465. for (i = 0; i < FAVNUM; i++) {
  5466. if (!soft_key_visible(device, i)) {
  5467. continue;
  5468. }
  5469. ast_cli(a->fd, "==> %d. dev=%s icon=%#-4x label=%-10s number=%-5s sub=%p line=%p\n",
  5470. i, device->softkeydevice[i], (unsigned)device->softkeyicon[i], device->softkeylabel[i], device->softkeynumber[i],
  5471. device->ssub[i], device->sline[i]);
  5472. }
  5473. device = device->next;
  5474. }
  5475. ast_mutex_unlock(&devicelock);
  5476. ast_cli(a->fd, "\nSessions:\n");
  5477. ast_mutex_lock(&sessionlock);
  5478. s = sessions;
  5479. while (s) {
  5480. ast_cli(a->fd,
  5481. "sin=%s timeout=%d state=%s macaddr=%s device=%p session=%p\n",
  5482. ast_inet_ntoa(s->sin.sin_addr), s->timeout, ptestate_tostr(s->state), s->macaddr,
  5483. s->device, s);
  5484. s = s->next;
  5485. }
  5486. ast_mutex_unlock(&sessionlock);
  5487. return CLI_SUCCESS;
  5488. }
  5489. static char *unistim_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  5490. {
  5491. struct unistim_device *device = devices;
  5492. switch (cmd) {
  5493. case CLI_INIT:
  5494. e->command = "unistim show devices";
  5495. e->usage =
  5496. "Usage: unistim show devices\n"
  5497. " Lists all known Unistim devices.\n";
  5498. return NULL;
  5499. case CLI_GENERATE:
  5500. return NULL; /* no completion */
  5501. }
  5502. if (a->argc != e->args)
  5503. return CLI_SHOWUSAGE;
  5504. ast_cli(a->fd, "%-20.20s %-20.20s %-15.15s %-15.15s %s\n", "Name/username", "MAC", "Host", "Firmware", "Status");
  5505. ast_mutex_lock(&devicelock);
  5506. while (device) {
  5507. ast_cli(a->fd, "%-20.20s %-20.20s %-15.15s %-15.15s %s\n",
  5508. device->name, device->id,
  5509. (!device->session) ? "(Unspecified)" : ast_inet_ntoa(device->session->sin.sin_addr),
  5510. (!device->session) ? "(Unspecified)" : device->session->firmware,
  5511. (!device->session) ? "UNKNOWN" : "OK");
  5512. device = device->next;
  5513. }
  5514. ast_mutex_unlock(&devicelock);
  5515. return CLI_SUCCESS;
  5516. }
  5517. static char *unistim_sp(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  5518. {
  5519. BUFFSEND;
  5520. struct unistim_subchannel *sub;
  5521. int i, j = 0, len;
  5522. unsigned char c, cc;
  5523. char tmp[256];
  5524. switch (cmd) {
  5525. case CLI_INIT:
  5526. e->command = "unistim send packet";
  5527. e->usage =
  5528. "Usage: unistim send packet USTM/line@name hexa\n"
  5529. " unistim send packet USTM/1000@hans 19040004\n";
  5530. return NULL;
  5531. case CLI_GENERATE:
  5532. return NULL; /* no completion */
  5533. }
  5534. if (a->argc < 5) {
  5535. return CLI_SHOWUSAGE;
  5536. }
  5537. if (strlen(a->argv[3]) < 9) {
  5538. return CLI_SHOWUSAGE;
  5539. }
  5540. len = strlen(a->argv[4]);
  5541. if (len % 2) {
  5542. return CLI_SHOWUSAGE;
  5543. }
  5544. ast_copy_string(tmp, a->argv[3] + 5, sizeof(tmp));
  5545. sub = find_subchannel_by_name(tmp);
  5546. if (!sub) {
  5547. ast_cli(a->fd, "Can't find '%s'\n", tmp);
  5548. return CLI_SUCCESS;
  5549. }
  5550. if (!sub->parent->parent->session) {
  5551. ast_cli(a->fd, "'%s' is not connected\n", tmp);
  5552. return CLI_SUCCESS;
  5553. }
  5554. ast_cli(a->fd, "Sending '%s' to %s (%p)\n", a->argv[4], tmp, sub->parent->parent->session);
  5555. for (i = 0; i < len; i++) {
  5556. c = a->argv[4][i];
  5557. if (c >= 'a') {
  5558. c -= 'a' - 10;
  5559. } else {
  5560. c -= '0';
  5561. }
  5562. i++;
  5563. cc = a->argv[4][i];
  5564. if (cc >= 'a') {
  5565. cc -= 'a' - 10;
  5566. } else {
  5567. cc -= '0';
  5568. }
  5569. tmp[j++] = (c << 4) | cc;
  5570. }
  5571. memcpy(buffsend + SIZE_HEADER, tmp, j);
  5572. send_client(SIZE_HEADER + j, buffsend, sub->parent->parent->session);
  5573. return CLI_SUCCESS;
  5574. }
  5575. static char *unistim_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  5576. {
  5577. switch (cmd) {
  5578. case CLI_INIT:
  5579. e->command = "unistim set debug {on|off}";
  5580. e->usage =
  5581. "Usage: unistim set debug\n"
  5582. " Display debug messages.\n";
  5583. return NULL;
  5584. case CLI_GENERATE:
  5585. return NULL; /* no completion */
  5586. }
  5587. if (a->argc != e->args) {
  5588. return CLI_SHOWUSAGE;
  5589. }
  5590. if (!strcasecmp(a->argv[3], "on")) {
  5591. unistimdebug = 1;
  5592. ast_cli(a->fd, "UNISTIM Debugging Enabled\n");
  5593. } else if (!strcasecmp(a->argv[3], "off")) {
  5594. unistimdebug = 0;
  5595. ast_cli(a->fd, "UNISTIM Debugging Disabled\n");
  5596. } else {
  5597. return CLI_SHOWUSAGE;
  5598. }
  5599. return CLI_SUCCESS;
  5600. }
  5601. /*! \brief --- unistim_reload: Force reload of module from cli ---
  5602. * Runs in the asterisk main thread, so don't do anything useful
  5603. * but setting a flag and waiting for do_monitor to do the job
  5604. * in our thread */
  5605. static char *unistim_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  5606. {
  5607. switch (cmd) {
  5608. case CLI_INIT:
  5609. e->command = "unistim reload";
  5610. e->usage =
  5611. "Usage: unistim reload\n"
  5612. " Reloads UNISTIM configuration from unistim.conf\n";
  5613. return NULL;
  5614. case CLI_GENERATE:
  5615. return NULL; /* no completion */
  5616. }
  5617. if (e && a && a->argc != e->args) {
  5618. return CLI_SHOWUSAGE;
  5619. }
  5620. reload();
  5621. return CLI_SUCCESS;
  5622. }
  5623. static struct ast_cli_entry unistim_cli[] = {
  5624. AST_CLI_DEFINE(unistim_reload, "Reload UNISTIM configuration"),
  5625. AST_CLI_DEFINE(unistim_show_info, "Show UNISTIM info"),
  5626. AST_CLI_DEFINE(unistim_show_devices, "Show UNISTIM devices"),
  5627. AST_CLI_DEFINE(unistim_sp, "Send packet (for reverse engineering)"),
  5628. AST_CLI_DEFINE(unistim_do_debug, "Toggle UNITSTIM debugging"),
  5629. };
  5630. static void unquote(char *out, const char *src, int maxlen)
  5631. {
  5632. int len = strlen(src);
  5633. if (!len) {
  5634. return;
  5635. }
  5636. if ((len > 1) && src[0] == '\"') {
  5637. /* This is a quoted string */
  5638. src++;
  5639. /* Don't take more than what's there */
  5640. len--;
  5641. if (maxlen > len - 1) {
  5642. maxlen = len - 1;
  5643. }
  5644. memcpy(out, src, maxlen);
  5645. ((char *) out)[maxlen] = '\0';
  5646. } else {
  5647. memcpy(out, src, maxlen);
  5648. }
  5649. return;
  5650. }
  5651. static int parse_bookmark(const char *text, struct unistim_device *d)
  5652. {
  5653. char line[256];
  5654. char *at;
  5655. char *number;
  5656. char *icon;
  5657. int p;
  5658. int len = strlen(text);
  5659. ast_copy_string(line, text, sizeof(line));
  5660. /* Position specified ? */
  5661. if ((len > 2) && (line[1] == '@')) {
  5662. p = line[0];
  5663. if ((p >= '0') && (p <= '5')) {
  5664. p -= '0';
  5665. } else {
  5666. ast_log(LOG_WARNING,
  5667. "Invalid position for bookmark : must be between 0 and 5\n");
  5668. return 0;
  5669. }
  5670. if (d->softkeyicon[p] != 0) {
  5671. ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used:\n", p);
  5672. return 0;
  5673. }
  5674. memmove(line, line + 2, sizeof(line) - 2);
  5675. } else {
  5676. /* No position specified, looking for a free slot */
  5677. for (p = 0; p <= 5; p++) {
  5678. if (!d->softkeyicon[p]) {
  5679. break;
  5680. }
  5681. }
  5682. if (p > 5) {
  5683. ast_log(LOG_WARNING, "No more free bookmark position\n");
  5684. return 0;
  5685. }
  5686. }
  5687. at = strchr(line, '@');
  5688. if (!at) {
  5689. ast_log(LOG_NOTICE, "Bookmark entry '%s' has no @ (at) sign!\n", text);
  5690. return 0;
  5691. }
  5692. *at = '\0';
  5693. at++;
  5694. number = at;
  5695. at = strchr(at, '@');
  5696. if (ast_strlen_zero(number)) {
  5697. ast_log(LOG_NOTICE, "Bookmark entry '%s' has no number\n", text);
  5698. return 0;
  5699. }
  5700. if (ast_strlen_zero(line)) {
  5701. ast_log(LOG_NOTICE, "Bookmark entry '%s' has no description\n", text);
  5702. return 0;
  5703. }
  5704. at = strchr(number, '@');
  5705. if (!at) {
  5706. d->softkeyicon[p] = FAV_ICON_SHARP; /* default icon */
  5707. } else {
  5708. *at = '\0';
  5709. at++;
  5710. icon = at;
  5711. if (ast_strlen_zero(icon)) {
  5712. ast_log(LOG_NOTICE, "Bookmark entry '%s' has no icon value\n", text);
  5713. return 0;
  5714. }
  5715. if (strncmp(icon, "USTM/", 5)) {
  5716. d->softkeyicon[p] = atoi(icon);
  5717. } else {
  5718. d->softkeyicon[p] = 1;
  5719. ast_copy_string(d->softkeydevice[p], icon + 5, sizeof(d->softkeydevice[p]));
  5720. }
  5721. }
  5722. ast_copy_string(d->softkeylabel[p], line, sizeof(d->softkeylabel[p]));
  5723. ast_copy_string(d->softkeynumber[p], number, sizeof(d->softkeynumber[p]));
  5724. if (unistimdebug) {
  5725. ast_verb(0, "New bookmark at pos %d label='%s' number='%s' icon=%#x\n",
  5726. p, d->softkeylabel[p], d->softkeynumber[p], (unsigned)d->softkeyicon[p]);
  5727. }
  5728. return 1;
  5729. }
  5730. /* Looking for dynamic icons entries in bookmarks */
  5731. static void finish_bookmark(void)
  5732. {
  5733. struct unistim_device *d = devices;
  5734. int i;
  5735. ast_mutex_lock(&devicelock);
  5736. while (d) {
  5737. for (i = 0; i < 6; i++) {
  5738. if (d->softkeyicon[i] == 1) { /* Something for us */
  5739. struct unistim_device *d2 = devices;
  5740. while (d2) {
  5741. if (!strcmp(d->softkeydevice[i], d2->name)) {
  5742. d->sp[i] = d2;
  5743. d->softkeyicon[i] = 0;
  5744. break;
  5745. }
  5746. d2 = d2->next;
  5747. }
  5748. if (d->sp[i] == NULL) {
  5749. ast_log(LOG_NOTICE, "Bookmark entry with device %s not found\n",
  5750. d->softkeydevice[i]);
  5751. }
  5752. }
  5753. }
  5754. d = d->next;
  5755. }
  5756. ast_mutex_unlock(&devicelock);
  5757. }
  5758. static struct unistim_line *find_line_by_number(struct unistim_device *d, const char *val) {
  5759. struct unistim_line *l, *ret = NULL;
  5760. AST_LIST_LOCK(&d->lines);
  5761. AST_LIST_TRAVERSE(&d->lines, l, list) {
  5762. if (!strcmp(l->name, val)) {
  5763. ret = l;
  5764. break;
  5765. }
  5766. }
  5767. AST_LIST_UNLOCK(&d->lines);
  5768. return ret;
  5769. }
  5770. static struct unistim_device *build_device(const char *cat, const struct ast_variable *v)
  5771. {
  5772. struct unistim_device *d;
  5773. struct unistim_line *l = NULL, *lt = NULL;
  5774. int create = 1;
  5775. int nbsoftkey, dateformat, timeformat, callhistory, sharpdial, linecnt;
  5776. char linelabel[AST_MAX_EXTENSION];
  5777. char ringvolume, ringstyle, cwvolume, cwstyle;
  5778. /* First, we need to know if we already have this name in our list */
  5779. /* Get a lock for the device chained list */
  5780. ast_mutex_lock(&devicelock);
  5781. d = devices;
  5782. while (d) {
  5783. if (!strcmp(d->name, cat)) {
  5784. /* Yep, we alreay have this one */
  5785. if (unistimsock < 0) {
  5786. /* It's a dupe */
  5787. ast_log(LOG_WARNING, "Duplicate entry found (%s), ignoring.\n", cat);
  5788. ast_mutex_unlock(&devicelock);
  5789. return NULL;
  5790. }
  5791. /* we're reloading right now */
  5792. create = 0;
  5793. break;
  5794. }
  5795. d = d->next;
  5796. }
  5797. ast_mutex_unlock(&devicelock);
  5798. if (!(lt = ast_calloc(1, sizeof(*lt)))) {
  5799. return NULL;
  5800. }
  5801. if (create) {
  5802. if (!(d = ast_calloc(1, sizeof(*d)))) {
  5803. return NULL;
  5804. }
  5805. ast_mutex_init(&d->lock);
  5806. ast_copy_string(d->name, cat, sizeof(d->name));
  5807. d->contrast = -1;
  5808. d->output = OUTPUT_HANDSET;
  5809. d->previous_output = OUTPUT_HANDSET;
  5810. d->volume = VOLUME_LOW;
  5811. d->mute = MUTE_OFF;
  5812. d->height = DEFAULTHEIGHT;
  5813. d->selected = -1;
  5814. } else {
  5815. /* Delete existing line information */
  5816. AST_LIST_LOCK(&d->lines);
  5817. AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
  5818. AST_LIST_REMOVE_CURRENT(list);
  5819. unistim_line_destroy(l);
  5820. }
  5821. AST_LIST_TRAVERSE_SAFE_END
  5822. AST_LIST_UNLOCK(&d->lines);
  5823. /* reset bookmarks */
  5824. memset(d->softkeylabel, 0, sizeof(d->softkeylabel));
  5825. memset(d->softkeynumber, 0, sizeof(d->softkeynumber));
  5826. memset(d->softkeyicon, 0, sizeof(d->softkeyicon));
  5827. memset(d->softkeydevice, 0, sizeof(d->softkeydevice));
  5828. memset(d->ssub, 0, sizeof(d->ssub));
  5829. memset(d->sline, 0, sizeof(d->sline));
  5830. memset(d->sp, 0, sizeof(d->sp));
  5831. }
  5832. ast_copy_string(d->context, DEFAULTCONTEXT, sizeof(d->context));
  5833. d->selected = -1;
  5834. d->interdigit_timer = DEFAULT_INTERDIGIT_TIMER;
  5835. linelabel[0] = '\0';
  5836. dateformat = 1;
  5837. timeformat = 1;
  5838. ringvolume = 2;
  5839. cwvolume = 1;
  5840. callhistory = 1;
  5841. sharpdial = 0;
  5842. ringstyle = 3;
  5843. cwstyle = 2;
  5844. nbsoftkey = 0;
  5845. linecnt = 0;
  5846. while (v) {
  5847. if (!strcasecmp(v->name, "rtp_port")) {
  5848. d->rtp_port = atoi(v->value);
  5849. } else if (!strcasecmp(v->name, "rtp_method")) {
  5850. d->rtp_method = atoi(v->value);
  5851. } else if (!strcasecmp(v->name, "status_method")) {
  5852. d->status_method = atoi(v->value);
  5853. } else if (!strcasecmp(v->name, "device")) {
  5854. ast_copy_string(d->id, v->value, sizeof(d->id));
  5855. } else if (!strcasecmp(v->name, "tn")) {
  5856. ast_copy_string(d->extension_number, v->value, sizeof(d->extension_number));
  5857. } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
  5858. d->ha = ast_append_ha(v->name, v->value, d->ha, NULL);
  5859. } else if (!strcasecmp(v->name, "context")) {
  5860. ast_copy_string(d->context, v->value, sizeof(d->context));
  5861. } else if (!strcasecmp(v->name, "maintext0")) {
  5862. unquote(d->maintext0, v->value, sizeof(d->maintext0) - 1);
  5863. } else if (!strcasecmp(v->name, "maintext1")) {
  5864. unquote(d->maintext1, v->value, sizeof(d->maintext1) - 1);
  5865. } else if (!strcasecmp(v->name, "maintext2")) {
  5866. unquote(d->maintext2, v->value, sizeof(d->maintext2) - 1);
  5867. } else if (!strcasecmp(v->name, "titledefault")) {
  5868. unquote(d->titledefault, v->value, sizeof(d->titledefault) - 1);
  5869. } else if (!strcasecmp(v->name, "dateformat")) {
  5870. dateformat = atoi(v->value);
  5871. } else if (!strcasecmp(v->name, "timeformat")) {
  5872. timeformat = atoi(v->value);
  5873. } else if (!strcasecmp(v->name, "contrast")) {
  5874. d->contrast = atoi(v->value);
  5875. if ((d->contrast < 0) || (d->contrast > 15)) {
  5876. ast_log(LOG_WARNING, "contrast must be beetween 0 and 15\n");
  5877. d->contrast = 8;
  5878. }
  5879. } else if (!strcasecmp(v->name, "nat")) {
  5880. d->nat = ast_true(v->value);
  5881. } else if (!strcasecmp(v->name, "ringvolume")) {
  5882. ringvolume = atoi(v->value);
  5883. } else if (!strcasecmp(v->name, "ringstyle")) {
  5884. ringstyle = atoi(v->value);
  5885. } else if (!strcasecmp(v->name, "cwvolume")) {
  5886. cwvolume = atoi(v->value);
  5887. } else if (!strcasecmp(v->name, "cwstyle")) {
  5888. cwstyle = atoi(v->value);
  5889. } else if (!strcasecmp(v->name, "callhistory")) {
  5890. callhistory = atoi(v->value);
  5891. } else if (!strcasecmp(v->name, "sharpdial")) {
  5892. sharpdial = ast_true(v->value) ? 1 : 0;
  5893. } else if (!strcasecmp(v->name, "interdigit_timer")) {
  5894. d->interdigit_timer = atoi(v->value);
  5895. } else if (!strcasecmp(v->name, "callerid")) {
  5896. if (!strcasecmp(v->value, "asreceived")) {
  5897. lt->cid_num[0] = '\0';
  5898. } else {
  5899. ast_copy_string(lt->cid_num, v->value, sizeof(lt->cid_num));
  5900. }
  5901. } else if (!strcasecmp(v->name, "language")) {
  5902. ast_copy_string(d->language, v->value, sizeof(d->language));
  5903. } else if (!strcasecmp(v->name, "country")) {
  5904. ast_copy_string(d->country, v->value, sizeof(d->country));
  5905. } else if (!strcasecmp(v->name, "accountcode")) {
  5906. ast_copy_string(lt->accountcode, v->value, sizeof(lt->accountcode));
  5907. } else if (!strcasecmp(v->name, "amaflags")) {
  5908. int y;
  5909. y = ast_channel_string2amaflag(v->value);
  5910. if (y < 0) {
  5911. ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value,
  5912. v->lineno);
  5913. } else {
  5914. lt->amaflags = y;
  5915. }
  5916. } else if (!strcasecmp(v->name, "musiconhold")) {
  5917. ast_copy_string(lt->musicclass, v->value, sizeof(lt->musicclass));
  5918. } else if (!strcasecmp(v->name, "callgroup")) {
  5919. lt->callgroup = ast_get_group(v->value);
  5920. } else if (!strcasecmp(v->name, "pickupgroup")) {
  5921. lt->pickupgroup = ast_get_group(v->value);
  5922. } else if (!strcasecmp(v->name, "mailbox")) {
  5923. ast_copy_string(lt->mailbox, v->value, sizeof(lt->mailbox));
  5924. } else if (!strcasecmp(v->name, "parkinglot")) {
  5925. ast_copy_string(lt->parkinglot, v->value, sizeof(lt->parkinglot));
  5926. } else if (!strcasecmp(v->name, "linelabel")) {
  5927. unquote(linelabel, v->value, sizeof(linelabel) - 1);
  5928. } else if (!strcasecmp(v->name, "extension")) {
  5929. if (!strcasecmp(v->value, "none")) {
  5930. d->extension = EXTENSION_NONE;
  5931. } else if (!strcasecmp(v->value, "ask")) {
  5932. d->extension = EXTENSION_ASK;
  5933. } else if (!strcasecmp(v->value, "line")) {
  5934. d->extension = EXTENSION_LINE;
  5935. } else {
  5936. ast_log(LOG_WARNING, "Unknown extension option.\n");
  5937. }
  5938. } else if (!strcasecmp(v->name, "bookmark")) {
  5939. if (nbsoftkey > 5) {
  5940. ast_log(LOG_WARNING,
  5941. "More than 6 softkeys defined. Ignoring new entries.\n");
  5942. } else {
  5943. if (parse_bookmark(v->value, d)) {
  5944. nbsoftkey++;
  5945. }
  5946. }
  5947. } else if (!strcasecmp(v->name, "line")) {
  5948. int len = strlen(linelabel);
  5949. int create_line = 0;
  5950. l = find_line_by_number(d, v->value);
  5951. if (!l) { /* If line still not exists */
  5952. if (!(l = unistim_line_alloc())) {
  5953. ast_free(d);
  5954. ast_free(lt);
  5955. return NULL;
  5956. }
  5957. lt->cap = l->cap;
  5958. memcpy(l, lt, sizeof(*l));
  5959. ast_mutex_init(&l->lock);
  5960. create_line = 1;
  5961. }
  5962. d->to_delete = 0;
  5963. /* Set softkey info for new line*/
  5964. d->sline[nbsoftkey] = l;
  5965. d->softkeyicon[nbsoftkey] = FAV_LINE_ICON;
  5966. if (!len) { /* label is undefined ? */
  5967. ast_copy_string(d->softkeylabel[nbsoftkey], v->value, sizeof(d->softkeylabel[nbsoftkey]));
  5968. } else {
  5969. int softkeylinepos = 0;
  5970. if ((len > 2) && (linelabel[1] == '@')) {
  5971. softkeylinepos = linelabel[0];
  5972. if ((softkeylinepos >= '0') && (softkeylinepos <= '5')) {
  5973. softkeylinepos -= '0';
  5974. d->softkeyicon[nbsoftkey] = FAV_ICON_NONE;
  5975. } else {
  5976. ast_log(LOG_WARNING,
  5977. "Invalid position for linelabel : must be between 0 and 5\n");
  5978. }
  5979. ast_copy_string(d->softkeylabel[softkeylinepos], linelabel + 2,
  5980. sizeof(d->softkeylabel[softkeylinepos]));
  5981. d->softkeyicon[softkeylinepos] = FAV_LINE_ICON;
  5982. } else {
  5983. ast_copy_string(d->softkeylabel[nbsoftkey], linelabel,
  5984. sizeof(d->softkeylabel[nbsoftkey]));
  5985. }
  5986. }
  5987. nbsoftkey++;
  5988. if (create_line) {
  5989. ast_copy_string(l->name, v->value, sizeof(l->name));
  5990. snprintf(l->fullname, sizeof(l->fullname), "USTM/%s@%s", l->name, d->name);
  5991. if (!ast_strlen_zero(l->mailbox)) {
  5992. if (unistimdebug) {
  5993. ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
  5994. }
  5995. }
  5996. ast_format_cap_copy(l->cap, global_cap);
  5997. l->parent = d;
  5998. linecnt++;
  5999. AST_LIST_LOCK(&d->lines);
  6000. AST_LIST_INSERT_TAIL(&d->lines, l, list);
  6001. AST_LIST_UNLOCK(&d->lines);
  6002. }
  6003. } else if (!strcasecmp(v->name, "height")) {
  6004. /* Allow the user to lower the expected display lines on the phone
  6005. * For example the Nortel i2001 and i2002 only have one ! */
  6006. d->height = atoi(v->value);
  6007. } else
  6008. ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name,
  6009. v->lineno);
  6010. v = v->next;
  6011. }
  6012. ast_free(lt);
  6013. if (linecnt == 0) {
  6014. ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
  6015. ast_free(d);
  6016. return NULL;
  6017. }
  6018. d->ringvolume = ringvolume;
  6019. d->ringstyle = ringstyle;
  6020. d->cwvolume = cwvolume;
  6021. d->cwstyle = cwstyle;
  6022. d->callhistory = callhistory;
  6023. d->sharp_dial = sharpdial;
  6024. d->tz = ast_get_indication_zone(d->country);
  6025. if ((d->tz == NULL) && !ast_strlen_zero(d->country)) {
  6026. ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
  6027. d->country);
  6028. }
  6029. d->datetimeformat = 56 + (dateformat * 4);
  6030. d->datetimeformat += timeformat;
  6031. if ((autoprovisioning == AUTOPROVISIONING_TN) &&
  6032. (!ast_strlen_zero(d->extension_number))) {
  6033. d->extension = EXTENSION_TN;
  6034. if (!ast_strlen_zero(d->id)) {
  6035. ast_log(LOG_WARNING,
  6036. "tn= and device= can't be used together. Ignoring device= entry\n");
  6037. }
  6038. d->id[0] = 'T'; /* magic : this is a tn entry */
  6039. ast_copy_string((d->id) + 1, d->extension_number, sizeof(d->id) - 1);
  6040. d->extension_number[0] = '\0';
  6041. } else if (ast_strlen_zero(d->id)) {
  6042. if (strcmp(d->name, "template")) {
  6043. ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
  6044. if (d->tz) {
  6045. d->tz = ast_tone_zone_unref(d->tz);
  6046. }
  6047. ast_free(d);
  6048. return NULL;
  6049. } else {
  6050. strcpy(d->id, "000000000000");
  6051. }
  6052. }
  6053. if (!d->rtp_port) {
  6054. d->rtp_port = 10000;
  6055. }
  6056. if (d->contrast == -1) {
  6057. d->contrast = 8;
  6058. }
  6059. if (ast_strlen_zero(d->maintext1)) {
  6060. strcpy(d->maintext1, d->name);
  6061. }
  6062. if (ast_strlen_zero(d->titledefault)) {
  6063. struct ast_tm tm = { 0, };
  6064. struct timeval cur_time = ast_tvnow();
  6065. if ((ast_localtime(&cur_time, &tm, 0)) == 0 || ast_strlen_zero(tm.tm_zone)) {
  6066. ast_log(LOG_WARNING, "Error in ast_localtime()\n");
  6067. ast_copy_string(d->titledefault, "UNISTIM for*", 12);
  6068. } else {
  6069. if (strlen(tm.tm_zone) < 4) {
  6070. strcpy(d->titledefault, "TimeZone ");
  6071. strcat(d->titledefault, tm.tm_zone);
  6072. } else if (strlen(tm.tm_zone) < 9) {
  6073. strcpy(d->titledefault, "TZ ");
  6074. strcat(d->titledefault, tm.tm_zone);
  6075. } else {
  6076. ast_copy_string(d->titledefault, tm.tm_zone, 12);
  6077. }
  6078. }
  6079. }
  6080. /* Update the chained link if it's a new device */
  6081. if (create) {
  6082. ast_mutex_lock(&devicelock);
  6083. d->next = devices;
  6084. devices = d;
  6085. ast_mutex_unlock(&devicelock);
  6086. ast_verb(3, "Added device '%s'\n", d->name);
  6087. } else {
  6088. ast_verb(3, "Device '%s' reloaded\n", d->name);
  6089. }
  6090. return d;
  6091. }
  6092. /*--- reload_config: Re-read unistim.conf config file ---*/
  6093. static int reload_config(void)
  6094. {
  6095. struct ast_config *cfg;
  6096. struct ast_variable *v;
  6097. struct ast_hostent ahp;
  6098. struct hostent *hp;
  6099. struct sockaddr_in bindaddr = { 0, };
  6100. char *config = "unistim.conf";
  6101. char *cat;
  6102. struct unistim_device *d;
  6103. const int reuseFlag = 1;
  6104. struct unistimsession *s;
  6105. struct ast_flags config_flags = { 0, };
  6106. cfg = ast_config_load(config, config_flags);
  6107. /* We *must* have a config file otherwise stop immediately */
  6108. if (!cfg) {
  6109. ast_log(LOG_ERROR, "Unable to load config %s\n", config);
  6110. return -1;
  6111. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  6112. ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
  6113. return -1;
  6114. }
  6115. /* Copy the default jb config over global_jbconf */
  6116. memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
  6117. unistim_keepalive = 120;
  6118. unistim_port = 0;
  6119. v = ast_variable_browse(cfg, "general");
  6120. while (v) {
  6121. /* handle jb conf */
  6122. if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
  6123. continue;
  6124. }
  6125. if (!strcasecmp(v->name, "keepalive")) {
  6126. unistim_keepalive = atoi(v->value);
  6127. } else if (!strcasecmp(v->name, "port")) {
  6128. unistim_port = atoi(v->value);
  6129. } else if (!strcasecmp(v->name, "tos")) {
  6130. if (ast_str2tos(v->value, &qos.tos)) {
  6131. ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
  6132. }
  6133. } else if (!strcasecmp(v->name, "tos_audio")) {
  6134. if (ast_str2tos(v->value, &qos.tos_audio)) {
  6135. ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
  6136. }
  6137. } else if (!strcasecmp(v->name, "cos")) {
  6138. if (ast_str2cos(v->value, &qos.cos)) {
  6139. ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
  6140. }
  6141. } else if (!strcasecmp(v->name, "cos_audio")) {
  6142. if (ast_str2cos(v->value, &qos.cos_audio)) {
  6143. ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
  6144. }
  6145. } else if (!strcasecmp(v->name, "debug")) {
  6146. if (!strcasecmp(v->value, "no")) {
  6147. unistimdebug = 0;
  6148. } else if (!strcasecmp(v->value, "yes")) {
  6149. unistimdebug = 1;
  6150. }
  6151. } else if (!strcasecmp(v->name, "autoprovisioning")) {
  6152. if (!strcasecmp(v->value, "no")) {
  6153. autoprovisioning = AUTOPROVISIONING_NO;
  6154. } else if (!strcasecmp(v->value, "yes")) {
  6155. autoprovisioning = AUTOPROVISIONING_YES;
  6156. } else if (!strcasecmp(v->value, "tn")) {
  6157. autoprovisioning = AUTOPROVISIONING_TN;
  6158. } else {
  6159. ast_log(LOG_WARNING, "Unknown autoprovisioning option.\n");
  6160. }
  6161. } else if (!strcasecmp(v->name, "public_ip")) {
  6162. if (!ast_strlen_zero(v->value)) {
  6163. if (!(hp = ast_gethostbyname(v->value, &ahp))) {
  6164. ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
  6165. } else {
  6166. memcpy(&public_ip.sin_addr, hp->h_addr, sizeof(public_ip.sin_addr));
  6167. public_ip.sin_family = AF_INET;
  6168. }
  6169. }
  6170. }
  6171. v = v->next;
  6172. }
  6173. if ((unistim_keepalive < 10) ||
  6174. (unistim_keepalive >
  6175. 255 - (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000))) {
  6176. ast_log(LOG_ERROR, "keepalive is invalid in %s\n", config);
  6177. ast_config_destroy(cfg);
  6178. return -1;
  6179. }
  6180. packet_send_ping[4] =
  6181. unistim_keepalive + (((NB_MAX_RETRANSMIT + 1) * RETRANSMIT_TIMER) / 1000);
  6182. if ((unistim_port < 1) || (unistim_port > 65535)) {
  6183. ast_log(LOG_ERROR, "port is not set or invalid in %s\n", config);
  6184. ast_config_destroy(cfg);
  6185. return -1;
  6186. }
  6187. unistim_keepalive *= 1000;
  6188. ast_mutex_lock(&devicelock);
  6189. d = devices;
  6190. while (d) {
  6191. if (d->to_delete >= 0) {
  6192. d->to_delete = 1;
  6193. }
  6194. d = d->next;
  6195. }
  6196. ast_mutex_unlock(&devicelock);
  6197. /* load the device sections */
  6198. cat = ast_category_browse(cfg, NULL);
  6199. while (cat) {
  6200. if (strcasecmp(cat, "general")) {
  6201. d = build_device(cat, ast_variable_browse(cfg, cat));
  6202. }
  6203. cat = ast_category_browse(cfg, cat);
  6204. }
  6205. ast_mutex_lock(&devicelock);
  6206. d = devices;
  6207. while (d) {
  6208. if (d->to_delete) {
  6209. struct unistim_line *l;
  6210. struct unistim_subchannel *sub;
  6211. if (unistimdebug) {
  6212. ast_verb(0, "Removing device '%s'\n", d->name);
  6213. }
  6214. AST_LIST_LOCK(&d->subs);
  6215. AST_LIST_TRAVERSE_SAFE_BEGIN(&d->subs, sub, list){
  6216. if (sub->subtype == SUB_REAL) {
  6217. if (!sub) {
  6218. ast_log(LOG_ERROR, "Device '%s' without a subchannel !, aborting\n",
  6219. d->name);
  6220. ast_config_destroy(cfg);
  6221. return 0;
  6222. }
  6223. if (sub->owner) {
  6224. ast_log(LOG_WARNING,
  6225. "Device '%s' was not deleted : a call is in progress. Try again later.\n",
  6226. d->name);
  6227. d = d->next;
  6228. continue;
  6229. }
  6230. }
  6231. if (sub->subtype == SUB_THREEWAY) {
  6232. ast_log(LOG_WARNING,
  6233. "Device '%s' with threeway call subchannels allocated, aborting.\n",
  6234. d->name);
  6235. break;
  6236. }
  6237. AST_LIST_REMOVE_CURRENT(list);
  6238. ast_mutex_destroy(&sub->lock);
  6239. ast_free(sub);
  6240. }
  6241. AST_LIST_TRAVERSE_SAFE_END
  6242. AST_LIST_UNLOCK(&d->subs);
  6243. AST_LIST_LOCK(&d->lines);
  6244. AST_LIST_TRAVERSE_SAFE_BEGIN(&d->lines, l, list){
  6245. AST_LIST_REMOVE_CURRENT(list);
  6246. ast_mutex_destroy(&l->lock);
  6247. unistim_line_destroy(l);
  6248. }
  6249. AST_LIST_TRAVERSE_SAFE_END
  6250. AST_LIST_UNLOCK(&d->lines);
  6251. if (d->session) {
  6252. if (sessions == d->session) {
  6253. sessions = d->session->next;
  6254. } else {
  6255. s = sessions;
  6256. while (s) {
  6257. if (s->next == d->session) {
  6258. s->next = d->session->next;
  6259. break;
  6260. }
  6261. s = s->next;
  6262. }
  6263. }
  6264. ast_mutex_destroy(&d->session->lock);
  6265. ast_free(d->session);
  6266. }
  6267. if (devices == d) {
  6268. devices = d->next;
  6269. } else {
  6270. struct unistim_device *d2 = devices;
  6271. while (d2) {
  6272. if (d2->next == d) {
  6273. d2->next = d->next;
  6274. break;
  6275. }
  6276. d2 = d2->next;
  6277. }
  6278. }
  6279. if (d->tz) {
  6280. d->tz = ast_tone_zone_unref(d->tz);
  6281. }
  6282. ast_mutex_destroy(&d->lock);
  6283. ast_free(d);
  6284. d = devices;
  6285. continue;
  6286. }
  6287. d = d->next;
  6288. }
  6289. finish_bookmark();
  6290. ast_mutex_unlock(&devicelock);
  6291. ast_config_destroy(cfg);
  6292. ast_mutex_lock(&sessionlock);
  6293. s = sessions;
  6294. while (s) {
  6295. if (s->device) {
  6296. refresh_all_favorite(s);
  6297. if (ast_strlen_zero(s->device->language)) {
  6298. struct unistim_languages lang;
  6299. lang = options_languages[find_language(s->device->language)];
  6300. send_charset_update(s, lang.encoding);
  6301. }
  6302. }
  6303. s = s->next;
  6304. }
  6305. ast_mutex_unlock(&sessionlock);
  6306. /* We don't recreate a socket when reloading (locks would be necessary). */
  6307. if (unistimsock > -1) {
  6308. return 0;
  6309. }
  6310. bindaddr.sin_addr.s_addr = INADDR_ANY;
  6311. bindaddr.sin_port = htons(unistim_port);
  6312. bindaddr.sin_family = AF_INET;
  6313. unistimsock = socket(AF_INET, SOCK_DGRAM, 0);
  6314. if (unistimsock < 0) {
  6315. ast_log(LOG_WARNING, "Unable to create UNISTIM socket: %s\n", strerror(errno));
  6316. return -1;
  6317. }
  6318. #ifdef HAVE_PKTINFO
  6319. {
  6320. const int pktinfoFlag = 1;
  6321. setsockopt(unistimsock, IPPROTO_IP, IP_PKTINFO, &pktinfoFlag,
  6322. sizeof(pktinfoFlag));
  6323. }
  6324. #else
  6325. if (public_ip.sin_family == 0) {
  6326. ast_log(LOG_WARNING,
  6327. "Your OS does not support IP_PKTINFO, you must set public_ip.\n");
  6328. unistimsock = -1;
  6329. return -1;
  6330. }
  6331. #endif
  6332. setsockopt(unistimsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuseFlag,
  6333. sizeof(reuseFlag));
  6334. if (bind(unistimsock, (struct sockaddr *) &bindaddr, sizeof(bindaddr)) < 0) {
  6335. ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
  6336. ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port),
  6337. strerror(errno));
  6338. close(unistimsock);
  6339. unistimsock = -1;
  6340. } else {
  6341. ast_verb(2, "UNISTIM Listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), htons(bindaddr.sin_port));
  6342. ast_set_qos(unistimsock, qos.tos, qos.cos, "UNISTIM");
  6343. }
  6344. return 0;
  6345. }
  6346. static enum ast_rtp_glue_result unistim_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
  6347. {
  6348. struct unistim_subchannel *sub = ast_channel_tech_pvt(chan);
  6349. if (!sub) {
  6350. return AST_RTP_GLUE_RESULT_FORBID;
  6351. }
  6352. if (!sub->rtp) {
  6353. return AST_RTP_GLUE_RESULT_FORBID;
  6354. }
  6355. ao2_ref(sub->rtp, +1);
  6356. *instance = sub->rtp;
  6357. return AST_RTP_GLUE_RESULT_LOCAL;
  6358. }
  6359. static int unistim_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
  6360. {
  6361. struct unistim_subchannel *sub;
  6362. struct sockaddr_in them = { 0, };
  6363. struct sockaddr_in us = { 0, };
  6364. if (!rtp) {
  6365. return 0;
  6366. }
  6367. sub = ast_channel_tech_pvt(chan);
  6368. if (!sub) {
  6369. ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
  6370. return -1;
  6371. }
  6372. {
  6373. struct ast_sockaddr tmp;
  6374. ast_rtp_instance_get_remote_address(rtp, &tmp);
  6375. ast_sockaddr_to_sin(&tmp, &them);
  6376. ast_rtp_instance_get_local_address(rtp, &tmp);
  6377. ast_sockaddr_to_sin(&tmp, &us);
  6378. }
  6379. /* TODO: Set rtp on phone in case of direct rtp (not implemented) */
  6380. return 0;
  6381. }
  6382. static struct ast_rtp_glue unistim_rtp_glue = {
  6383. .type = channel_type,
  6384. .get_rtp_info = unistim_get_rtp_peer,
  6385. .update_peer = unistim_set_rtp_peer,
  6386. };
  6387. /*--- load_module: PBX load module - initialization ---*/
  6388. int load_module(void)
  6389. {
  6390. int res;
  6391. struct ast_format tmpfmt;
  6392. if (!(global_cap = ast_format_cap_alloc(0))) {
  6393. goto buff_failed;
  6394. }
  6395. if (!(unistim_tech.capabilities = ast_format_cap_alloc(0))) {
  6396. goto buff_failed;
  6397. }
  6398. ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
  6399. ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
  6400. ast_format_cap_copy(unistim_tech.capabilities, global_cap);
  6401. if (!(buff = ast_malloc(SIZE_PAGE))) {
  6402. goto buff_failed;
  6403. }
  6404. io = io_context_create();
  6405. if (!io) {
  6406. ast_log(LOG_ERROR, "Failed to allocate IO context\n");
  6407. goto io_failed;
  6408. }
  6409. sched = ast_sched_context_create();
  6410. if (!sched) {
  6411. ast_log(LOG_ERROR, "Failed to allocate scheduler context\n");
  6412. goto sched_failed;
  6413. }
  6414. res = reload_config();
  6415. if (res) {
  6416. return AST_MODULE_LOAD_DECLINE;
  6417. }
  6418. /* Make sure we can register our unistim channel type */
  6419. if (ast_channel_register(&unistim_tech)) {
  6420. ast_log(LOG_ERROR, "Unable to register channel type '%s'\n", channel_type);
  6421. goto chanreg_failed;
  6422. }
  6423. ast_rtp_glue_register(&unistim_rtp_glue);
  6424. ast_cli_register_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
  6425. restart_monitor();
  6426. return AST_MODULE_LOAD_SUCCESS;
  6427. chanreg_failed:
  6428. /*! XXX \todo Leaking anything allocated by reload_config() ... */
  6429. ast_sched_context_destroy(sched);
  6430. sched = NULL;
  6431. sched_failed:
  6432. io_context_destroy(io);
  6433. io = NULL;
  6434. io_failed:
  6435. ast_free(buff);
  6436. buff = NULL;
  6437. global_cap = ast_format_cap_destroy(global_cap);
  6438. unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
  6439. buff_failed:
  6440. return AST_MODULE_LOAD_FAILURE;
  6441. }
  6442. static int unload_module(void)
  6443. {
  6444. /* First, take us out of the channel loop */
  6445. if (sched) {
  6446. ast_sched_context_destroy(sched);
  6447. }
  6448. ast_cli_unregister_multiple(unistim_cli, ARRAY_LEN(unistim_cli));
  6449. ast_channel_unregister(&unistim_tech);
  6450. ast_rtp_glue_unregister(&unistim_rtp_glue);
  6451. ast_mutex_lock(&monlock);
  6452. if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
  6453. pthread_cancel(monitor_thread);
  6454. pthread_kill(monitor_thread, SIGURG);
  6455. pthread_join(monitor_thread, NULL);
  6456. }
  6457. monitor_thread = AST_PTHREADT_STOP;
  6458. ast_mutex_unlock(&monlock);
  6459. if (buff) {
  6460. ast_free(buff);
  6461. }
  6462. if (unistimsock > -1) {
  6463. close(unistimsock);
  6464. }
  6465. global_cap = ast_format_cap_destroy(global_cap);
  6466. unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
  6467. return 0;
  6468. }
  6469. /*! reload: Part of Asterisk module interface ---*/
  6470. int reload(void)
  6471. {
  6472. if (unistimdebug) {
  6473. ast_verb(0, "reload unistim\n");
  6474. }
  6475. ast_mutex_lock(&unistim_reload_lock);
  6476. if (!unistim_reloading) {
  6477. unistim_reloading = 1;
  6478. }
  6479. ast_mutex_unlock(&unistim_reload_lock);
  6480. restart_monitor();
  6481. return 0;
  6482. }
  6483. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "UNISTIM Protocol (USTM)",
  6484. .load = load_module,
  6485. .unload = unload_module,
  6486. .reload = reload,
  6487. );