app_osplookup.c 105 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2006, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Open Settlement Protocol (OSP) Applications
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. *
  24. * \extref The OSP Toolkit: http://www.transnexus.com
  25. * \extref OpenSSL http://www.openssl.org
  26. *
  27. * \ingroup applications
  28. */
  29. /*** MODULEINFO
  30. <depend>osptk</depend>
  31. <depend>openssl</depend>
  32. <support_level>extended</support_level>
  33. ***/
  34. #include "asterisk.h"
  35. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  36. #include <osp/osp.h>
  37. #include <osp/osputils.h>
  38. #include <osp/ospb64.h>
  39. #include "asterisk/paths.h"
  40. #include "asterisk/lock.h"
  41. #include "asterisk/config.h"
  42. #include "asterisk/utils.h"
  43. #include "asterisk/causes.h"
  44. #include "asterisk/channel.h"
  45. #include "asterisk/app.h"
  46. #include "asterisk/module.h"
  47. #include "asterisk/pbx.h"
  48. #include "asterisk/cli.h"
  49. #include "asterisk/astosp.h"
  50. /*** DOCUMENTATION
  51. <application name="OSPAuth" language="en_US">
  52. <synopsis>
  53. OSP Authentication.
  54. </synopsis>
  55. <syntax>
  56. <parameter name="provider">
  57. <para>The name of the provider that authenticates the call.</para>
  58. </parameter>
  59. <parameter name="options">
  60. <para>Reserverd.</para>
  61. </parameter>
  62. </syntax>
  63. <description>
  64. <para>Authenticate a call by OSP.</para>
  65. <para>Input variables:</para>
  66. <variablelist>
  67. <variable name="OSPINPEERIP">
  68. <para>The last hop IP address.</para>
  69. </variable>
  70. <variable name="OSPINTOKEN">
  71. <para>The inbound OSP token.</para>
  72. </variable>
  73. </variablelist>
  74. <para>Output variables:</para>
  75. <variablelist>
  76. <variable name="OSPINHANDLE">
  77. <para>The inbound call OSP transaction handle.</para>
  78. </variable>
  79. <variable name="OSPINTIMELIMIT">
  80. <para>The inbound call duration limit in seconds.</para>
  81. </variable>
  82. </variablelist>
  83. <para>This application sets the following channel variable upon completion:</para>
  84. <variablelist>
  85. <variable name="OSPAUTHSTATUS">
  86. <para>The status of OSPAuth attempt as a text string, one of</para>
  87. <value name="SUCCESS" />
  88. <value name="FAILED" />
  89. <value name="ERROR" />
  90. </variable>
  91. </variablelist>
  92. </description>
  93. <see-also>
  94. <ref type="application">OSPLookup</ref>
  95. <ref type="application">OSPNext</ref>
  96. <ref type="application">OSPFinish</ref>
  97. </see-also>
  98. </application>
  99. <application name="OSPLookup" language="en_US">
  100. <synopsis>
  101. Lookup destination by OSP.
  102. </synopsis>
  103. <syntax>
  104. <parameter name="exten" required="true">
  105. <para>The exten of the call.</para>
  106. </parameter>
  107. <parameter name="provider">
  108. <para>The name of the provider that is used to route the call.</para>
  109. </parameter>
  110. <parameter name="options">
  111. <enumlist>
  112. <enum name="h">
  113. <para>generate H323 call id for the outbound call</para>
  114. </enum>
  115. <enum name="s">
  116. <para>generate SIP call id for the outbound call. Have not been implemented</para>
  117. </enum>
  118. <enum name="i">
  119. <para>generate IAX call id for the outbound call. Have not been implemented</para>
  120. </enum>
  121. </enumlist>
  122. </parameter>
  123. </syntax>
  124. <description>
  125. <para>Looks up destination via OSP.</para>
  126. <para>Input variables:</para>
  127. <variablelist>
  128. <variable name="OSPINACTUALSRC">
  129. <para>The actual source device IP address in indirect mode.</para>
  130. </variable>
  131. <variable name="OSPINPEERIP">
  132. <para>The last hop IP address.</para>
  133. </variable>
  134. <variable name="OSPINTECH">
  135. <para>The inbound channel technology for the call.</para>
  136. </variable>
  137. <variable name="OSPINHANDLE">
  138. <para>The inbound call OSP transaction handle.</para>
  139. </variable>
  140. <variable name="OSPINTIMELIMIT">
  141. <para>The inbound call duration limit in seconds.</para>
  142. </variable>
  143. <variable name="OSPINNETWORKID">
  144. <para>The inbound source network ID.</para>
  145. </variable>
  146. <variable name="OSPINNPRN">
  147. <para>The inbound routing number.</para>
  148. </variable>
  149. <variable name="OSPINNPCIC">
  150. <para>The inbound carrier identification code.</para>
  151. </variable>
  152. <variable name="OSPINNPDI">
  153. <para>The inbound number portability database dip indicator.</para>
  154. </variable>
  155. <variable name="OSPINSPID">
  156. <para>The inbound service provider identity.</para>
  157. </variable>
  158. <variable name="OSPINOCN">
  159. <para>The inbound operator company number.</para>
  160. </variable>
  161. <variable name="OSPINSPN">
  162. <para>The inbound service provider name.</para>
  163. </variable>
  164. <variable name="OSPINALTSPN">
  165. <para>The inbound alternate service provider name.</para>
  166. </variable>
  167. <variable name="OSPINMCC">
  168. <para>The inbound mobile country code.</para>
  169. </variable>
  170. <variable name="OSPINMNC">
  171. <para>The inbound mobile network code.</para>
  172. </variable>
  173. <variable name="OSPINTOHOST">
  174. <para>The inbound To header host part.</para>
  175. </variable>
  176. <variable name="OSPINRPIDUSER">
  177. <para>The inbound Remote-Party-ID header user part.</para>
  178. </variable>
  179. <variable name="OSPINPAIUSER">
  180. <para>The inbound P-Asserted-Identify header user part.</para>
  181. </variable>
  182. <variable name="OSPINDIVUSER">
  183. <para>The inbound Diversion header user part.</para>
  184. </variable>
  185. <variable name="OSPINDIVHOST">
  186. <para>The inbound Diversion header host part.</para>
  187. </variable>
  188. <variable name="OSPINPCIUSER">
  189. <para>The inbound P-Charge-Info header user part.</para>
  190. </variable>
  191. <variable name="OSPINCUSTOMINFOn">
  192. <para>The inbound custom information, where <literal>n</literal> is the index beginning with <literal>1</literal>
  193. upto <literal>8</literal>.</para>
  194. </variable>
  195. </variablelist>
  196. <para>Output variables:</para>
  197. <variablelist>
  198. <variable name="OSPOUTHANDLE">
  199. <para>The outbound call OSP transaction handle.</para>
  200. </variable>
  201. <variable name="OSPOUTTECH">
  202. <para>The outbound channel technology for the call.</para>
  203. </variable>
  204. <variable name="OSPDESTINATION">
  205. <para>The outbound destination IP address.</para>
  206. </variable>
  207. <variable name="OSPOUTCALLING">
  208. <para>The outbound calling number.</para>
  209. </variable>
  210. <variable name="OSPOUTCALLED">
  211. <para>The outbound called number.</para>
  212. </variable>
  213. <variable name="OSPOUTNETWORKID">
  214. <para>The outbound destination network ID.</para>
  215. </variable>
  216. <variable name="OSPOUTNPRN">
  217. <para>The outbound routing number.</para>
  218. </variable>
  219. <variable name="OSPOUTNPCIC">
  220. <para>The outbound carrier identification code.</para>
  221. </variable>
  222. <variable name="OSPOUTNPDI">
  223. <para>The outbound number portability database dip indicator.</para>
  224. </variable>
  225. <variable name="OSPOUTSPID">
  226. <para>The outbound service provider identity.</para>
  227. </variable>
  228. <variable name="OSPOUTOCN">
  229. <para>The outbound operator company number.</para>
  230. </variable>
  231. <variable name="OSPOUTSPN">
  232. <para>The outbound service provider name.</para>
  233. </variable>
  234. <variable name="OSPOUTALTSPN">
  235. <para>The outbound alternate service provider name.</para>
  236. </variable>
  237. <variable name="OSPOUTMCC">
  238. <para>The outbound mobile country code.</para>
  239. </variable>
  240. <variable name="OSPOUTMNC">
  241. <para>The outbound mobile network code.</para>
  242. </variable>
  243. <variable name="OSPOUTTOKEN">
  244. <para>The outbound OSP token.</para>
  245. </variable>
  246. <variable name="OSPDESTREMAILS">
  247. <para>The number of remained destinations.</para>
  248. </variable>
  249. <variable name="OSPOUTTIMELIMIT">
  250. <para>The outbound call duration limit in seconds.</para>
  251. </variable>
  252. <variable name="OSPOUTCALLIDTYPES">
  253. <para>The outbound Call-ID types.</para>
  254. </variable>
  255. <variable name="OSPOUTCALLID">
  256. <para>The outbound Call-ID. Only for H.323.</para>
  257. </variable>
  258. <variable name="OSPDIALSTR">
  259. <para>The outbound Dial command string.</para>
  260. </variable>
  261. </variablelist>
  262. <para>This application sets the following channel variable upon completion:</para>
  263. <variablelist>
  264. <variable name="OSPLOOKUPSTATUS">
  265. <para>The status of OSPLookup attempt as a text string, one of</para>
  266. <value name="SUCCESS" />
  267. <value name="FAILED" />
  268. <value name="ERROR" />
  269. </variable>
  270. </variablelist>
  271. </description>
  272. <see-also>
  273. <ref type="application">OSPAuth</ref>
  274. <ref type="application">OSPNext</ref>
  275. <ref type="application">OSPFinish</ref>
  276. </see-also>
  277. </application>
  278. <application name="OSPNext" language="en_US">
  279. <synopsis>
  280. Lookup next destination by OSP.
  281. </synopsis>
  282. <description>
  283. <para>Looks up the next destination via OSP.</para>
  284. <para>Input variables:</para>
  285. <variablelist>
  286. <variable name="OSPINHANDLE">
  287. <para>The inbound call OSP transaction handle.</para>
  288. </variable>
  289. <variable name="OSPOUTHANDLE">
  290. <para>The outbound call OSP transaction handle.</para>
  291. </variable>
  292. <variable name="OSPINTIMELIMIT">
  293. <para>The inbound call duration limit in seconds.</para>
  294. </variable>
  295. <variable name="OSPOUTCALLIDTYPES">
  296. <para>The outbound Call-ID types.</para>
  297. </variable>
  298. <variable name="OSPDESTREMAILS">
  299. <para>The number of remained destinations.</para>
  300. </variable>
  301. </variablelist>
  302. <para>Output variables:</para>
  303. <variablelist>
  304. <variable name="OSPOUTTECH">
  305. <para>The outbound channel technology.</para>
  306. </variable>
  307. <variable name="OSPDESTINATION">
  308. <para>The destination IP address.</para>
  309. </variable>
  310. <variable name="OSPOUTCALLING">
  311. <para>The outbound calling number.</para>
  312. </variable>
  313. <variable name="OSPOUTCALLED">
  314. <para>The outbound called number.</para>
  315. </variable>
  316. <variable name="OSPOUTNETWORKID">
  317. <para>The outbound destination network ID.</para>
  318. </variable>
  319. <variable name="OSPOUTNPRN">
  320. <para>The outbound routing number.</para>
  321. </variable>
  322. <variable name="OSPOUTNPCIC">
  323. <para>The outbound carrier identification code.</para>
  324. </variable>
  325. <variable name="OSPOUTNPDI">
  326. <para>The outbound number portability database dip indicator.</para>
  327. </variable>
  328. <variable name="OSPOUTSPID">
  329. <para>The outbound service provider identity.</para>
  330. </variable>
  331. <variable name="OSPOUTOCN">
  332. <para>The outbound operator company number.</para>
  333. </variable>
  334. <variable name="OSPOUTSPN">
  335. <para>The outbound service provider name.</para>
  336. </variable>
  337. <variable name="OSPOUTALTSPN">
  338. <para>The outbound alternate service provider name.</para>
  339. </variable>
  340. <variable name="OSPOUTMCC">
  341. <para>The outbound mobile country code.</para>
  342. </variable>
  343. <variable name="OSPOUTMNC">
  344. <para>The outbound mobile network code.</para>
  345. </variable>
  346. <variable name="OSPOUTTOKEN">
  347. <para>The outbound OSP token.</para>
  348. </variable>
  349. <variable name="OSPDESTREMAILS">
  350. <para>The number of remained destinations.</para>
  351. </variable>
  352. <variable name="OSPOUTTIMELIMIT">
  353. <para>The outbound call duration limit in seconds.</para>
  354. </variable>
  355. <variable name="OSPOUTCALLID">
  356. <para>The outbound Call-ID. Only for H.323.</para>
  357. </variable>
  358. <variable name="OSPDIALSTR">
  359. <para>The outbound Dial command string.</para>
  360. </variable>
  361. </variablelist>
  362. <para>This application sets the following channel variable upon completion:</para>
  363. <variablelist>
  364. <variable name="OSPNEXTSTATUS">
  365. <para>The status of the OSPNext attempt as a text string, one of</para>
  366. <value name="SUCCESS" />
  367. <value name="FAILED" />
  368. <value name="ERROR" />
  369. </variable>
  370. </variablelist>
  371. </description>
  372. <see-also>
  373. <ref type="application">OSPAuth</ref>
  374. <ref type="application">OSPLookup</ref>
  375. <ref type="application">OSPFinish</ref>
  376. </see-also>
  377. </application>
  378. <application name="OSPFinish" language="en_US">
  379. <synopsis>
  380. Report OSP entry.
  381. </synopsis>
  382. <syntax>
  383. <parameter name="cause">
  384. <para>Hangup cause.</para>
  385. </parameter>
  386. <parameter name="options">
  387. <para>Reserved.</para>
  388. </parameter>
  389. </syntax>
  390. <description>
  391. <para>Report call state.</para>
  392. <para>Input variables:</para>
  393. <variablelist>
  394. <variable name="OSPINHANDLE">
  395. <para>The inbound call OSP transaction handle.</para>
  396. </variable>
  397. <variable name="OSPOUTHANDLE">
  398. <para>The outbound call OSP transaction handle.</para>
  399. </variable>
  400. <variable name="OSPAUTHSTATUS">
  401. <para>The OSPAuth status.</para>
  402. </variable>
  403. <variable name="OSPLOOKUPSTATUS">
  404. <para>The OSPLookup status.</para>
  405. </variable>
  406. <variable name="OSPNEXTSTATUS">
  407. <para>The OSPNext status.</para>
  408. </variable>
  409. <variable name="OSPINAUDIOQOS">
  410. <para>The inbound call leg audio QoS string.</para>
  411. </variable>
  412. <variable name="OSPOUTAUDIOQOS">
  413. <para>The outbound call leg audio QoS string.</para>
  414. </variable>
  415. </variablelist>
  416. <para>This application sets the following channel variable upon completion:</para>
  417. <variablelist>
  418. <variable name="OSPFINISHSTATUS">
  419. <para>The status of the OSPFinish attempt as a text string, one of</para>
  420. <value name="SUCCESS" />
  421. <value name="FAILED" />
  422. <value name="ERROR" />
  423. </variable>
  424. </variablelist>
  425. </description>
  426. <see-also>
  427. <ref type="application">OSPAuth</ref>
  428. <ref type="application">OSPLookup</ref>
  429. <ref type="application">OSPNext</ref>
  430. </see-also>
  431. </application>
  432. ***/
  433. /* OSP Buffer Sizes */
  434. #define OSP_SIZE_INTSTR ((unsigned int)16) /* OSP signed/unsigned int string buffer size */
  435. #define OSP_SIZE_NORSTR ((unsigned int)256) /* OSP normal string buffer size */
  436. #define OSP_SIZE_KEYSTR ((unsigned int)1024) /* OSP certificate string buffer size */
  437. #define OSP_SIZE_TOKSTR ((unsigned int)4096) /* OSP token string buffer size */
  438. #define OSP_SIZE_TECHSTR ((unsigned int)32) /* OSP signed/unsigned int string buffer size */
  439. #define OSP_SIZE_UUID ((unsigned int)16) /* UUID size */
  440. #define OSP_SIZE_UUIDSTR ((unsigned int)36) /* UUID string size */
  441. #define OSP_SIZE_QOSSTR ((unsigned int)1024) /* QoS string buffer size */
  442. /* Call ID Type*/
  443. #define OSP_CALLID_UNDEF ((unsigned int)0) /* Undefined */
  444. #define OSP_CALLID_SIP ((unsigned int)(1 << 0)) /* SIP */
  445. #define OSP_CALLID_H323 ((unsigned int)(1 << 1)) /* H.323 */
  446. #define OSP_CALLID_IAX ((unsigned int)(1 << 2)) /* IAX2 */
  447. #define OSP_CALLID_MAXNUM ((unsigned int)3) /* Max number of call ID types */
  448. /* OSP Supported Destination Protocols */
  449. #define OSP_PROT_SIP ((const char*)"SIP") /* SIP protocol name */
  450. #define OSP_PROT_H323 ((const char*)"H323") /* H.323 Q.931 protocol name*/
  451. #define OSP_PROT_IAX ((const char*)"IAX") /* IAX2 protocol name */
  452. #define OSP_PROT_SKYPE ((const char*)"SKYPE") /* Skype protocol name */
  453. /* OSP supported Destination Tech */
  454. #define OSP_TECH_SIP ((const char*)"SIP") /* SIP tech name */
  455. #define OSP_TECH_H323 ((const char*)"H323") /* OH323 tech name */
  456. #define OSP_TECH_IAX ((const char*)"IAX2") /* IAX2 tech name */
  457. #define OSP_TECH_SKYPE ((const char*)"SKYPE") /* Skype tech name */
  458. /* SIP OSP header field name */
  459. #define OSP_SIP_HEADER ((const char*)"P-OSP-Auth-Token")
  460. /* OSP Authentication Policy */
  461. enum osp_authpolicy {
  462. OSP_AUTH_NO = 0, /* Accept any call */
  463. OSP_AUTH_YES, /* Accept call with valid OSP token or without OSP token */
  464. OSP_AUTH_EXC /* Only accept call with valid OSP token */
  465. };
  466. /* OSP Work Mode */
  467. enum osp_workmode {
  468. OSP_MODE_DIRECT= 0, /* Direct */
  469. OSP_MODE_INDIRECT /* Indirect */
  470. };
  471. /* OSP Service Type */
  472. enum osp_srvtype {
  473. OSP_SRV_VOICE = 0, /* Normal voice service */
  474. OSP_SRV_NPQUERY /* Ported number query service */
  475. };
  476. /* OSP Constants */
  477. #define OSP_OK ((int)1) /* OSP function call successful */
  478. #define OSP_FAILED ((int)0) /* OSP function call failed */
  479. #define OSP_ERROR ((int)-1) /* OSP function call error */
  480. #define OSP_AST_OK ((int)0) /* Asterisk function call successful */
  481. #define OSP_AST_ERROR ((int)-1) /* Asterisk function call error */
  482. #define OSP_INVALID_HANDLE ((int)-1) /* Invalid OSP handle, provider, transaction etc. */
  483. #define OSP_CONFIG_FILE ((const char*)"osp.conf") /* OSP configuration file name */
  484. #define OSP_GENERAL_CAT ((const char*)"general") /* OSP global configuration context name */
  485. #define OSP_DEF_PROVIDER ((const char*)"default") /* OSP default provider context name */
  486. #define OSP_MAX_CERTS ((unsigned int)10) /* OSP max number of cacerts */
  487. #define OSP_MAX_SPOINTS ((unsigned int)10) /* OSP max number of service points */
  488. #define OSP_DEF_MAXCONNECT ((unsigned int)20) /* OSP default max_connections */
  489. #define OSP_MIN_MAXCONNECT ((unsigned int)1) /* OSP min max_connections */
  490. #define OSP_MAX_MAXCONNECT ((unsigned int)1000) /* OSP max max_connections */
  491. #define OSP_DEF_RETRYDELAY ((unsigned int)0) /* OSP default retry delay */
  492. #define OSP_MIN_RETRYDELAY ((unsigned int)0) /* OSP min retry delay */
  493. #define OSP_MAX_RETRYDELAY ((unsigned int)10) /* OSP max retry delay */
  494. #define OSP_DEF_RETRYLIMIT ((unsigned int)2) /* OSP default retry times */
  495. #define OSP_MIN_RETRYLIMIT ((unsigned int)0) /* OSP min retry times */
  496. #define OSP_MAX_RETRYLIMIT ((unsigned int)100) /* OSP max retry times */
  497. #define OSP_DEF_TIMEOUT ((unsigned int)500) /* OSP default timeout in ms */
  498. #define OSP_MIN_TIMEOUT ((unsigned int)200) /* OSP min timeout in ms */
  499. #define OSP_MAX_TIMEOUT ((unsigned int)10000) /* OSP max timeout in ms */
  500. #define OSP_DEF_AUTHPOLICY OSP_AUTH_YES /* OSP default auth policy, yes */
  501. #define OSP_AUDIT_URL ((const char*)"localhost") /* OSP default Audit URL */
  502. #define OSP_LOCAL_VALIDATION ((int)1) /* Validate OSP token locally */
  503. #define OSP_SSL_LIFETIME ((unsigned int)300) /* SSL life time, in seconds */
  504. #define OSP_HTTP_PERSISTENCE ((int)1) /* In seconds */
  505. #define OSP_CUSTOMER_ID ((const char*)"") /* OSP customer ID */
  506. #define OSP_DEVICE_ID ((const char*)"") /* OSP device ID */
  507. #define OSP_DEF_MAXDESTS ((unsigned int)12) /* OSP default max number of destinations */
  508. #define OSP_DEF_TIMELIMIT ((unsigned int)0) /* OSP default duration limit, no limit */
  509. #define OSP_DEF_PROTOCOL OSP_PROT_SIP /* OSP default signaling protocol, SIP */
  510. #define OSP_DEF_WORKMODE OSP_MODE_DIRECT /* OSP default work mode, direct */
  511. #define OSP_DEF_SRVTYPE OSP_SRV_VOICE /* OSP default service type, voice */
  512. #define OSP_MAX_CUSTOMINFO ((unsigned int)8) /* OSP max number of custom info */
  513. #define OSP_DEF_INTSTATS ((int)-1) /* OSP default int statistic */
  514. #define OSP_DEF_FLOATSTATS ((float)-1) /* OSP default float statistic */
  515. /* OSP Provider */
  516. struct osp_provider {
  517. OSPTPROVHANDLE handle; /* OSP provider handle */
  518. char name[OSP_SIZE_NORSTR]; /* OSP provider context name */
  519. char privatekey[OSP_SIZE_NORSTR]; /* OSP private key file name */
  520. char localcert[OSP_SIZE_NORSTR]; /* OSP local cert file name */
  521. unsigned int canum; /* Number of cacerts */
  522. char cacerts[OSP_MAX_CERTS][OSP_SIZE_NORSTR]; /* Cacert file names */
  523. unsigned int spnum; /* Number of service points */
  524. char spoints[OSP_MAX_SPOINTS][OSP_SIZE_NORSTR]; /* Service point URLs */
  525. unsigned int maxconnect; /* Max number of connections */
  526. unsigned int retrydelay; /* Retry delay */
  527. unsigned int retrylimit; /* Retry limit */
  528. unsigned int timeout; /* Timeout in ms */
  529. char source[OSP_SIZE_NORSTR]; /* IP of self */
  530. enum osp_authpolicy authpolicy; /* OSP authentication policy */
  531. const char* defprotocol; /* OSP default signaling protocol */
  532. enum osp_workmode workmode; /* OSP work mode */
  533. enum osp_srvtype srvtype; /* OSP service type */
  534. struct osp_provider* next; /* Pointer to next OSP provider */
  535. };
  536. /* Call ID */
  537. struct osp_callid {
  538. unsigned char buf[OSP_SIZE_NORSTR]; /* Call ID string */
  539. unsigned int len; /* Call ID length */
  540. };
  541. /* Number Portability Data */
  542. struct osp_npdata {
  543. const char* rn; /* Rounding Number */
  544. const char* cic; /* Carrier Identification Code */
  545. int npdi; /* NP Database Dip Indicator */
  546. const char* opname[OSPC_OPNAME_NUMBER]; /* Operator Names */
  547. };
  548. /* SIP Header Parameters */
  549. struct osp_headers {
  550. const char* rpiduser; /* Remote-Party-ID header user info */
  551. const char* paiuser; /* P-Asserted-Identity header user info */
  552. const char* divuser; /* Diversion header user info */
  553. const char* divhost; /* Diversion header host info */
  554. const char* pciuser; /* P-Charge-Info header user info */
  555. };
  556. /* OSP Application In/Output Results */
  557. struct osp_results {
  558. int inhandle; /* Inbound transaction handle */
  559. int outhandle; /* Outbound transaction handle */
  560. unsigned int intimelimit; /* Inbound duration limit */
  561. unsigned int outtimelimit; /* Outbound duration limit */
  562. char intech[OSP_SIZE_TECHSTR]; /* Inbound Asterisk TECH string */
  563. char outtech[OSP_SIZE_TECHSTR]; /* Outbound Asterisk TECH string */
  564. char dest[OSP_SIZE_NORSTR]; /* Outbound destination IP address */
  565. char calling[OSP_SIZE_NORSTR]; /* Outbound calling number, may be translated */
  566. char called[OSP_SIZE_NORSTR]; /* Outbound called number, may be translated */
  567. char token[OSP_SIZE_TOKSTR]; /* Outbound OSP token */
  568. char networkid[OSP_SIZE_NORSTR]; /* Outbound network ID */
  569. char nprn[OSP_SIZE_NORSTR]; /* Outbound NP routing number */
  570. char npcic[OSP_SIZE_NORSTR]; /* Outbound NP carrier identification code */
  571. int npdi; /* Outbound NP database dip indicator */
  572. char opname[OSPC_OPNAME_NUMBER][OSP_SIZE_NORSTR]; /* Outbound Operator names */
  573. unsigned int numdests; /* Number of remain outbound destinations */
  574. struct osp_callid outcallid; /* Outbound call ID */
  575. };
  576. /* OSP Call Leg */
  577. enum osp_callleg {
  578. OSP_CALL_INBOUND, /* Inbound call leg */
  579. OSP_CALL_OUTBOUND /* Outbound call leg */
  580. };
  581. /* OSP Media Stream Direction */
  582. enum osp_direction {
  583. OSP_DIR_RX = 0, /* Receive */
  584. OSP_DIR_TX, /* Send */
  585. OSP_DIR_NUMBER /* Number of directions */
  586. };
  587. /* OSP Metrics */
  588. struct osp_metrics {
  589. int value; /* Value */
  590. float min; /* Minimum */
  591. float max; /* Maximum */
  592. float avg; /* Average */
  593. float sdev; /* Standard deviation */
  594. };
  595. /* OSP Module Global Variables */
  596. AST_MUTEX_DEFINE_STATIC(osp_lock); /* Lock of OSP provider list */
  597. static int osp_initialized = 0; /* Init flag */
  598. static int osp_hardware = 0; /* Hardware acceleration flag */
  599. static int osp_security = 0; /* Using security features flag */
  600. static struct osp_provider* osp_providers = NULL; /* OSP provider list */
  601. static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED; /* Token format supported */
  602. /* OSP default certificates */
  603. const char* B64PKey = "MIIBOgIBAAJBAK8t5l+PUbTC4lvwlNxV5lpl+2dwSZGW46dowTe6y133XyVEwNiiRma2YNk3xKs/TJ3Wl9Wpns2SYEAJsFfSTukCAwEAAQJAPz13vCm2GmZ8Zyp74usTxLCqSJZNyMRLHQWBM0g44Iuy4wE3vpi7Wq+xYuSOH2mu4OddnxswCP4QhaXVQavTAQIhAOBVCKXtppEw9UaOBL4vW0Ed/6EA/1D8hDW6St0h7EXJAiEAx+iRmZKhJD6VT84dtX5ZYNVk3j3dAcIOovpzUj9a0CECIEduTCapmZQ5xqAEsLXuVlxRtQgLTUD4ZxDElPn8x0MhAiBE2HlcND0+qDbvtwJQQOUzDgqg5xk3w8capboVdzAlQQIhAMC+lDL7+gDYkNAft5Mu+NObJmQs4Cr+DkDFsKqoxqrm";
  604. const char* B64LCert = "MIIBeTCCASMCEHqkOHVRRWr+1COq3CR/xsowDQYJKoZIhvcNAQEEBQAwOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMB4XDTA1MDYyMzAwMjkxOFoXDTA2MDYyNDAwMjkxOFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCvLeZfj1G0wuJb8JTcVeZaZftncEmRluOnaME3ustd918lRMDYokZmtmDZN8SrP0yd1pfVqZ7NkmBACbBX0k7pAgMBAAEwDQYJKoZIhvcNAQEEBQADQQDnV8QNFVVJx/+7IselU0wsepqMurivXZzuxOmTEmTVDzCJx1xhA8jd3vGAj7XDIYiPub1PV23eY5a2ARJuw5w9";
  605. const char* B64CACert = "MIIBYDCCAQoCAQEwDQYJKoZIhvcNAQEEBQAwOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMB4XDTAyMDIwNDE4MjU1MloXDTEyMDIwMzE4MjU1MlowOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPGeGwV41EIhX0jEDFLRXQhDEr50OUQPq+f55VwQd0TQNts06BP29+UiNdRW3c3IRHdZcJdC1Cg68ME9cgeq0h8CAwEAATANBgkqhkiG9w0BAQQFAANBAGkzBSj1EnnmUxbaiG1N4xjIuLAWydun7o3bFk2tV8dBIhnuh445obYyk1EnQ27kI7eACCILBZqi2MHDOIMnoN0=";
  606. /* OSP Client Wrapper APIs */
  607. /*!
  608. * \brief Create OSP provider handle according to configuration
  609. * \param cfg OSP configuration
  610. * \param name OSP provider context name
  611. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  612. */
  613. static int osp_create_provider(
  614. struct ast_config* cfg,
  615. const char* name)
  616. {
  617. int res = OSP_FAILED;
  618. struct ast_variable* var;
  619. struct osp_provider* provider;
  620. OSPTPRIVATEKEY privatekey;
  621. OSPT_CERT localcert;
  622. OSPT_CERT cacerts[OSP_MAX_CERTS];
  623. const OSPT_CERT* pcacerts[OSP_MAX_CERTS];
  624. const char* pspoints[OSP_MAX_SPOINTS];
  625. unsigned char privatekeydata[OSP_SIZE_KEYSTR];
  626. unsigned char localcertdata[OSP_SIZE_KEYSTR];
  627. unsigned char cacertdata[OSP_SIZE_KEYSTR];
  628. int i, num, error = OSPC_ERR_NO_ERROR;
  629. if (!(provider = ast_calloc(1, sizeof(*provider)))) {
  630. ast_log(LOG_ERROR, "Out of memory\n");
  631. return OSP_ERROR;
  632. }
  633. /* ast_calloc has set 0 in provider */
  634. provider->handle = OSP_INVALID_HANDLE;
  635. ast_copy_string(provider->name, name, sizeof(provider->name));
  636. snprintf(provider->privatekey, sizeof(provider->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, name);
  637. snprintf(provider->localcert, sizeof(provider->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, name);
  638. snprintf(provider->cacerts[0], sizeof(provider->cacerts[0]), "%s/%s-cacert_0.pem", ast_config_AST_KEY_DIR, name);
  639. provider->maxconnect = OSP_DEF_MAXCONNECT;
  640. provider->retrydelay = OSP_DEF_RETRYDELAY;
  641. provider->retrylimit = OSP_DEF_RETRYLIMIT;
  642. provider->timeout = OSP_DEF_TIMEOUT;
  643. provider->authpolicy = OSP_DEF_AUTHPOLICY;
  644. provider->defprotocol = OSP_DEF_PROTOCOL;
  645. provider->workmode = OSP_DEF_WORKMODE;
  646. provider->srvtype = OSP_DEF_SRVTYPE;
  647. for (var = ast_variable_browse(cfg, name); var != NULL; var = var->next) {
  648. if (!strcasecmp(var->name, "privatekey")) {
  649. if (osp_security) {
  650. if (var->value[0] == '/') {
  651. ast_copy_string(provider->privatekey, var->value, sizeof(provider->privatekey));
  652. } else {
  653. snprintf(provider->privatekey, sizeof(provider->privatekey), "%s/%s", ast_config_AST_KEY_DIR, var->value);
  654. }
  655. ast_debug(1, "OSP: privatekey '%s'\n", provider->privatekey);
  656. }
  657. } else if (!strcasecmp(var->name, "localcert")) {
  658. if (osp_security) {
  659. if (var->value[0] == '/') {
  660. ast_copy_string(provider->localcert, var->value, sizeof(provider->localcert));
  661. } else {
  662. snprintf(provider->localcert, sizeof(provider->localcert), "%s/%s", ast_config_AST_KEY_DIR, var->value);
  663. }
  664. ast_debug(1, "OSP: localcert '%s'\n", provider->localcert);
  665. }
  666. } else if (!strcasecmp(var->name, "cacert")) {
  667. if (osp_security) {
  668. if (provider->canum < OSP_MAX_CERTS) {
  669. if (var->value[0] == '/') {
  670. ast_copy_string(provider->cacerts[provider->canum], var->value, sizeof(provider->cacerts[provider->canum]));
  671. } else {
  672. snprintf(provider->cacerts[provider->canum], sizeof(provider->cacerts[provider->canum]), "%s/%s", ast_config_AST_KEY_DIR, var->value);
  673. }
  674. ast_debug(1, "OSP: cacerts[%d]: '%s'\n", provider->canum, provider->cacerts[provider->canum]);
  675. provider->canum++;
  676. } else {
  677. ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", var->lineno);
  678. }
  679. }
  680. } else if (!strcasecmp(var->name, "servicepoint")) {
  681. if (provider->spnum < OSP_MAX_SPOINTS) {
  682. ast_copy_string(provider->spoints[provider->spnum], var->value, sizeof(provider->spoints[provider->spnum]));
  683. ast_debug(1, "OSP: servicepoint[%d]: '%s'\n", provider->spnum, provider->spoints[provider->spnum]);
  684. provider->spnum++;
  685. } else {
  686. ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", var->lineno);
  687. }
  688. } else if (!strcasecmp(var->name, "maxconnect")) {
  689. if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_MAXCONNECT) && (num <= OSP_MAX_MAXCONNECT)) {
  690. provider->maxconnect = num;
  691. ast_debug(1, "OSP: maxconnect '%d'\n", num);
  692. } else {
  693. ast_log(LOG_WARNING, "OSP: maxconnect should be an integer from %d to %d, not '%s' at line %d\n",
  694. OSP_MIN_MAXCONNECT, OSP_MAX_MAXCONNECT, var->value, var->lineno);
  695. }
  696. } else if (!strcasecmp(var->name, "retrydelay")) {
  697. if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_RETRYDELAY) && (num <= OSP_MAX_RETRYDELAY)) {
  698. provider->retrydelay = num;
  699. ast_debug(1, "OSP: retrydelay '%d'\n", num);
  700. } else {
  701. ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
  702. OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, var->value, var->lineno);
  703. }
  704. } else if (!strcasecmp(var->name, "retrylimit")) {
  705. if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_RETRYLIMIT) && (num <= OSP_MAX_RETRYLIMIT)) {
  706. provider->retrylimit = num;
  707. ast_debug(1, "OSP: retrylimit '%d'\n", num);
  708. } else {
  709. ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
  710. OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, var->value, var->lineno);
  711. }
  712. } else if (!strcasecmp(var->name, "timeout")) {
  713. if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_TIMEOUT) && (num <= OSP_MAX_TIMEOUT)) {
  714. provider->timeout = num;
  715. ast_debug(1, "OSP: timeout '%d'\n", num);
  716. } else {
  717. ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
  718. OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, var->value, var->lineno);
  719. }
  720. } else if (!strcasecmp(var->name, "source")) {
  721. ast_copy_string(provider->source, var->value, sizeof(provider->source));
  722. ast_debug(1, "OSP: source '%s'\n", provider->source);
  723. } else if (!strcasecmp(var->name, "authpolicy")) {
  724. if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_AUTH_NO) || (num == OSP_AUTH_YES) || (num == OSP_AUTH_EXC))) {
  725. provider->authpolicy = num;
  726. ast_debug(1, "OSP: authpolicy '%d'\n", num);
  727. } else {
  728. ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
  729. OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXC, var->value, var->lineno);
  730. }
  731. } else if (!strcasecmp(var->name, "defprotocol")) {
  732. if (!strcasecmp(var->value, OSP_PROT_SIP)) {
  733. provider->defprotocol = OSP_PROT_SIP;
  734. ast_debug(1, "OSP: default protocol SIP\n");
  735. } else if (!strcasecmp(var->value, OSP_PROT_H323)) {
  736. provider->defprotocol = OSP_PROT_H323;
  737. ast_debug(1, "OSP: default protocol H.323\n");
  738. } else if (!strcasecmp(var->value, OSP_PROT_IAX)) {
  739. provider->defprotocol = OSP_PROT_IAX;
  740. ast_debug(1, "OSP: default protocol IAX\n");
  741. } else if (!strcasecmp(var->value, OSP_PROT_SKYPE)) {
  742. provider->defprotocol = OSP_PROT_SKYPE;
  743. ast_debug(1, "OSP: default protocol Skype\n");
  744. } else {
  745. ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s or %s not '%s' at line %d\n",
  746. OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_SKYPE, var->value, var->lineno);
  747. }
  748. } else if (!strcasecmp(var->name, "workmode")) {
  749. if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_MODE_DIRECT) || (num == OSP_MODE_INDIRECT))) {
  750. provider->workmode = num;
  751. ast_debug(1, "OSP: workmode '%d'\n", num);
  752. } else {
  753. ast_log(LOG_WARNING, "OSP: workmode should be %d or %d, not '%s' at line %d\n",
  754. OSP_MODE_DIRECT, OSP_MODE_INDIRECT, var->value, var->lineno);
  755. }
  756. } else if (!strcasecmp(var->name, "servicetype")) {
  757. if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_SRV_VOICE) || (num == OSP_SRV_NPQUERY))) {
  758. provider->srvtype = num;
  759. ast_debug(1, "OSP: servicetype '%d'\n", num);
  760. } else {
  761. ast_log(LOG_WARNING, "OSP: servicetype should be %d or %d, not '%s' at line %d\n",
  762. OSP_SRV_VOICE, OSP_SRV_NPQUERY, var->value, var->lineno);
  763. }
  764. }
  765. }
  766. if (provider->canum == 0) {
  767. provider->canum = 1;
  768. }
  769. for (i = 0; i < provider->spnum; i++) {
  770. pspoints[i] = provider->spoints[i];
  771. }
  772. if (osp_security) {
  773. privatekey.PrivateKeyData = NULL;
  774. privatekey.PrivateKeyLength = 0;
  775. localcert.CertData = NULL;
  776. localcert.CertDataLength = 0;
  777. for (i = 0; i < provider->canum; i++) {
  778. cacerts[i].CertData = NULL;
  779. cacerts[i].CertDataLength = 0;
  780. }
  781. if ((error = OSPPUtilLoadPEMPrivateKey((unsigned char*)provider->privatekey, &privatekey)) != OSPC_ERR_NO_ERROR) {
  782. ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", provider->privatekey, error);
  783. } else if ((error = OSPPUtilLoadPEMCert((unsigned char*)provider->localcert, &localcert)) != OSPC_ERR_NO_ERROR) {
  784. ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", provider->localcert, error);
  785. } else {
  786. for (i = 0; i < provider->canum; i++) {
  787. if ((error = OSPPUtilLoadPEMCert((unsigned char*)provider->cacerts[i], &cacerts[i])) != OSPC_ERR_NO_ERROR) {
  788. ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", provider->cacerts[i], error);
  789. break;
  790. } else {
  791. pcacerts[i] = &cacerts[i];
  792. }
  793. }
  794. }
  795. } else {
  796. privatekey.PrivateKeyData = privatekeydata;
  797. privatekey.PrivateKeyLength = sizeof(privatekeydata);
  798. localcert.CertData = localcertdata;
  799. localcert.CertDataLength = sizeof(localcertdata);
  800. cacerts[0].CertData = cacertdata;
  801. cacerts[0].CertDataLength = sizeof(cacertdata);
  802. pcacerts[0] = &cacerts[0];
  803. if ((error = OSPPBase64Decode(B64PKey, strlen(B64PKey), privatekey.PrivateKeyData, &privatekey.PrivateKeyLength)) != OSPC_ERR_NO_ERROR) {
  804. ast_log(LOG_WARNING, "OSP: Unable to decode private key, error '%d'\n", error);
  805. } else if ((error = OSPPBase64Decode(B64LCert, strlen(B64LCert), localcert.CertData, &localcert.CertDataLength)) != OSPC_ERR_NO_ERROR) {
  806. ast_log(LOG_WARNING, "OSP: Unable to decode local cert, error '%d'\n", error);
  807. } else if ((error = OSPPBase64Decode(B64CACert, strlen(B64CACert), cacerts[0].CertData, &cacerts[0].CertDataLength)) != OSPC_ERR_NO_ERROR) {
  808. ast_log(LOG_WARNING, "OSP: Unable to decode cacert, error '%d'\n", error);
  809. }
  810. }
  811. if (error == OSPC_ERR_NO_ERROR) {
  812. error = OSPPProviderNew(provider->spnum,
  813. pspoints,
  814. NULL,
  815. OSP_AUDIT_URL,
  816. &privatekey,
  817. &localcert,
  818. provider->canum,
  819. pcacerts,
  820. OSP_LOCAL_VALIDATION,
  821. OSP_SSL_LIFETIME,
  822. provider->maxconnect,
  823. OSP_HTTP_PERSISTENCE,
  824. provider->retrydelay,
  825. provider->retrylimit,
  826. provider->timeout,
  827. OSP_CUSTOMER_ID,
  828. OSP_DEVICE_ID,
  829. &provider->handle);
  830. if (error != OSPC_ERR_NO_ERROR) {
  831. ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", name, error);
  832. res = OSP_ERROR;
  833. } else {
  834. ast_debug(1, "OSP: provider '%s'\n", name);
  835. ast_mutex_lock(&osp_lock);
  836. provider->next = osp_providers;
  837. osp_providers = provider;
  838. ast_mutex_unlock(&osp_lock);
  839. res = OSP_OK;
  840. }
  841. }
  842. if (osp_security) {
  843. for (i = 0; i < provider->canum; i++) {
  844. if (cacerts[i].CertData) {
  845. ast_free(cacerts[i].CertData);
  846. }
  847. }
  848. if (localcert.CertData) {
  849. ast_free(localcert.CertData);
  850. }
  851. if (privatekey.PrivateKeyData) {
  852. ast_free(privatekey.PrivateKeyData);
  853. }
  854. }
  855. if (res != OSP_OK) {
  856. ast_free(provider);
  857. }
  858. return res;
  859. }
  860. /*!
  861. * \brief Get OSP provider by name
  862. * \param name OSP provider context name
  863. * \param provider OSP provider structure
  864. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  865. */
  866. static int osp_get_provider(
  867. const char* name,
  868. struct osp_provider** provider)
  869. {
  870. int res = OSP_FAILED;
  871. struct osp_provider* p;
  872. *provider = NULL;
  873. ast_mutex_lock(&osp_lock);
  874. for (p = osp_providers; p != NULL; p = p->next) {
  875. if (!strcasecmp(p->name, name)) {
  876. *provider = p;
  877. ast_debug(1, "OSP: find provider '%s'\n", name);
  878. res = OSP_OK;
  879. break;
  880. }
  881. }
  882. ast_mutex_unlock(&osp_lock);
  883. return res;
  884. }
  885. /*!
  886. * \brief Create OSP transaction handle
  887. * \param name OSP provider context name
  888. * \param trans OSP transaction handle, output
  889. * \param source Source of provider, output
  890. * \param srcsize Size of source buffer, in
  891. * \return OSK_OK Success, OSK_FAILED Failed, OSP_ERROR Error
  892. */
  893. static int osp_create_transaction(
  894. const char* name,
  895. int* trans,
  896. char* source,
  897. unsigned int srcsize)
  898. {
  899. int res = OSP_FAILED;
  900. struct osp_provider* provider;
  901. int error;
  902. if ((trans == NULL) || (source == NULL) || (srcsize <= 0)) {
  903. ast_log(LOG_ERROR, "Invalid parameters\n");
  904. return OSP_ERROR;
  905. }
  906. *trans = OSP_INVALID_HANDLE;
  907. *source = '\0';
  908. ast_mutex_lock(&osp_lock);
  909. for (provider = osp_providers; provider; provider = provider->next) {
  910. if (!strcasecmp(provider->name, name)) {
  911. error = OSPPTransactionNew(provider->handle, trans);
  912. if (error == OSPC_ERR_NO_ERROR) {
  913. ast_debug(1, "OSP: transaction '%d'\n", *trans);
  914. ast_copy_string(source, provider->source, srcsize);
  915. ast_debug(1, "OSP: source '%s'\n", source);
  916. res = OSP_OK;
  917. } else {
  918. *trans = OSP_INVALID_HANDLE;
  919. ast_debug(1, "OSP: Unable to create transaction handle, error '%d'\n", error);
  920. *source = '\0';
  921. res = OSP_ERROR;
  922. }
  923. break;
  924. }
  925. }
  926. ast_mutex_unlock(&osp_lock);
  927. return res;
  928. }
  929. /*!
  930. * \brief Convert "address:port" to "[x.x.x.x]:port" or "hostname:port" format
  931. * \param src Source address string
  932. * \param dest Destination address string
  933. * \param destsize Size of dest buffer
  934. */
  935. static void osp_convert_inout(
  936. const char* src,
  937. char* dest,
  938. unsigned int destsize)
  939. {
  940. struct in_addr inp;
  941. char buffer[OSP_SIZE_NORSTR];
  942. char* port;
  943. if ((dest != NULL) && (destsize > 0)) {
  944. if (!ast_strlen_zero(src)) {
  945. ast_copy_string(buffer, src, sizeof(buffer));
  946. if((port = strchr(buffer, ':')) != NULL) {
  947. *port = '\0';
  948. port++;
  949. }
  950. if (inet_pton(AF_INET, buffer, &inp) == 1) {
  951. if (port != NULL) {
  952. snprintf(dest, destsize, "[%s]:%s", buffer, port);
  953. } else {
  954. snprintf(dest, destsize, "[%s]", buffer);
  955. }
  956. dest[destsize - 1] = '\0';
  957. } else {
  958. ast_copy_string(dest, src, destsize);
  959. }
  960. } else {
  961. *dest = '\0';
  962. }
  963. }
  964. }
  965. /*!
  966. * \brief Convert "[x.x.x.x]:port" or "hostname:prot" to "address:port" format
  967. * \param src Source address string
  968. * \param dest Destination address string
  969. * \param destsize Size of dest buffer
  970. */
  971. static void osp_convert_outin(
  972. const char* src,
  973. char* dest,
  974. unsigned int destsize)
  975. {
  976. char buffer[OSP_SIZE_NORSTR];
  977. char* end;
  978. char* port;
  979. if ((dest != NULL) && (destsize > 0)) {
  980. if (!ast_strlen_zero(src)) {
  981. ast_copy_string(buffer, src, sizeof(buffer));
  982. if (buffer[0] == '[') {
  983. if((port = strchr(buffer + 1, ':')) != NULL) {
  984. *port = '\0';
  985. port++;
  986. }
  987. if ((end = strchr(buffer + 1, ']')) != NULL) {
  988. *end = '\0';
  989. }
  990. if (port != NULL) {
  991. snprintf(dest, destsize, "%s:%s", buffer + 1, port);
  992. dest[destsize - 1] = '\0';
  993. } else {
  994. ast_copy_string(dest, buffer + 1, destsize);
  995. }
  996. } else {
  997. ast_copy_string(dest, src, destsize);
  998. }
  999. } else {
  1000. *dest = '\0';
  1001. }
  1002. }
  1003. }
  1004. /*!
  1005. * \brief Validate OSP token of inbound call
  1006. * \param trans OSP transaction handle
  1007. * \param source Source of inbound call
  1008. * \param destination Destination of inbound call
  1009. * \param calling Calling number
  1010. * \param called Called number
  1011. * \param token OSP token, may be empty
  1012. * \param timelimit Call duration limit, output
  1013. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  1014. */
  1015. static int osp_validate_token(
  1016. int trans,
  1017. const char* source,
  1018. const char* destination,
  1019. const char* calling,
  1020. const char* called,
  1021. const char* token,
  1022. unsigned int* timelimit)
  1023. {
  1024. int res;
  1025. int tokenlen;
  1026. unsigned char tokenstr[OSP_SIZE_TOKSTR];
  1027. char src[OSP_SIZE_NORSTR];
  1028. char dest[OSP_SIZE_NORSTR];
  1029. unsigned int authorised;
  1030. unsigned int dummy = 0;
  1031. int error;
  1032. if (timelimit == NULL) {
  1033. ast_log(LOG_ERROR, "Invalid parameters\n");
  1034. return OSP_ERROR;
  1035. }
  1036. tokenlen = ast_base64decode(tokenstr, token, strlen(token));
  1037. osp_convert_inout(source, src, sizeof(src));
  1038. osp_convert_inout(destination, dest, sizeof(dest));
  1039. error = OSPPTransactionValidateAuthorisation(trans,
  1040. src,
  1041. dest,
  1042. NULL,
  1043. NULL,
  1044. calling ? calling : "",
  1045. OSPC_NFORMAT_E164,
  1046. called,
  1047. OSPC_NFORMAT_E164,
  1048. 0,
  1049. NULL,
  1050. tokenlen,
  1051. (char*)tokenstr,
  1052. &authorised,
  1053. timelimit,
  1054. &dummy,
  1055. NULL,
  1056. osp_tokenformat);
  1057. if (error != OSPC_ERR_NO_ERROR) {
  1058. ast_log(LOG_WARNING, "OSP: Unable to validate inbound token, error '%d'\n", error);
  1059. *timelimit = 0;
  1060. res = OSP_ERROR;
  1061. } else if (authorised) {
  1062. ast_debug(1, "OSP: Authorised\n");
  1063. res = OSP_OK;
  1064. } else {
  1065. ast_debug(1, "OSP: Unauthorised\n");
  1066. res = OSP_FAILED;
  1067. }
  1068. return res;
  1069. }
  1070. /*!
  1071. * \brief Choose min duration limit
  1072. * \param in Inbound duration limit
  1073. * \param out Outbound duration limit
  1074. * \return min duration limit
  1075. */
  1076. static unsigned int osp_choose_timelimit(
  1077. unsigned int in,
  1078. unsigned int out)
  1079. {
  1080. if (in == OSP_DEF_TIMELIMIT) {
  1081. return out;
  1082. } else if (out == OSP_DEF_TIMELIMIT) {
  1083. return in;
  1084. } else {
  1085. return in < out ? in : out;
  1086. }
  1087. }
  1088. /*!
  1089. * \brief Choose min duration limit
  1090. * \param provider OSP provider
  1091. * \param calling Calling number
  1092. * \param called Called number
  1093. * \param destination Destination IP in '[x.x.x.x]' format
  1094. * \param tokenlen OSP token length
  1095. * \param token OSP token
  1096. * \param reason Failure reason, output
  1097. * \param results OSP lookup results, in/output
  1098. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  1099. */
  1100. static int osp_check_destination(
  1101. struct osp_provider* provider,
  1102. const char* calling,
  1103. const char* called,
  1104. const char* destination,
  1105. unsigned int tokenlen,
  1106. const char* token,
  1107. OSPEFAILREASON* reason,
  1108. struct osp_results* results)
  1109. {
  1110. int res;
  1111. OSPE_DEST_OSPENABLED enabled;
  1112. OSPE_PROTOCOL_NAME protocol;
  1113. char dest[OSP_SIZE_NORSTR];
  1114. OSPE_OPERATOR_NAME type;
  1115. int error;
  1116. if ((provider == NULL) || (reason == NULL) || (results == NULL)) {
  1117. ast_log(LOG_ERROR, "Invalid parameters\n");
  1118. return OSP_ERROR;
  1119. }
  1120. if ((error = OSPPTransactionIsDestOSPEnabled(results->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
  1121. ast_debug(1, "OSP: Unable to get destination OSP version, error '%d'\n", error);
  1122. *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
  1123. return OSP_ERROR;
  1124. }
  1125. if (enabled == OSPC_DOSP_FALSE) {
  1126. results->token[0] = '\0';
  1127. } else {
  1128. ast_base64encode(results->token, (const unsigned char*)token, tokenlen, sizeof(results->token) - 1);
  1129. }
  1130. if ((error = OSPPTransactionGetDestinationNetworkId(results->outhandle, sizeof(results->networkid), results->networkid)) != OSPC_ERR_NO_ERROR) {
  1131. ast_debug(1, "OSP: Unable to get destination network ID, error '%d'\n", error);
  1132. results->networkid[0] = '\0';
  1133. }
  1134. error = OSPPTransactionGetNumberPortabilityParameters(results->outhandle,
  1135. sizeof(results->nprn),
  1136. results->nprn,
  1137. sizeof(results->npcic),
  1138. results->npcic,
  1139. &results->npdi);
  1140. if (error != OSPC_ERR_NO_ERROR) {
  1141. ast_debug(1, "OSP: Unable to get number portability parameters, error '%d'\n", error);
  1142. results->nprn[0] = '\0';
  1143. results->npcic[0] = '\0';
  1144. results->npdi = 0;
  1145. }
  1146. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1147. error = OSPPTransactionGetOperatorName(results->outhandle, type, sizeof(results->opname[type]), results->opname[type]);
  1148. if (error != OSPC_ERR_NO_ERROR) {
  1149. ast_debug(1, "OSP: Unable to get operator name of type '%d', error '%d'\n", type, error);
  1150. results->opname[type][0] = '\0';
  1151. }
  1152. }
  1153. if ((error = OSPPTransactionGetDestProtocol(results->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
  1154. ast_debug(1, "OSP: Unable to get destination protocol, error '%d'\n", error);
  1155. *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
  1156. results->token[0] = '\0';
  1157. results->networkid[0] = '\0';
  1158. results->nprn[0] = '\0';
  1159. results->npcic[0] = '\0';
  1160. results->npdi = 0;
  1161. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1162. results->opname[type][0] = '\0';
  1163. }
  1164. return OSP_ERROR;
  1165. }
  1166. res = OSP_OK;
  1167. osp_convert_outin(destination, dest, sizeof(dest));
  1168. switch(protocol) {
  1169. case OSPC_PROTNAME_SIP:
  1170. ast_debug(1, "OSP: protocol SIP\n");
  1171. ast_copy_string(results->outtech, OSP_TECH_SIP, sizeof(results->outtech));
  1172. ast_copy_string(results->dest, dest, sizeof(results->dest));
  1173. ast_copy_string(results->calling, calling, sizeof(results->calling));
  1174. ast_copy_string(results->called, called, sizeof(results->called));
  1175. break;
  1176. case OSPC_PROTNAME_Q931:
  1177. ast_debug(1, "OSP: protocol Q.931\n");
  1178. ast_copy_string(results->outtech, OSP_TECH_H323, sizeof(results->outtech));
  1179. ast_copy_string(results->dest, dest, sizeof(results->dest));
  1180. ast_copy_string(results->calling, calling, sizeof(results->calling));
  1181. ast_copy_string(results->called, called, sizeof(results->called));
  1182. break;
  1183. case OSPC_PROTNAME_IAX:
  1184. ast_debug(1, "OSP: protocol IAX\n");
  1185. ast_copy_string(results->outtech, OSP_TECH_IAX, sizeof(results->outtech));
  1186. ast_copy_string(results->dest, dest, sizeof(results->dest));
  1187. ast_copy_string(results->calling, calling, sizeof(results->calling));
  1188. ast_copy_string(results->called, called, sizeof(results->called));
  1189. break;
  1190. case OSPC_PROTNAME_SKYPE:
  1191. ast_debug(1, "OSP: protocol Skype\n");
  1192. ast_copy_string(results->outtech, OSP_TECH_SKYPE, sizeof(results->outtech));
  1193. ast_copy_string(results->dest, dest, sizeof(results->dest));
  1194. ast_copy_string(results->calling, calling, sizeof(results->calling));
  1195. ast_copy_string(results->called, called, sizeof(results->called));
  1196. break;
  1197. case OSPC_PROTNAME_UNDEFINED:
  1198. case OSPC_PROTNAME_UNKNOWN:
  1199. ast_debug(1, "OSP: unknown/undefined protocol '%d'\n", protocol);
  1200. ast_debug(1, "OSP: use default protocol '%s'\n", provider->defprotocol);
  1201. ast_copy_string(results->outtech, provider->defprotocol, sizeof(results->outtech));
  1202. ast_copy_string(results->dest, dest, sizeof(results->dest));
  1203. ast_copy_string(results->calling, calling, sizeof(results->calling));
  1204. ast_copy_string(results->called, called, sizeof(results->called));
  1205. break;
  1206. case OSPC_PROTNAME_LRQ:
  1207. case OSPC_PROTNAME_T37:
  1208. case OSPC_PROTNAME_T38:
  1209. case OSPC_PROTNAME_SMPP:
  1210. case OSPC_PROTNAME_XMPP:
  1211. default:
  1212. ast_log(LOG_WARNING, "OSP: unsupported protocol '%d'\n", protocol);
  1213. *reason = OSPC_FAIL_PROTOCOL_ERROR;
  1214. results->token[0] = '\0';
  1215. results->networkid[0] = '\0';
  1216. results->nprn[0] = '\0';
  1217. results->npcic[0] = '\0';
  1218. results->npdi = 0;
  1219. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1220. results->opname[type][0] = '\0';
  1221. }
  1222. res = OSP_FAILED;
  1223. break;
  1224. }
  1225. return res;
  1226. }
  1227. /*!
  1228. * \brief Convert Asterisk status to TC code
  1229. * \param cause Asterisk hangup cause
  1230. * \return OSP TC code
  1231. */
  1232. static OSPEFAILREASON asterisk2osp(
  1233. int cause)
  1234. {
  1235. return (OSPEFAILREASON)cause;
  1236. }
  1237. /*!
  1238. * \brief OSP Authentication function
  1239. * \param name OSP provider context name
  1240. * \param trans OSP transaction handle, output
  1241. * \param source Source of inbound call
  1242. * \param calling Calling number
  1243. * \param called Called number
  1244. * \param token OSP token, may be empty
  1245. * \param timelimit Call duration limit, output
  1246. * \return OSP_OK Authenricated, OSP_FAILED Unauthenticated, OSP_ERROR Error
  1247. */
  1248. static int osp_auth(
  1249. const char* name,
  1250. int* trans,
  1251. const char* source,
  1252. const char* calling,
  1253. const char* called,
  1254. const char* token,
  1255. unsigned int* timelimit)
  1256. {
  1257. int res;
  1258. struct osp_provider* provider = NULL;
  1259. char dest[OSP_SIZE_NORSTR];
  1260. if ((trans == NULL) || (timelimit == NULL)) {
  1261. ast_log(LOG_ERROR, "Invalid parameters\n");
  1262. return OSP_ERROR;
  1263. }
  1264. *trans = OSP_INVALID_HANDLE;
  1265. *timelimit = OSP_DEF_TIMELIMIT;
  1266. if ((res = osp_get_provider(name, &provider)) <= 0) {
  1267. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
  1268. return res;
  1269. }
  1270. switch (provider->authpolicy) {
  1271. case OSP_AUTH_NO:
  1272. res = OSP_OK;
  1273. break;
  1274. case OSP_AUTH_EXC:
  1275. if (ast_strlen_zero(token)) {
  1276. res = OSP_FAILED;
  1277. } else if ((res = osp_create_transaction(name, trans, dest, sizeof(dest))) <= 0) {
  1278. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  1279. *trans = OSP_INVALID_HANDLE;
  1280. res = OSP_FAILED;
  1281. } else if((res = osp_validate_token(*trans, source, dest, calling, called, token, timelimit)) <= 0) {
  1282. OSPPTransactionRecordFailure(*trans, OSPC_FAIL_CALL_REJECTED);
  1283. }
  1284. break;
  1285. case OSP_AUTH_YES:
  1286. default:
  1287. if (ast_strlen_zero(token)) {
  1288. res = OSP_OK;
  1289. } else if ((res = osp_create_transaction(name, trans, dest, sizeof(dest))) <= 0) {
  1290. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  1291. *trans = OSP_INVALID_HANDLE;
  1292. res = OSP_FAILED;
  1293. } else if((res = osp_validate_token(*trans, source, dest, calling, called, token, timelimit)) <= 0) {
  1294. OSPPTransactionRecordFailure(*trans, OSPC_FAIL_CALL_REJECTED);
  1295. }
  1296. break;
  1297. }
  1298. return res;
  1299. }
  1300. /*!
  1301. * \brief Create a UUID
  1302. * \param uuid UUID buffer
  1303. * \param bufsize UUID buffer size
  1304. * \return OSK_OK Created, OSP_ERROR Error
  1305. */
  1306. static int osp_create_uuid(
  1307. unsigned char* uuid,
  1308. unsigned int* bufsize)
  1309. {
  1310. int i, res;
  1311. long int tmp[OSP_SIZE_UUID / sizeof(long int)];
  1312. if ((uuid != NULL) && (*bufsize >= OSP_SIZE_UUID)) {
  1313. for (i = 0; i < OSP_SIZE_UUID / sizeof(long int); i++) {
  1314. tmp[i] = ast_random();
  1315. }
  1316. memcpy(uuid, tmp, OSP_SIZE_UUID);
  1317. *bufsize = OSP_SIZE_UUID;
  1318. res = OSP_OK;
  1319. } else {
  1320. ast_log(LOG_ERROR, "Invalid parameters\n");
  1321. res = OSP_ERROR;
  1322. }
  1323. return res;
  1324. }
  1325. /*!
  1326. * \brief UUID to string
  1327. * \param uuid UUID
  1328. * \param buffer String buffer
  1329. * \param bufsize String buffer size
  1330. * \return OSP_OK Successed, OSP_ERROR Error
  1331. */
  1332. static int osp_uuid2str(
  1333. unsigned char* uuid,
  1334. char* buffer,
  1335. unsigned int bufsize)
  1336. {
  1337. int res;
  1338. if ((uuid != NULL) && (bufsize > OSP_SIZE_UUIDSTR)) {
  1339. snprintf(buffer, bufsize, "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-"
  1340. "%02hhx%02hhx-%02hhx%02hhx-"
  1341. "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
  1342. uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
  1343. uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
  1344. res = OSP_OK;
  1345. } else {
  1346. ast_log(LOG_ERROR, "Invalid parameters\n");
  1347. res = OSP_ERROR;
  1348. }
  1349. return res;
  1350. }
  1351. /*!
  1352. * \brief Create a call ID according to the type
  1353. * \param type Call ID type
  1354. * \param callid Call ID buffer
  1355. * \return OSK_OK Created, OSP_FAILED Not create, OSP_ERROR Error
  1356. */
  1357. static int osp_create_callid(
  1358. unsigned int type,
  1359. struct osp_callid* callid)
  1360. {
  1361. int res;
  1362. if (callid == NULL) {
  1363. ast_log(LOG_ERROR, "Invalid parameters\n");
  1364. return OSP_ERROR;
  1365. }
  1366. callid->len = sizeof(callid->buf);
  1367. switch (type) {
  1368. case OSP_CALLID_H323:
  1369. res = osp_create_uuid(callid->buf, &callid->len);
  1370. break;
  1371. case OSP_CALLID_SIP:
  1372. case OSP_CALLID_IAX:
  1373. res = OSP_FAILED;
  1374. break;
  1375. default:
  1376. res = OSP_ERROR;
  1377. break;
  1378. }
  1379. if ((res != OSP_OK) && (callid->len != 0)) {
  1380. callid->buf[0] = '\0';
  1381. callid->len = 0;
  1382. }
  1383. return res;
  1384. }
  1385. /*!
  1386. * \brief OSP Lookup function
  1387. * \param name OSP provider context name
  1388. * \param callidtypes Call ID types
  1389. * \param actualsrc Actual source device in indirect mode
  1390. * \param srcdev Source device of outbound call
  1391. * \param calling Calling number
  1392. * \param called Called number
  1393. * \param snetid Source network ID
  1394. * \param np NP parameters
  1395. * \param headers SIP header parameters
  1396. * \param cinfo Custom info
  1397. * \param results Lookup results
  1398. * \return OSP_OK Found , OSP_FAILED No route, OSP_ERROR Error
  1399. */
  1400. static int osp_lookup(
  1401. const char* name,
  1402. unsigned int callidtypes,
  1403. const char* actualsrc,
  1404. const char* srcdev,
  1405. const char* calling,
  1406. const char* called,
  1407. const char* snetid,
  1408. struct osp_npdata* np,
  1409. struct osp_headers* headers,
  1410. const char* cinfo[],
  1411. struct osp_results* results)
  1412. {
  1413. int res;
  1414. struct osp_provider* provider = NULL;
  1415. OSPE_PROTOCOL_NAME protocol;
  1416. char source[OSP_SIZE_NORSTR];
  1417. char callingnum[OSP_SIZE_NORSTR];
  1418. char callednum[OSP_SIZE_NORSTR];
  1419. char destination[OSP_SIZE_NORSTR];
  1420. char* tmp;
  1421. unsigned int tokenlen;
  1422. char token[OSP_SIZE_TOKSTR];
  1423. char src[OSP_SIZE_NORSTR];
  1424. char dev[OSP_SIZE_NORSTR];
  1425. char host[OSP_SIZE_NORSTR];
  1426. unsigned int i, type;
  1427. struct osp_callid callid;
  1428. unsigned int callidnum;
  1429. OSPT_CALL_ID* callids[OSP_CALLID_MAXNUM];
  1430. char dest[OSP_SIZE_NORSTR];
  1431. const char* preferred[2] = { NULL };
  1432. unsigned int dummy = 0;
  1433. OSPEFAILREASON reason;
  1434. int error;
  1435. if (results == NULL) {
  1436. ast_log(LOG_ERROR, "Invalid parameters\n");
  1437. return OSP_ERROR;
  1438. }
  1439. osp_convert_inout(results->dest, dest, sizeof(dest));
  1440. results->outhandle = OSP_INVALID_HANDLE;
  1441. results->outtech[0] = '\0';
  1442. results->calling[0] = '\0';
  1443. results->called[0] = '\0';
  1444. results->token[0] = '\0';
  1445. results->networkid[0] = '\0';
  1446. results->nprn[0] = '\0';
  1447. results->npcic[0] = '\0';
  1448. results->npdi = 0;
  1449. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1450. results->opname[type][0] = '\0';
  1451. }
  1452. results->numdests = 0;
  1453. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1454. if ((res = osp_get_provider(name, &provider)) <= 0) {
  1455. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
  1456. return res;
  1457. }
  1458. if ((res = osp_create_transaction(name, &results->outhandle, source, sizeof(source))) <= 0) {
  1459. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  1460. results->outhandle = OSP_INVALID_HANDLE;
  1461. if (results->inhandle != OSP_INVALID_HANDLE) {
  1462. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1463. }
  1464. return OSP_ERROR;
  1465. }
  1466. if (!strcasecmp(results->intech, OSP_TECH_SIP)) {
  1467. protocol = OSPC_PROTNAME_SIP;
  1468. } else if (!strcasecmp(results->intech, OSP_TECH_H323)) {
  1469. protocol = OSPC_PROTNAME_Q931;
  1470. } else if (!strcasecmp(results->intech, OSP_TECH_IAX)) {
  1471. protocol = OSPC_PROTNAME_IAX;
  1472. } else if (!strcasecmp(results->intech, OSP_TECH_SKYPE)) {
  1473. protocol = OSPC_PROTNAME_SKYPE;
  1474. } else {
  1475. protocol = OSPC_PROTNAME_SIP;
  1476. }
  1477. OSPPTransactionSetProtocol(results->outhandle, OSPC_PROTTYPE_SOURCE, protocol);
  1478. if (!ast_strlen_zero(snetid)) {
  1479. OSPPTransactionSetNetworkIds(results->outhandle, snetid, "");
  1480. }
  1481. OSPPTransactionSetNumberPortability(results->outhandle, np->rn, np->cic, np->npdi);
  1482. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1483. OSPPTransactionSetOperatorName(results->outhandle, type, np->opname[type]);
  1484. }
  1485. OSPPTransactionSetRemotePartyId(results->outhandle, OSPC_NFORMAT_E164, headers->rpiduser);
  1486. OSPPTransactionSetAssertedId(results->outhandle, OSPC_NFORMAT_E164, headers->paiuser);
  1487. osp_convert_inout(headers->divhost, host, sizeof(host));
  1488. OSPPTransactionSetDiversion(results->outhandle, headers->divuser, host);
  1489. OSPPTransactionSetChargeInfo(results->outhandle, OSPC_NFORMAT_E164, headers->pciuser);
  1490. if (cinfo != NULL) {
  1491. for (i = 0; i < OSP_MAX_CUSTOMINFO; i++) {
  1492. if (!ast_strlen_zero(cinfo[i])) {
  1493. OSPPTransactionSetCustomInfo(results->outhandle, i, cinfo[i]);
  1494. }
  1495. }
  1496. }
  1497. ast_copy_string(callednum, called, sizeof(callednum));
  1498. if((tmp = strchr(callednum, ';')) != NULL) {
  1499. *tmp = '\0';
  1500. }
  1501. callidnum = 0;
  1502. callids[0] = NULL;
  1503. for (i = 0; i < OSP_CALLID_MAXNUM; i++) {
  1504. type = 1 << i;
  1505. if (callidtypes & type) {
  1506. error = osp_create_callid(type, &callid);
  1507. if (error == 1) {
  1508. callids[callidnum] = OSPPCallIdNew(callid.len, callid.buf);
  1509. callidnum++;
  1510. }
  1511. }
  1512. }
  1513. if (provider->workmode == OSP_MODE_INDIRECT) {
  1514. osp_convert_inout(srcdev, src, sizeof(src));
  1515. if (ast_strlen_zero(actualsrc)) {
  1516. osp_convert_inout(srcdev, dev, sizeof(dev));
  1517. } else {
  1518. osp_convert_inout(actualsrc, dev, sizeof(dev));
  1519. }
  1520. } else {
  1521. osp_convert_inout(source, src, sizeof(src));
  1522. osp_convert_inout(srcdev, dev, sizeof(dev));
  1523. }
  1524. if (provider->srvtype == OSP_SRV_NPQUERY) {
  1525. OSPPTransactionSetServiceType(results->outhandle, OSPC_SERVICE_NPQUERY);
  1526. if (!ast_strlen_zero(dest)) {
  1527. preferred[0] = dest;
  1528. }
  1529. results->numdests = 1;
  1530. } else {
  1531. OSPPTransactionSetServiceType(results->outhandle, OSPC_SERVICE_VOICE);
  1532. results->numdests = OSP_DEF_MAXDESTS;
  1533. }
  1534. error = OSPPTransactionRequestAuthorisation(results->outhandle,
  1535. src,
  1536. dev,
  1537. calling ? calling : "",
  1538. OSPC_NFORMAT_E164,
  1539. callednum,
  1540. OSPC_NFORMAT_E164,
  1541. NULL,
  1542. callidnum,
  1543. callids,
  1544. preferred,
  1545. &results->numdests,
  1546. &dummy,
  1547. NULL);
  1548. for (i = 0; i < callidnum; i++) {
  1549. OSPPCallIdDelete(&callids[i]);
  1550. }
  1551. if (error != OSPC_ERR_NO_ERROR) {
  1552. ast_log(LOG_WARNING, "OSP: Unable to request authorization, error '%d'\n", error);
  1553. results->numdests = 0;
  1554. if (results->inhandle != OSP_INVALID_HANDLE) {
  1555. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1556. }
  1557. return OSP_ERROR;
  1558. }
  1559. if (!results->numdests) {
  1560. ast_debug(1, "OSP: No more destination\n");
  1561. if (results->inhandle != OSP_INVALID_HANDLE) {
  1562. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1563. }
  1564. return OSP_FAILED;
  1565. }
  1566. results->outcallid.len = sizeof(results->outcallid.buf);
  1567. tokenlen = sizeof(token);
  1568. error = OSPPTransactionGetFirstDestination(results->outhandle,
  1569. 0,
  1570. NULL,
  1571. NULL,
  1572. &results->outtimelimit,
  1573. &results->outcallid.len,
  1574. results->outcallid.buf,
  1575. sizeof(callednum),
  1576. callednum,
  1577. sizeof(callingnum),
  1578. callingnum,
  1579. sizeof(destination),
  1580. destination,
  1581. 0,
  1582. NULL,
  1583. &tokenlen,
  1584. token);
  1585. if (error != OSPC_ERR_NO_ERROR) {
  1586. ast_debug(1, "OSP: Unable to get first route, error '%d'\n", error);
  1587. results->numdests = 0;
  1588. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1589. if (results->inhandle != OSP_INVALID_HANDLE) {
  1590. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1591. }
  1592. return OSP_ERROR;
  1593. }
  1594. results->numdests--;
  1595. results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
  1596. ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
  1597. ast_debug(1, "OSP: calling '%s'\n", callingnum);
  1598. ast_debug(1, "OSP: called '%s'\n", callednum);
  1599. ast_debug(1, "OSP: destination '%s'\n", destination);
  1600. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  1601. if ((res = osp_check_destination(provider, callingnum, callednum, destination, tokenlen, token, &reason, results)) > 0) {
  1602. return OSP_OK;
  1603. }
  1604. if (!results->numdests) {
  1605. ast_debug(1, "OSP: No more destination\n");
  1606. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1607. OSPPTransactionRecordFailure(results->outhandle, reason);
  1608. if (results->inhandle != OSP_INVALID_HANDLE) {
  1609. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1610. }
  1611. return OSP_FAILED;
  1612. }
  1613. while(results->numdests) {
  1614. results->outcallid.len = sizeof(results->outcallid.buf);
  1615. tokenlen = sizeof(token);
  1616. error = OSPPTransactionGetNextDestination(results->outhandle,
  1617. reason,
  1618. 0,
  1619. NULL,
  1620. NULL,
  1621. &results->outtimelimit,
  1622. &results->outcallid.len,
  1623. results->outcallid.buf,
  1624. sizeof(callednum),
  1625. callednum,
  1626. sizeof(callingnum),
  1627. callingnum,
  1628. sizeof(destination),
  1629. destination,
  1630. 0,
  1631. NULL,
  1632. &tokenlen,
  1633. token);
  1634. if (error == OSPC_ERR_NO_ERROR) {
  1635. results->numdests--;
  1636. results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
  1637. ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
  1638. ast_debug(1, "OSP: calling '%s'\n", callingnum);
  1639. ast_debug(1, "OSP: called '%s'\n", callednum);
  1640. ast_debug(1, "OSP: destination '%s'\n", destination);
  1641. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  1642. if ((res = osp_check_destination(provider, callingnum, callednum, destination, tokenlen, token, &reason, results)) > 0) {
  1643. break;
  1644. } else if (!results->numdests) {
  1645. ast_debug(1, "OSP: No more destination\n");
  1646. OSPPTransactionRecordFailure(results->outhandle, reason);
  1647. if (results->inhandle != OSP_INVALID_HANDLE) {
  1648. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1649. }
  1650. res = OSP_FAILED;
  1651. break;
  1652. }
  1653. } else {
  1654. ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
  1655. results->numdests = 0;
  1656. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1657. if (results->inhandle != OSP_INVALID_HANDLE) {
  1658. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1659. }
  1660. res = OSP_ERROR;
  1661. break;
  1662. }
  1663. }
  1664. return res;
  1665. }
  1666. /*!
  1667. * \brief OSP Lookup Next function
  1668. * \param name OSP provider name
  1669. * \param cause Asterisk hangup cause
  1670. * \param results Lookup results, in/output
  1671. * \return OSP_OK Found , OSP_FAILED No route, OSP_ERROR Error
  1672. */
  1673. static int osp_next(
  1674. const char* name,
  1675. int cause,
  1676. struct osp_results* results)
  1677. {
  1678. int res;
  1679. struct osp_provider* provider = NULL;
  1680. char calling[OSP_SIZE_NORSTR];
  1681. char called[OSP_SIZE_NORSTR];
  1682. char dest[OSP_SIZE_NORSTR];
  1683. unsigned int tokenlen;
  1684. char token[OSP_SIZE_TOKSTR];
  1685. OSPEFAILREASON reason;
  1686. OSPE_OPERATOR_NAME type;
  1687. int error;
  1688. if (results == NULL) {
  1689. ast_log(LOG_ERROR, "Invalid parameters\n");
  1690. return OSP_ERROR;
  1691. }
  1692. results->outtech[0] = '\0';
  1693. results->dest[0] = '\0';
  1694. results->calling[0] = '\0';
  1695. results->called[0] = '\0';
  1696. results->token[0] = '\0';
  1697. results->networkid[0] = '\0';
  1698. results->nprn[0] = '\0';
  1699. results->npcic[0] = '\0';
  1700. results->npdi = 0;
  1701. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  1702. results->opname[type][0] = '\0';
  1703. }
  1704. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1705. if ((res = osp_get_provider(name, &provider)) <= 0) {
  1706. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
  1707. return res;
  1708. }
  1709. if (results->outhandle == OSP_INVALID_HANDLE) {
  1710. ast_debug(1, "OSP: Transaction handle undefined\n");
  1711. results->numdests = 0;
  1712. if (results->inhandle != OSP_INVALID_HANDLE) {
  1713. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1714. }
  1715. return OSP_ERROR;
  1716. }
  1717. reason = asterisk2osp(cause);
  1718. if (!results->numdests) {
  1719. ast_debug(1, "OSP: No more destination\n");
  1720. OSPPTransactionRecordFailure(results->outhandle, reason);
  1721. if (results->inhandle != OSP_INVALID_HANDLE) {
  1722. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1723. }
  1724. return OSP_FAILED;
  1725. }
  1726. while(results->numdests) {
  1727. results->outcallid.len = sizeof(results->outcallid.buf);
  1728. tokenlen = sizeof(token);
  1729. error = OSPPTransactionGetNextDestination(
  1730. results->outhandle,
  1731. reason,
  1732. 0,
  1733. NULL,
  1734. NULL,
  1735. &results->outtimelimit,
  1736. &results->outcallid.len,
  1737. results->outcallid.buf,
  1738. sizeof(called),
  1739. called,
  1740. sizeof(calling),
  1741. calling,
  1742. sizeof(dest),
  1743. dest,
  1744. 0,
  1745. NULL,
  1746. &tokenlen,
  1747. token);
  1748. if (error == OSPC_ERR_NO_ERROR) {
  1749. results->numdests--;
  1750. results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
  1751. ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
  1752. ast_debug(1, "OSP: calling '%s'\n", calling);
  1753. ast_debug(1, "OSP: called '%s'\n", called);
  1754. ast_debug(1, "OSP: destination '%s'\n", dest);
  1755. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  1756. if ((res = osp_check_destination(provider, calling, called, dest, tokenlen, token, &reason, results)) > 0) {
  1757. res = OSP_OK;
  1758. break;
  1759. } else if (!results->numdests) {
  1760. ast_debug(1, "OSP: No more destination\n");
  1761. OSPPTransactionRecordFailure(results->outhandle, reason);
  1762. if (results->inhandle != OSP_INVALID_HANDLE) {
  1763. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1764. }
  1765. res = OSP_FAILED;
  1766. break;
  1767. }
  1768. } else {
  1769. ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
  1770. results->token[0] = '\0';
  1771. results->numdests = 0;
  1772. results->outtimelimit = OSP_DEF_TIMELIMIT;
  1773. if (results->inhandle != OSP_INVALID_HANDLE) {
  1774. OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1775. }
  1776. res = OSP_ERROR;
  1777. break;
  1778. }
  1779. }
  1780. return res;
  1781. }
  1782. /*!
  1783. * \brief Get integer from variable string
  1784. * \param vstr Variable string
  1785. * \return OSP_DEF_INTSTATS Error
  1786. */
  1787. static int osp_get_varint(
  1788. const char* vstr)
  1789. {
  1790. char* tmp;
  1791. int value = OSP_DEF_INTSTATS;
  1792. if (!ast_strlen_zero(vstr)) {
  1793. if ((tmp = strchr(vstr, '=')) != NULL) {
  1794. tmp++;
  1795. if (sscanf(tmp, "%30d", &value) != 1) {
  1796. value = OSP_DEF_INTSTATS;
  1797. }
  1798. }
  1799. }
  1800. return value;
  1801. }
  1802. /*!
  1803. * \brief Get float from variable string
  1804. * \param vstr Variable string
  1805. * \return OSP_DEF_FLOATSTATS Error
  1806. */
  1807. static float osp_get_varfloat(
  1808. const char* vstr)
  1809. {
  1810. char* tmp;
  1811. float value = OSP_DEF_FLOATSTATS;
  1812. if (!ast_strlen_zero(vstr)) {
  1813. if ((tmp = strchr(vstr, '=')) != NULL) {
  1814. tmp++;
  1815. if (sscanf(tmp, "%30f", &value) != 1) {
  1816. value = OSP_DEF_FLOATSTATS;
  1817. }
  1818. }
  1819. }
  1820. return value;
  1821. }
  1822. /*!
  1823. * \brief Report QoS
  1824. * \param trans OSP in/outbound transaction handle
  1825. * \param leg Inbound/outbound
  1826. * \param qos QoS string
  1827. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  1828. */
  1829. static int osp_report_qos(
  1830. int trans,
  1831. enum osp_callleg leg,
  1832. const char* qos)
  1833. {
  1834. int res = OSP_FAILED;
  1835. enum osp_direction dir;
  1836. char buffer[OSP_SIZE_NORSTR];
  1837. char* tmp;
  1838. char* item;
  1839. int totalpackets[OSP_DIR_NUMBER];
  1840. struct osp_metrics lost[OSP_DIR_NUMBER];
  1841. struct osp_metrics jitter[OSP_DIR_NUMBER];
  1842. struct osp_metrics rtt;
  1843. int value;
  1844. if (!ast_strlen_zero(qos)) {
  1845. for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
  1846. totalpackets[dir] = OSP_DEF_INTSTATS;
  1847. }
  1848. for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
  1849. lost[dir].value = OSP_DEF_INTSTATS;
  1850. lost[dir].min = OSP_DEF_FLOATSTATS;
  1851. lost[dir].max = OSP_DEF_FLOATSTATS;
  1852. lost[dir].avg = OSP_DEF_FLOATSTATS;
  1853. lost[dir].sdev = OSP_DEF_FLOATSTATS;
  1854. }
  1855. for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
  1856. jitter[dir].value = OSP_DEF_INTSTATS;
  1857. jitter[dir].min = OSP_DEF_FLOATSTATS;
  1858. jitter[dir].max = OSP_DEF_FLOATSTATS;
  1859. jitter[dir].avg = OSP_DEF_FLOATSTATS;
  1860. jitter[dir].sdev = OSP_DEF_FLOATSTATS;
  1861. }
  1862. rtt.value = OSP_DEF_INTSTATS;
  1863. rtt.min = OSP_DEF_FLOATSTATS;
  1864. rtt.max = OSP_DEF_FLOATSTATS;
  1865. rtt.avg = OSP_DEF_FLOATSTATS;
  1866. rtt.sdev = OSP_DEF_FLOATSTATS;
  1867. ast_copy_string(buffer, qos, sizeof(buffer));
  1868. for (item = strtok_r(buffer, ";", &tmp); item; item = strtok_r(NULL, ";", &tmp)) {
  1869. if (!strncasecmp(item, "rxcount", strlen("rxcount"))) {
  1870. totalpackets[OSP_DIR_RX] = osp_get_varint(item);
  1871. } else if (!strncasecmp(item, "txcount", strlen("txcount"))) {
  1872. totalpackets[OSP_DIR_TX] = osp_get_varint(item);
  1873. } else if (!strncasecmp(item, "lp", strlen("lp"))) {
  1874. lost[OSP_DIR_RX].value = osp_get_varint(item);
  1875. } else if (!strncasecmp(item, "minrxlost", strlen("minrxlost"))) {
  1876. lost[OSP_DIR_RX].min = osp_get_varfloat(item);
  1877. } else if (!strncasecmp(item, "maxrxlost", strlen("maxrxlost"))) {
  1878. lost[OSP_DIR_RX].max = osp_get_varfloat(item);
  1879. } else if (!strncasecmp(item, "avgrxlost", strlen("avgrxlost"))) {
  1880. lost[OSP_DIR_RX].avg = osp_get_varfloat(item);
  1881. } else if (!strncasecmp(item, "stdevrxlost", strlen("stdevrxlost"))) {
  1882. lost[OSP_DIR_RX].sdev = osp_get_varfloat(item);
  1883. } else if (!strncasecmp(item, "rlp", strlen("rlp"))) {
  1884. lost[OSP_DIR_TX].value = osp_get_varint(item);
  1885. } else if (!strncasecmp(item, "reported_minlost", strlen("reported_minlost"))) {
  1886. lost[OSP_DIR_TX].min = osp_get_varfloat(item);
  1887. } else if (!strncasecmp(item, "reported_maxlost", strlen("reported_maxlost"))) {
  1888. lost[OSP_DIR_TX].max = osp_get_varfloat(item);
  1889. } else if (!strncasecmp(item, "reported_avglost", strlen("reported_avglost"))) {
  1890. lost[OSP_DIR_TX].avg = osp_get_varfloat(item);
  1891. } else if (!strncasecmp(item, "reported_stdevlost", strlen("reported_stdevlost"))) {
  1892. lost[OSP_DIR_TX].sdev = osp_get_varfloat(item);
  1893. } else if (!strncasecmp(item, "rxjitter", strlen("rxjitter"))) {
  1894. jitter[OSP_DIR_RX].value = osp_get_varint(item);
  1895. } else if (!strncasecmp(item, "minrxjitter", strlen("minrxjitter"))) {
  1896. jitter[OSP_DIR_RX].min = osp_get_varfloat(item);
  1897. } else if (!strncasecmp(item, "maxrxjitter", strlen("maxrxjitter"))) {
  1898. jitter[OSP_DIR_RX].max = osp_get_varfloat(item);
  1899. } else if (!strncasecmp(item, "avgrxjitter", strlen("avgjitter"))) {
  1900. jitter[OSP_DIR_RX].avg = osp_get_varfloat(item);
  1901. } else if (!strncasecmp(item, "stdevrxjitter", strlen("stdevjitter"))) {
  1902. jitter[OSP_DIR_RX].sdev = osp_get_varfloat(item);
  1903. } else if (!strncasecmp(item, "txjitter", strlen("txjitter"))) {
  1904. jitter[OSP_DIR_TX].value = osp_get_varint(item);
  1905. } else if (!strncasecmp(item, "reported_minjitter", strlen("reported_minjitter"))) {
  1906. jitter[OSP_DIR_TX].min = osp_get_varfloat(item);
  1907. } else if (!strncasecmp(item, "reported_maxjitter", strlen("reported_maxjitter"))) {
  1908. jitter[OSP_DIR_TX].max = osp_get_varfloat(item);
  1909. } else if (!strncasecmp(item, "reported_avgjitter", strlen("reported_avgjitter"))) {
  1910. jitter[OSP_DIR_TX].avg = osp_get_varfloat(item);
  1911. } else if (!strncasecmp(item, "reported_stdevjitter", strlen("reported_stdevjitter"))) {
  1912. jitter[OSP_DIR_TX].sdev = osp_get_varfloat(item);
  1913. } else if (!strncasecmp(item, "rtt", strlen("rtt"))) {
  1914. rtt.value = osp_get_varint(item);
  1915. } else if (!strncasecmp(item, "minrtt", strlen("minrtt"))) {
  1916. rtt.min = osp_get_varfloat(item);
  1917. } else if (!strncasecmp(item, "maxrtt", strlen("maxrtt"))) {
  1918. rtt.max = osp_get_varfloat(item);
  1919. } else if (!strncasecmp(item, "avgrtt", strlen("avgrtt"))) {
  1920. rtt.avg = osp_get_varfloat(item);
  1921. } else if (!strncasecmp(item, "stdevrtt", strlen("stdevrtt"))) {
  1922. rtt.sdev = osp_get_varfloat(item);
  1923. }
  1924. }
  1925. ast_debug(1, "OSP: call leg '%d'\n", leg);
  1926. ast_debug(1, "OSP: rxcount '%d'\n", totalpackets[OSP_DIR_RX]);
  1927. ast_debug(1, "OSP: txcount '%d'\n", totalpackets[OSP_DIR_TX]);
  1928. ast_debug(1, "OSP: lp '%d'\n",lost[OSP_DIR_RX].value);
  1929. ast_debug(1, "OSP: minrxlost '%f'\n", lost[OSP_DIR_RX].min);
  1930. ast_debug(1, "OSP: maxrxlost '%f'\n", lost[OSP_DIR_RX].max);
  1931. ast_debug(1, "OSP: avgrxlost '%f'\n", lost[OSP_DIR_RX].avg);
  1932. ast_debug(1, "OSP: stdevrxlost '%f'\n", lost[OSP_DIR_RX].sdev);
  1933. ast_debug(1, "OSP: rlp '%d'\n", lost[OSP_DIR_TX].value);
  1934. ast_debug(1, "OSP: reported_minlost '%f'\n", lost[OSP_DIR_TX].min);
  1935. ast_debug(1, "OSP: reported_maxlost '%f'\n", lost[OSP_DIR_TX].max);
  1936. ast_debug(1, "OSP: reported_avglost '%f'\n", lost[OSP_DIR_TX].avg);
  1937. ast_debug(1, "OSP: reported_stdevlost '%f'\n", lost[OSP_DIR_TX].sdev);
  1938. ast_debug(1, "OSP: rxjitter '%d'\n", jitter[OSP_DIR_RX].value);
  1939. ast_debug(1, "OSP: minrxjitter '%f'\n", jitter[OSP_DIR_RX].min);
  1940. ast_debug(1, "OSP: maxrxjitter '%f'\n", jitter[OSP_DIR_RX].max);
  1941. ast_debug(1, "OSP: avgrxjitter '%f'\n", jitter[OSP_DIR_RX].avg);
  1942. ast_debug(1, "OSP: stdevrxjitter '%f'\n", jitter[OSP_DIR_RX].sdev);
  1943. ast_debug(1, "OSP: txjitter '%d'\n", jitter[OSP_DIR_TX].value);
  1944. ast_debug(1, "OSP: reported_minjitter '%f'\n", jitter[OSP_DIR_TX].min);
  1945. ast_debug(1, "OSP: reported_maxjitter '%f'\n", jitter[OSP_DIR_TX].max);
  1946. ast_debug(1, "OSP: reported_avgjitter '%f'\n", jitter[OSP_DIR_TX].avg);
  1947. ast_debug(1, "OSP: reported_stdevjitter '%f'\n", jitter[OSP_DIR_TX].sdev);
  1948. ast_debug(1, "OSP: rtt '%d'\n", rtt.value);
  1949. ast_debug(1, "OSP: minrtt '%f'\n", rtt.min);
  1950. ast_debug(1, "OSP: maxrtt '%f'\n", rtt.max);
  1951. ast_debug(1, "OSP: avgrtt '%f'\n", rtt.avg);
  1952. ast_debug(1, "OSP: stdevrtt '%f'\n", rtt.sdev);
  1953. if (leg == OSP_CALL_INBOUND) {
  1954. OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, totalpackets[OSP_DIR_RX]);
  1955. OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP, totalpackets[OSP_DIR_TX]);
  1956. if (lost[OSP_DIR_RX].value >= 0) {
  1957. value = lost[OSP_DIR_RX].value;
  1958. } else {
  1959. value = (int)lost[OSP_DIR_RX].avg;
  1960. }
  1961. OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, value, OSP_DEF_INTSTATS);
  1962. if (lost[OSP_DIR_TX].value >= 0) {
  1963. value = lost[OSP_DIR_TX].value;
  1964. } else {
  1965. value = (int)lost[OSP_DIR_TX].avg;
  1966. }
  1967. OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP, value, OSP_DEF_INTSTATS);
  1968. if (jitter[OSP_DIR_RX].value >= 0) {
  1969. value = jitter[OSP_DIR_RX].value;
  1970. } else {
  1971. value = (int)jitter[OSP_DIR_RX].avg;
  1972. }
  1973. OSPPTransactionSetJitter(trans,
  1974. OSPC_SMETRIC_RTP,
  1975. OSPC_SDIR_SRCREP,
  1976. OSP_DEF_INTSTATS,
  1977. (int)jitter[OSP_DIR_RX].min,
  1978. (int)jitter[OSP_DIR_RX].max,
  1979. value, jitter[OSP_DIR_RX].sdev);
  1980. if (jitter[OSP_DIR_TX].value >= 0) {
  1981. value = jitter[OSP_DIR_TX].value;
  1982. } else {
  1983. value = (int)jitter[OSP_DIR_TX].avg;
  1984. }
  1985. OSPPTransactionSetJitter(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP,
  1986. OSP_DEF_INTSTATS, (int)jitter[OSP_DIR_TX].min, (int)jitter[OSP_DIR_TX].max, value, jitter[OSP_DIR_TX].sdev);
  1987. } else {
  1988. OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, totalpackets[OSP_DIR_RX]);
  1989. OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_SRCREP, totalpackets[OSP_DIR_TX]);
  1990. OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, lost[OSP_DIR_RX].value, OSP_DEF_INTSTATS);
  1991. OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_SRCREP, lost[OSP_DIR_TX].value, OSP_DEF_INTSTATS);
  1992. if (jitter[OSP_DIR_RX].value >= 0) {
  1993. value = jitter[OSP_DIR_RX].value;
  1994. } else {
  1995. value = (int)jitter[OSP_DIR_RX].avg;
  1996. }
  1997. OSPPTransactionSetJitter(trans,
  1998. OSPC_SMETRIC_RTP,
  1999. OSPC_SDIR_DESTREP,
  2000. OSP_DEF_INTSTATS,
  2001. (int)jitter[OSP_DIR_RX].min,
  2002. (int)jitter[OSP_DIR_RX].max,
  2003. value,
  2004. jitter[OSP_DIR_RX].sdev);
  2005. if (jitter[OSP_DIR_TX].value >= 0) {
  2006. value = jitter[OSP_DIR_TX].value;
  2007. } else {
  2008. value = (int)jitter[OSP_DIR_TX].avg;
  2009. }
  2010. OSPPTransactionSetJitter(trans,
  2011. OSPC_SMETRIC_RTCP,
  2012. OSPC_SDIR_SRCREP,
  2013. OSP_DEF_INTSTATS,
  2014. (int)jitter[OSP_DIR_TX].min,
  2015. (int)jitter[OSP_DIR_TX].max,
  2016. value,
  2017. jitter[OSP_DIR_TX].sdev);
  2018. }
  2019. res = OSP_OK;
  2020. }
  2021. return res;
  2022. }
  2023. /*!
  2024. * \brief OSP Finish function
  2025. * \param trans OSP in/outbound transaction handle
  2026. * \param recorded If failure reason has been recorded
  2027. * \param cause Asterisk hangup cause
  2028. * \param start Call start time
  2029. * \param connect Call connect time
  2030. * \param end Call end time
  2031. * \param release Who release first, 0 source, 1 destination
  2032. * \param inqos Inbound QoS string
  2033. * \param outqos Outbound QoS string
  2034. * \return OSP_OK Success, OSP_FAILED Failed, OSP_ERROR Error
  2035. */
  2036. static int osp_finish(
  2037. int trans,
  2038. int recorded,
  2039. int cause,
  2040. time_t start,
  2041. time_t connect,
  2042. time_t end,
  2043. unsigned int release,
  2044. const char* inqos,
  2045. const char* outqos)
  2046. {
  2047. int res;
  2048. OSPEFAILREASON reason;
  2049. time_t alert = 0;
  2050. unsigned isPddInfoPresent = 0;
  2051. unsigned pdd = 0;
  2052. unsigned int dummy = 0;
  2053. int error;
  2054. if (trans == OSP_INVALID_HANDLE) {
  2055. return OSP_FAILED;
  2056. }
  2057. OSPPTransactionSetRoleInfo(trans, OSPC_RSTATE_STOP, OSPC_RFORMAT_OSP, OSPC_RVENDOR_ASTERISK);
  2058. if (!recorded) {
  2059. reason = asterisk2osp(cause);
  2060. OSPPTransactionRecordFailure(trans, reason);
  2061. }
  2062. osp_report_qos(trans, OSP_CALL_INBOUND, inqos);
  2063. osp_report_qos(trans, OSP_CALL_OUTBOUND, outqos);
  2064. error = OSPPTransactionReportUsage(trans,
  2065. difftime(end, connect),
  2066. start,
  2067. end,
  2068. alert,
  2069. connect,
  2070. isPddInfoPresent,
  2071. pdd,
  2072. release,
  2073. NULL,
  2074. OSP_DEF_INTSTATS,
  2075. OSP_DEF_INTSTATS,
  2076. OSP_DEF_INTSTATS,
  2077. OSP_DEF_INTSTATS,
  2078. &dummy,
  2079. NULL);
  2080. if (error == OSPC_ERR_NO_ERROR) {
  2081. ast_debug(1, "OSP: Usage reported\n");
  2082. res = OSP_OK;
  2083. } else {
  2084. ast_debug(1, "OSP: Unable to report usage, error '%d'\n", error);
  2085. res = OSP_ERROR;
  2086. }
  2087. OSPPTransactionDelete(trans);
  2088. return res;
  2089. }
  2090. /* OSP Application APIs */
  2091. /*!
  2092. * \brief OSP Application OSPAuth
  2093. * \param chan Channel
  2094. * \param data Parameter
  2095. * \return OSP_AST_OK Success, OSP_AST_ERROR Error
  2096. */
  2097. static int ospauth_exec(
  2098. struct ast_channel *chan,
  2099. const char *data)
  2100. {
  2101. int res;
  2102. const char* provider = OSP_DEF_PROVIDER;
  2103. struct varshead* headp;
  2104. struct ast_var_t* current;
  2105. const char* source = "";
  2106. const char* token = "";
  2107. int handle;
  2108. unsigned int timelimit;
  2109. char buffer[OSP_SIZE_INTSTR];
  2110. const char* status;
  2111. char* tmp;
  2112. AST_DECLARE_APP_ARGS(args,
  2113. AST_APP_ARG(provider);
  2114. AST_APP_ARG(options);
  2115. );
  2116. tmp = ast_strdupa(data);
  2117. AST_STANDARD_APP_ARGS(args, tmp);
  2118. if (!ast_strlen_zero(args.provider)) {
  2119. provider = args.provider;
  2120. }
  2121. ast_debug(1, "OSPAuth: provider '%s'\n", provider);
  2122. headp = ast_channel_varshead(chan);
  2123. AST_LIST_TRAVERSE(headp, current, entries) {
  2124. if (!strcmp(ast_var_name(current), "OSPINPEERIP")) {
  2125. source = ast_var_value(current);
  2126. } else if (!strcmp(ast_var_name(current), "OSPINTOKEN")) {
  2127. token = ast_var_value(current);
  2128. }
  2129. }
  2130. ast_debug(1, "OSPAuth: source '%s'\n", source);
  2131. ast_debug(1, "OSPAuth: token size '%zd'\n", strlen(token));
  2132. res = osp_auth(provider, &handle, source,
  2133. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
  2134. ast_channel_exten(chan), token, &timelimit);
  2135. if (res > 0) {
  2136. status = AST_OSP_SUCCESS;
  2137. } else {
  2138. timelimit = OSP_DEF_TIMELIMIT;
  2139. if (!res) {
  2140. status = AST_OSP_FAILED;
  2141. } else {
  2142. status = AST_OSP_ERROR;
  2143. }
  2144. }
  2145. snprintf(buffer, sizeof(buffer), "%d", handle);
  2146. pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
  2147. ast_debug(1, "OSPAuth: OSPINHANDLE '%s'\n", buffer);
  2148. snprintf(buffer, sizeof(buffer), "%d", timelimit);
  2149. pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer);
  2150. ast_debug(1, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer);
  2151. pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status);
  2152. ast_debug(1, "OSPAuth: %s\n", status);
  2153. if(res != OSP_OK) {
  2154. res = OSP_AST_ERROR;
  2155. } else {
  2156. res = OSP_AST_OK;
  2157. }
  2158. return res;
  2159. }
  2160. /*!
  2161. * \brief OSP Application OSPLookup
  2162. * \param chan Channel
  2163. * \param data Parameter
  2164. * \return OSP_AST_OK Success, OSP_AST_ERROR Error
  2165. */
  2166. static int osplookup_exec(
  2167. struct ast_channel* chan,
  2168. const char * data)
  2169. {
  2170. int res;
  2171. const char* provider = OSP_DEF_PROVIDER;
  2172. unsigned int callidtypes = OSP_CALLID_UNDEF;
  2173. struct varshead* headp;
  2174. struct ast_var_t* current;
  2175. const char* actualsrc = "";
  2176. const char* srcdev = "";
  2177. const char* snetid = "";
  2178. struct osp_npdata np;
  2179. OSPE_OPERATOR_NAME type;
  2180. struct osp_headers headers;
  2181. unsigned int i;
  2182. const char* cinfo[OSP_MAX_CUSTOMINFO] = { NULL };
  2183. char buffer[OSP_SIZE_TOKSTR];
  2184. struct osp_results results;
  2185. const char* status;
  2186. char* tmp;
  2187. AST_DECLARE_APP_ARGS(args,
  2188. AST_APP_ARG(exten);
  2189. AST_APP_ARG(provider);
  2190. AST_APP_ARG(options);
  2191. );
  2192. if (ast_strlen_zero(data)) {
  2193. ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[,provider[,options]])\n");
  2194. return OSP_AST_ERROR;
  2195. }
  2196. tmp = ast_strdupa(data);
  2197. AST_STANDARD_APP_ARGS(args, tmp);
  2198. ast_debug(1, "OSPLookup: exten '%s'\n", args.exten);
  2199. if (!ast_strlen_zero(args.provider)) {
  2200. provider = args.provider;
  2201. }
  2202. ast_debug(1, "OSPlookup: provider '%s'\n", provider);
  2203. if (args.options) {
  2204. if (strchr(args.options, 'h')) {
  2205. callidtypes |= OSP_CALLID_H323;
  2206. }
  2207. if (strchr(args.options, 's')) {
  2208. callidtypes |= OSP_CALLID_SIP;
  2209. }
  2210. if (strchr(args.options, 'i')) {
  2211. callidtypes |= OSP_CALLID_IAX;
  2212. }
  2213. }
  2214. ast_debug(1, "OSPLookup: call id types '%d'\n", callidtypes);
  2215. results.inhandle = OSP_INVALID_HANDLE;
  2216. results.intimelimit = OSP_DEF_TIMELIMIT;
  2217. results.dest[0] = '\0';
  2218. np.rn = "";
  2219. np.cic = "";
  2220. np.npdi = 0;
  2221. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  2222. np.opname[type] = "";
  2223. }
  2224. headers.rpiduser = "";
  2225. headers.paiuser = "";
  2226. headers.divuser = "";
  2227. headers.divhost = "";
  2228. headers.pciuser = "";
  2229. headp = ast_channel_varshead(chan);
  2230. AST_LIST_TRAVERSE(headp, current, entries) {
  2231. if (!strcmp(ast_var_name(current), "OSPINACTUALSRC")) {
  2232. actualsrc = ast_var_value(current);
  2233. } else if (!strcmp(ast_var_name(current), "OSPINPEERIP")) {
  2234. srcdev = ast_var_value(current);
  2235. } else if (!strcmp(ast_var_name(current), "OSPINTECH")) {
  2236. ast_copy_string(results.intech, ast_var_value(current), sizeof(results.intech));
  2237. } else if (!strcmp(ast_var_name(current), "OSPINHANDLE")) {
  2238. if (sscanf(ast_var_value(current), "%30d", &results.inhandle) != 1) {
  2239. results.inhandle = OSP_INVALID_HANDLE;
  2240. }
  2241. } else if (!strcmp(ast_var_name(current), "OSPINTIMELIMIT")) {
  2242. if (sscanf(ast_var_value(current), "%30d", &results.intimelimit) != 1) {
  2243. results.intimelimit = OSP_DEF_TIMELIMIT;
  2244. }
  2245. } else if (!strcmp(ast_var_name(current), "OSPINNETWORKID")) {
  2246. snetid = ast_var_value(current);
  2247. } else if (!strcmp(ast_var_name(current), "OSPINNPRN")) {
  2248. np.rn = ast_var_value(current);
  2249. } else if (!strcmp(ast_var_name(current), "OSPINNPCIC")) {
  2250. np.cic = ast_var_value(current);
  2251. } else if (!strcmp(ast_var_name(current), "OSPINNPDI")) {
  2252. if (ast_true(ast_var_value(current))) {
  2253. np.npdi = 1;
  2254. }
  2255. } else if (!strcmp(ast_var_name(current), "OSPINSPID")) {
  2256. np.opname[OSPC_OPNAME_SPID] = ast_var_value(current);
  2257. } else if (!strcmp(ast_var_name(current), "OSPINOCN")) {
  2258. np.opname[OSPC_OPNAME_OCN] = ast_var_value(current);
  2259. } else if (!strcmp(ast_var_name(current), "OSPINSPN")) {
  2260. np.opname[OSPC_OPNAME_SPN] = ast_var_value(current);
  2261. } else if (!strcmp(ast_var_name(current), "OSPINALTSPN")) {
  2262. np.opname[OSPC_OPNAME_ALTSPN] = ast_var_value(current);
  2263. } else if (!strcmp(ast_var_name(current), "OSPINMCC")) {
  2264. np.opname[OSPC_OPNAME_MCC] = ast_var_value(current);
  2265. } else if (!strcmp(ast_var_name(current), "OSPINMNC")) {
  2266. np.opname[OSPC_OPNAME_MNC] = ast_var_value(current);
  2267. } else if (!strcmp(ast_var_name(current), "OSPINTOHOST")) {
  2268. ast_copy_string(results.dest, ast_var_value(current), sizeof(results.dest));
  2269. } else if (!strcmp(ast_var_name(current), "OSPINRPIDUSER")) {
  2270. headers.rpiduser = ast_var_value(current);
  2271. } else if (!strcmp(ast_var_name(current), "OSPINPAIUSER")) {
  2272. headers.paiuser = ast_var_value(current);
  2273. } else if (!strcmp(ast_var_name(current), "OSPINDIVUSER")) {
  2274. headers.divuser = ast_var_value(current);
  2275. } else if (!strcmp(ast_var_name(current), "OSPINDIVHOST")) {
  2276. headers.divhost = ast_var_value(current);
  2277. } else if (!strcmp(ast_var_name(current), "OSPINPCIUSER")) {
  2278. headers.pciuser = ast_var_value(current);
  2279. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO1")) {
  2280. cinfo[0] = ast_var_value(current);
  2281. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO2")) {
  2282. cinfo[1] = ast_var_value(current);
  2283. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO3")) {
  2284. cinfo[2] = ast_var_value(current);
  2285. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO4")) {
  2286. cinfo[3] = ast_var_value(current);
  2287. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO5")) {
  2288. cinfo[4] = ast_var_value(current);
  2289. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO6")) {
  2290. cinfo[5] = ast_var_value(current);
  2291. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO7")) {
  2292. cinfo[6] = ast_var_value(current);
  2293. } else if (!strcmp(ast_var_name(current), "OSPINCUSTOMINFO8")) {
  2294. cinfo[7] = ast_var_value(current);
  2295. }
  2296. }
  2297. ast_debug(1, "OSPLookup: actual source device '%s'\n", actualsrc);
  2298. ast_debug(1, "OSPLookup: source device '%s'\n", srcdev);
  2299. ast_debug(1, "OSPLookup: OSPINTECH '%s'\n", results.intech);
  2300. ast_debug(1, "OSPLookup: OSPINHANDLE '%d'\n", results.inhandle);
  2301. ast_debug(1, "OSPLookup: OSPINTIMELIMIT '%d'\n", results.intimelimit);
  2302. ast_debug(1, "OSPLookup: OSPINNETWORKID '%s'\n", snetid);
  2303. ast_debug(1, "OSPLookup: OSPINNPRN '%s'\n", np.rn);
  2304. ast_debug(1, "OSPLookup: OSPINNPCIC '%s'\n", np.cic);
  2305. ast_debug(1, "OSPLookup: OSPINNPDI '%d'\n", np.npdi);
  2306. ast_debug(1, "OSPLookup: OSPINSPID '%s'\n", np.opname[OSPC_OPNAME_SPID]);
  2307. ast_debug(1, "OSPLookup: OSPINOCN '%s'\n", np.opname[OSPC_OPNAME_OCN]);
  2308. ast_debug(1, "OSPLookup: OSPINSPN '%s'\n", np.opname[OSPC_OPNAME_SPN]);
  2309. ast_debug(1, "OSPLookup: OSPINALTSPN '%s'\n", np.opname[OSPC_OPNAME_ALTSPN]);
  2310. ast_debug(1, "OSPLookup: OSPINMCC '%s'\n", np.opname[OSPC_OPNAME_MCC]);
  2311. ast_debug(1, "OSPLookup: OSPINMNC '%s'\n", np.opname[OSPC_OPNAME_MNC]);
  2312. ast_debug(1, "OSPLookup: OSPINTOHOST '%s'\n", results.dest);
  2313. ast_debug(1, "OSPLookup: OSPINRPIDUSER '%s'\n", headers.rpiduser);
  2314. ast_debug(1, "OSPLookup: OSPINPAIUSER '%s'\n", headers.paiuser);
  2315. ast_debug(1, "OSPLookup: OSPINDIVUSER '%s'\n", headers.divuser);
  2316. ast_debug(1, "OSPLookup: OSPINDIVHOST'%s'\n", headers.divhost);
  2317. ast_debug(1, "OSPLookup: OSPINPCIUSER '%s'\n", headers.pciuser);
  2318. for (i = 0; i < OSP_MAX_CUSTOMINFO; i++) {
  2319. if (!ast_strlen_zero(cinfo[i])) {
  2320. ast_debug(1, "OSPLookup: OSPINCUSTOMINFO%d '%s'\n", i, cinfo[i]);
  2321. }
  2322. }
  2323. if (ast_autoservice_start(chan) < 0) {
  2324. return OSP_AST_ERROR;
  2325. }
  2326. res = osp_lookup(provider, callidtypes, actualsrc, srcdev,
  2327. S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
  2328. args.exten, snetid, &np, &headers, cinfo, &results);
  2329. if (res > 0) {
  2330. status = AST_OSP_SUCCESS;
  2331. } else {
  2332. results.outtech[0] = '\0';
  2333. results.dest[0] = '\0';
  2334. results.calling[0] = '\0';
  2335. results.called[0] = '\0';
  2336. results.token[0] = '\0';
  2337. results.networkid[0] = '\0';
  2338. results.nprn[0] = '\0';
  2339. results.npcic[0] = '\0';
  2340. results.npdi = 0;
  2341. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  2342. results.opname[type][0] = '\0';
  2343. }
  2344. results.numdests = 0;
  2345. results.outtimelimit = OSP_DEF_TIMELIMIT;
  2346. results.outcallid.buf[0] = '\0';
  2347. results.outcallid.len = 0;
  2348. if (!res) {
  2349. status = AST_OSP_FAILED;
  2350. } else {
  2351. status = AST_OSP_ERROR;
  2352. }
  2353. }
  2354. snprintf(buffer, sizeof(buffer), "%d", results.outhandle);
  2355. pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
  2356. ast_debug(1, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
  2357. pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.outtech);
  2358. ast_debug(1, "OSPLookup: OSPOUTTECH '%s'\n", results.outtech);
  2359. pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
  2360. ast_debug(1, "OSPLookup: OSPDESTINATION '%s'\n", results.dest);
  2361. pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
  2362. ast_debug(1, "OSPLookup: OSPOUTCALLING '%s'\n", results.calling);
  2363. pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
  2364. ast_debug(1, "OSPLookup: OSPOUTCALLED '%s'\n", results.called);
  2365. pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
  2366. ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
  2367. pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
  2368. ast_debug(1, "OSPLookup: OSPOUTNPRN '%s'\n", results.nprn);
  2369. pbx_builtin_setvar_helper(chan, "OSPOUTNPCIC", results.npcic);
  2370. ast_debug(1, "OSPLookup: OSPOUTNPCIC '%s'\n", results.npcic);
  2371. snprintf(buffer, sizeof(buffer), "%d", results.npdi);
  2372. pbx_builtin_setvar_helper(chan, "OSPOUTNPDI", buffer);
  2373. ast_debug(1, "OSPLookup: OSPOUTNPDI'%s'\n", buffer);
  2374. pbx_builtin_setvar_helper(chan, "OSPOUTSPID", results.opname[OSPC_OPNAME_SPID]);
  2375. ast_debug(1, "OSPLookup: OSPOUTSPID '%s'\n", results.opname[OSPC_OPNAME_SPID]);
  2376. pbx_builtin_setvar_helper(chan, "OSPOUTOCN", results.opname[OSPC_OPNAME_OCN]);
  2377. ast_debug(1, "OSPLookup: OSPOUTOCN '%s'\n", results.opname[OSPC_OPNAME_OCN]);
  2378. pbx_builtin_setvar_helper(chan, "OSPOUTSPN", results.opname[OSPC_OPNAME_SPN]);
  2379. ast_debug(1, "OSPLookup: OSPOUTSPN '%s'\n", results.opname[OSPC_OPNAME_SPN]);
  2380. pbx_builtin_setvar_helper(chan, "OSPOUTALTSPN", results.opname[OSPC_OPNAME_ALTSPN]);
  2381. ast_debug(1, "OSPLookup: OSPOUTALTSPN '%s'\n", results.opname[OSPC_OPNAME_ALTSPN]);
  2382. pbx_builtin_setvar_helper(chan, "OSPOUTMCC", results.opname[OSPC_OPNAME_MCC]);
  2383. ast_debug(1, "OSPLookup: OSPOUTMCC '%s'\n", results.opname[OSPC_OPNAME_MCC]);
  2384. pbx_builtin_setvar_helper(chan, "OSPOUTMNC", results.opname[OSPC_OPNAME_MNC]);
  2385. ast_debug(1, "OSPLookup: OSPOUTMNC '%s'\n", results.opname[OSPC_OPNAME_MNC]);
  2386. pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
  2387. ast_debug(1, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
  2388. snprintf(buffer, sizeof(buffer), "%d", results.numdests);
  2389. pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
  2390. ast_debug(1, "OSPLookup: OSPDESTREMAILS '%s'\n", buffer);
  2391. snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
  2392. pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
  2393. ast_debug(1, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
  2394. snprintf(buffer, sizeof(buffer), "%d", callidtypes);
  2395. pbx_builtin_setvar_helper(chan, "OSPOUTCALLIDTYPES", buffer);
  2396. ast_debug(1, "OSPLookup: OSPOUTCALLIDTYPES '%s'\n", buffer);
  2397. pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
  2398. ast_debug(1, "OSPLookup: %s\n", status);
  2399. if (!strcasecmp(results.outtech, OSP_TECH_SIP)) {
  2400. snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
  2401. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2402. if (!ast_strlen_zero(results.token)) {
  2403. snprintf(buffer, sizeof(buffer), "%s: %s", OSP_SIP_HEADER, results.token);
  2404. pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
  2405. ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
  2406. }
  2407. } else if (!strcasecmp(results.outtech, OSP_TECH_H323)) {
  2408. if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
  2409. osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
  2410. } else {
  2411. buffer[0] = '\0';
  2412. }
  2413. pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
  2414. snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
  2415. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2416. } else if (!strcasecmp(results.outtech, OSP_TECH_IAX)) {
  2417. snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.outtech, results.dest, results.called);
  2418. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2419. } else if (!strcasecmp(results.outtech, OSP_TECH_SKYPE)) {
  2420. snprintf(buffer, sizeof(buffer), "%s/%s", results.outtech, results.called);
  2421. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2422. }
  2423. if (ast_autoservice_stop(chan) < 0) {
  2424. return OSP_AST_ERROR;
  2425. }
  2426. if(res != OSP_OK) {
  2427. res = OSP_AST_ERROR;
  2428. } else {
  2429. res = OSP_AST_OK;
  2430. }
  2431. return res;
  2432. }
  2433. /*!
  2434. * \brief OSP Application OSPNext
  2435. * \param chan Channel
  2436. * \param data Parameter
  2437. * \return OSP_AST_OK Success, OSP_AST_ERROR Error
  2438. */
  2439. static int ospnext_exec(
  2440. struct ast_channel* chan,
  2441. const char * data)
  2442. {
  2443. int res;
  2444. const char* provider = OSP_DEF_PROVIDER;
  2445. int cause = 0;
  2446. struct varshead* headp;
  2447. struct ast_var_t* current;
  2448. struct osp_results results;
  2449. OSPE_OPERATOR_NAME type;
  2450. char buffer[OSP_SIZE_TOKSTR];
  2451. unsigned int callidtypes = OSP_CALLID_UNDEF;
  2452. const char* status;
  2453. char* tmp;
  2454. AST_DECLARE_APP_ARGS(args,
  2455. AST_APP_ARG(cause);
  2456. AST_APP_ARG(provider);
  2457. AST_APP_ARG(options);
  2458. );
  2459. if (ast_strlen_zero(data)) {
  2460. ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[,provider[,options]])\n");
  2461. return OSP_AST_ERROR;
  2462. }
  2463. tmp = ast_strdupa(data);
  2464. AST_STANDARD_APP_ARGS(args, tmp);
  2465. if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
  2466. cause = 0;
  2467. }
  2468. ast_debug(1, "OSPNext: cause '%d'\n", cause);
  2469. if (!ast_strlen_zero(args.provider)) {
  2470. provider = args.provider;
  2471. }
  2472. ast_debug(1, "OSPlookup: provider '%s'\n", provider);
  2473. results.inhandle = OSP_INVALID_HANDLE;
  2474. results.outhandle = OSP_INVALID_HANDLE;
  2475. results.intimelimit = OSP_DEF_TIMELIMIT;
  2476. results.numdests = 0;
  2477. headp = ast_channel_varshead(chan);
  2478. AST_LIST_TRAVERSE(headp, current, entries) {
  2479. if (!strcmp(ast_var_name(current), "OSPINHANDLE")) {
  2480. if (sscanf(ast_var_value(current), "%30d", &results.inhandle) != 1) {
  2481. results.inhandle = OSP_INVALID_HANDLE;
  2482. }
  2483. } else if (!strcmp(ast_var_name(current), "OSPOUTHANDLE")) {
  2484. if (sscanf(ast_var_value(current), "%30d", &results.outhandle) != 1) {
  2485. results.outhandle = OSP_INVALID_HANDLE;
  2486. }
  2487. } else if (!strcmp(ast_var_name(current), "OSPINTIMELIMIT")) {
  2488. if (sscanf(ast_var_value(current), "%30d", &results.intimelimit) != 1) {
  2489. results.intimelimit = OSP_DEF_TIMELIMIT;
  2490. }
  2491. } else if (!strcmp(ast_var_name(current), "OSPOUTCALLIDTYPES")) {
  2492. if (sscanf(ast_var_value(current), "%30d", &callidtypes) != 1) {
  2493. callidtypes = OSP_CALLID_UNDEF;
  2494. }
  2495. } else if (!strcmp(ast_var_name(current), "OSPDESTREMAILS")) {
  2496. if (sscanf(ast_var_value(current), "%30d", &results.numdests) != 1) {
  2497. results.numdests = 0;
  2498. }
  2499. }
  2500. }
  2501. ast_debug(1, "OSPNext: OSPINHANDLE '%d'\n", results.inhandle);
  2502. ast_debug(1, "OSPNext: OSPOUTHANDLE '%d'\n", results.outhandle);
  2503. ast_debug(1, "OSPNext: OSPINTIMELIMIT '%d'\n", results.intimelimit);
  2504. ast_debug(1, "OSPNext: OSPOUTCALLIDTYPES '%d'\n", callidtypes);
  2505. ast_debug(1, "OSPNext: OSPDESTREMAILS '%d'\n", results.numdests);
  2506. if ((res = osp_next(provider, cause, &results)) > 0) {
  2507. status = AST_OSP_SUCCESS;
  2508. } else {
  2509. results.outtech[0] = '\0';
  2510. results.dest[0] = '\0';
  2511. results.calling[0] = '\0';
  2512. results.called[0] = '\0';
  2513. results.token[0] = '\0';
  2514. results.networkid[0] = '\0';
  2515. results.nprn[0] = '\0';
  2516. results.npcic[0] = '\0';
  2517. results.npdi = 0;
  2518. for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
  2519. results.opname[type][0] = '\0';
  2520. }
  2521. results.numdests = 0;
  2522. results.outtimelimit = OSP_DEF_TIMELIMIT;
  2523. results.outcallid.buf[0] = '\0';
  2524. results.outcallid.len = 0;
  2525. if (!res) {
  2526. status = AST_OSP_FAILED;
  2527. } else {
  2528. status = AST_OSP_ERROR;
  2529. }
  2530. }
  2531. pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.outtech);
  2532. ast_debug(1, "OSPNext: OSPOUTTECH '%s'\n", results.outtech);
  2533. pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
  2534. ast_debug(1, "OSPNext: OSPDESTINATION '%s'\n", results.dest);
  2535. pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
  2536. ast_debug(1, "OSPNext: OSPOUTCALLING '%s'\n", results.calling);
  2537. pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
  2538. ast_debug(1, "OSPNext: OSPOUTCALLED'%s'\n", results.called);
  2539. pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
  2540. ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
  2541. pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
  2542. ast_debug(1, "OSPLookup: OSPOUTNPRN '%s'\n", results.nprn);
  2543. pbx_builtin_setvar_helper(chan, "OSPOUTNPCIC", results.npcic);
  2544. ast_debug(1, "OSPLookup: OSPOUTNPCIC '%s'\n", results.npcic);
  2545. snprintf(buffer, sizeof(buffer), "%d", results.npdi);
  2546. pbx_builtin_setvar_helper(chan, "OSPOUTNPDI", buffer);
  2547. ast_debug(1, "OSPLookup: OSPOUTNPDI'%s'\n", buffer);
  2548. pbx_builtin_setvar_helper(chan, "OSPOUTSPID", results.opname[OSPC_OPNAME_SPID]);
  2549. ast_debug(1, "OSPLookup: OSPOUTSPID '%s'\n", results.opname[OSPC_OPNAME_SPID]);
  2550. pbx_builtin_setvar_helper(chan, "OSPOUTOCN", results.opname[OSPC_OPNAME_OCN]);
  2551. ast_debug(1, "OSPLookup: OSPOUTOCN '%s'\n", results.opname[OSPC_OPNAME_OCN]);
  2552. pbx_builtin_setvar_helper(chan, "OSPOUTSPN", results.opname[OSPC_OPNAME_SPN]);
  2553. ast_debug(1, "OSPLookup: OSPOUTSPN '%s'\n", results.opname[OSPC_OPNAME_SPN]);
  2554. pbx_builtin_setvar_helper(chan, "OSPOUTALTSPN", results.opname[OSPC_OPNAME_ALTSPN]);
  2555. ast_debug(1, "OSPLookup: OSPOUTALTSPN '%s'\n", results.opname[OSPC_OPNAME_ALTSPN]);
  2556. pbx_builtin_setvar_helper(chan, "OSPOUTMCC", results.opname[OSPC_OPNAME_MCC]);
  2557. ast_debug(1, "OSPLookup: OSPOUTMCC '%s'\n", results.opname[OSPC_OPNAME_MCC]);
  2558. pbx_builtin_setvar_helper(chan, "OSPOUTMNC", results.opname[OSPC_OPNAME_MNC]);
  2559. ast_debug(1, "OSPLookup: OSPOUTMNC '%s'\n", results.opname[OSPC_OPNAME_MNC]);
  2560. pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
  2561. ast_debug(1, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
  2562. snprintf(buffer, sizeof(buffer), "%d", results.numdests);
  2563. pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
  2564. ast_debug(1, "OSPNext: OSPDESTREMAILS '%s'\n", buffer);
  2565. snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
  2566. pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
  2567. ast_debug(1, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
  2568. pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
  2569. ast_debug(1, "OSPNext: %s\n", status);
  2570. if (!strcasecmp(results.outtech, OSP_TECH_SIP)) {
  2571. snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
  2572. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2573. if (!ast_strlen_zero(results.token)) {
  2574. snprintf(buffer, sizeof(buffer), "%s: %s", OSP_SIP_HEADER, results.token);
  2575. pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
  2576. ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
  2577. }
  2578. } else if (!strcasecmp(results.outtech, OSP_TECH_H323)) {
  2579. if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
  2580. osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
  2581. } else {
  2582. buffer[0] = '\0';
  2583. }
  2584. pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
  2585. snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
  2586. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2587. } else if (!strcasecmp(results.outtech, OSP_TECH_IAX)) {
  2588. snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.outtech, results.dest, results.called);
  2589. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2590. } else if (!strcasecmp(results.outtech, OSP_TECH_SKYPE)) {
  2591. snprintf(buffer, sizeof(buffer), "%s/%s", results.outtech, results.called);
  2592. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  2593. }
  2594. if(res != OSP_OK) {
  2595. res = OSP_AST_ERROR;
  2596. } else {
  2597. res = OSP_AST_OK;
  2598. }
  2599. return res;
  2600. }
  2601. /*!
  2602. * \brief OSP Application OSPFinish
  2603. * \param chan Channel
  2604. * \param data Parameter
  2605. * \return OSP_AST_OK Success, OSP_AST_ERROR Error
  2606. */
  2607. static int ospfinished_exec(
  2608. struct ast_channel* chan,
  2609. const char * data)
  2610. {
  2611. int res = OSP_OK;
  2612. int cause = 0;
  2613. struct varshead* headp;
  2614. struct ast_var_t* current;
  2615. int inhandle = OSP_INVALID_HANDLE;
  2616. int outhandle = OSP_INVALID_HANDLE;
  2617. int recorded = 0;
  2618. time_t start = 0, connect = 0, end = 0;
  2619. unsigned int release;
  2620. char buffer[OSP_SIZE_INTSTR];
  2621. char inqos[OSP_SIZE_QOSSTR] = { 0 };
  2622. char outqos[OSP_SIZE_QOSSTR] = { 0 };
  2623. const char* status;
  2624. char* tmp;
  2625. AST_DECLARE_APP_ARGS(args,
  2626. AST_APP_ARG(cause);
  2627. AST_APP_ARG(options);
  2628. );
  2629. tmp = ast_strdupa(data);
  2630. AST_STANDARD_APP_ARGS(args, tmp);
  2631. headp = ast_channel_varshead(chan);
  2632. AST_LIST_TRAVERSE(headp, current, entries) {
  2633. if (!strcmp(ast_var_name(current), "OSPINHANDLE")) {
  2634. if (sscanf(ast_var_value(current), "%30d", &inhandle) != 1) {
  2635. inhandle = OSP_INVALID_HANDLE;
  2636. }
  2637. } else if (!strcmp(ast_var_name(current), "OSPOUTHANDLE")) {
  2638. if (sscanf(ast_var_value(current), "%30d", &outhandle) != 1) {
  2639. outhandle = OSP_INVALID_HANDLE;
  2640. }
  2641. } else if (!recorded &&
  2642. (!strcmp(ast_var_name(current), "OSPAUTHSTATUS") ||
  2643. !strcmp(ast_var_name(current), "OSPLOOKUPSTATUS") ||
  2644. !strcmp(ast_var_name(current), "OSPNEXTSTATUS")))
  2645. {
  2646. if (strcmp(ast_var_value(current), AST_OSP_SUCCESS)) {
  2647. recorded = 1;
  2648. }
  2649. } else if (!strcmp(ast_var_name(current), "OSPINAUDIOQOS")) {
  2650. ast_copy_string(inqos, ast_var_value(current), sizeof(inqos));
  2651. } else if (!strcmp(ast_var_name(current), "OSPOUTAUDIOQOS")) {
  2652. ast_copy_string(outqos, ast_var_value(current), sizeof(outqos));
  2653. }
  2654. }
  2655. ast_debug(1, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
  2656. ast_debug(1, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
  2657. ast_debug(1, "OSPFinish: recorded '%d'\n", recorded);
  2658. ast_debug(1, "OSPFinish: OSPINAUDIOQOS '%s'\n", inqos);
  2659. ast_debug(1, "OSPFinish: OSPOUTAUDIOQOS '%s'\n", outqos);
  2660. if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
  2661. cause = 0;
  2662. }
  2663. ast_debug(1, "OSPFinish: cause '%d'\n", cause);
  2664. if (!ast_tvzero(ast_channel_creationtime(chan))) {
  2665. start = ast_channel_creationtime(chan).tv_sec;
  2666. }
  2667. if (!ast_tvzero(ast_channel_answertime(chan))) {
  2668. connect = ast_channel_answertime(chan).tv_sec;
  2669. }
  2670. if (connect) {
  2671. end = time(NULL);
  2672. } else {
  2673. end = connect;
  2674. }
  2675. ast_debug(1, "OSPFinish: start '%ld'\n", start);
  2676. ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
  2677. ast_debug(1, "OSPFinish: end '%ld'\n", end);
  2678. release = ast_check_hangup(chan) ? 0 : 1;
  2679. if (osp_finish(outhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
  2680. ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
  2681. }
  2682. switch (cause) {
  2683. case AST_CAUSE_NORMAL_CLEARING:
  2684. break;
  2685. default:
  2686. cause = AST_CAUSE_NO_ROUTE_DESTINATION;
  2687. break;
  2688. }
  2689. if (osp_finish(inhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
  2690. ast_debug(1, "OSPFinish: Unable to report usage for inbound call\n");
  2691. }
  2692. snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);
  2693. pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
  2694. pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
  2695. if (res > 0) {
  2696. status = AST_OSP_SUCCESS;
  2697. } else if (!res) {
  2698. status = AST_OSP_FAILED;
  2699. } else {
  2700. status = AST_OSP_ERROR;
  2701. }
  2702. pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status);
  2703. if(res != OSP_OK) {
  2704. res = OSP_AST_ERROR;
  2705. } else {
  2706. res = OSP_AST_OK;
  2707. }
  2708. return res;
  2709. }
  2710. /* OSP Module APIs */
  2711. static int osp_unload(void)
  2712. {
  2713. struct osp_provider* provider;
  2714. struct osp_provider* next;
  2715. if (osp_initialized) {
  2716. ast_mutex_lock(&osp_lock);
  2717. for (provider = osp_providers; provider; provider = next) {
  2718. next = provider->next;
  2719. OSPPProviderDelete(provider->handle, 0);
  2720. ast_free(provider);
  2721. }
  2722. osp_providers = NULL;
  2723. ast_mutex_unlock(&osp_lock);
  2724. OSPPCleanup();
  2725. osp_tokenformat = TOKEN_ALGO_SIGNED;
  2726. osp_security = 0;
  2727. osp_hardware = 0;
  2728. osp_initialized = 0;
  2729. }
  2730. return 0;
  2731. }
  2732. static int osp_load(int reload)
  2733. {
  2734. const char* cvar;
  2735. unsigned int ivar;
  2736. struct ast_config* cfg;
  2737. struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
  2738. int error = OSPC_ERR_NO_ERROR;
  2739. if ((cfg = ast_config_load(OSP_CONFIG_FILE, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
  2740. return 0;
  2741. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  2742. ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", OSP_CONFIG_FILE);
  2743. return 0;
  2744. }
  2745. if (cfg) {
  2746. if (reload) {
  2747. osp_unload();
  2748. }
  2749. if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate")) && ast_true(cvar)) {
  2750. if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
  2751. ast_log(LOG_WARNING, "OSP: Unable to enable hardware acceleration, error='%d'\n", error);
  2752. OSPPInit(0);
  2753. } else {
  2754. osp_hardware = 1;
  2755. }
  2756. } else {
  2757. OSPPInit(0);
  2758. }
  2759. ast_debug(1, "OSP: osp_hardware '%d'\n", osp_hardware);
  2760. if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "securityfeatures")) && ast_true(cvar)) {
  2761. osp_security = 1;
  2762. }
  2763. ast_debug(1, "OSP: osp_security '%d'\n", osp_security);
  2764. if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat"))) {
  2765. if ((sscanf(cvar, "%30d", &ivar) == 1) &&
  2766. ((ivar == TOKEN_ALGO_SIGNED) || (ivar == TOKEN_ALGO_UNSIGNED) || (ivar == TOKEN_ALGO_BOTH)))
  2767. {
  2768. osp_tokenformat = ivar;
  2769. } else {
  2770. ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
  2771. TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, cvar);
  2772. }
  2773. }
  2774. ast_debug(1, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);
  2775. for (cvar = ast_category_browse(cfg, NULL); cvar != NULL; cvar = ast_category_browse(cfg, cvar)) {
  2776. if (strcasecmp(cvar, OSP_GENERAL_CAT)) {
  2777. osp_create_provider(cfg, cvar);
  2778. }
  2779. }
  2780. osp_initialized = 1;
  2781. ast_config_destroy(cfg);
  2782. } else {
  2783. ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
  2784. return 0;
  2785. }
  2786. ast_debug(1, "OSP: osp_initialized '%d'\n", osp_initialized);
  2787. return 1;
  2788. }
  2789. static char *handle_cli_osp_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  2790. {
  2791. int i;
  2792. int found = 0;
  2793. struct osp_provider* provider;
  2794. const char* name = NULL;
  2795. const char* tokenalgo;
  2796. switch (cmd) {
  2797. case CLI_INIT:
  2798. e->command = "osp show";
  2799. e->usage =
  2800. "Usage: osp show\n"
  2801. " Displays information on Open Settlement Protocol support\n";
  2802. return NULL;
  2803. case CLI_GENERATE:
  2804. return NULL;
  2805. }
  2806. if ((a->argc < 2) || (a->argc > 3)) {
  2807. return CLI_SHOWUSAGE;
  2808. }
  2809. if (a->argc > 2) {
  2810. name = a->argv[2];
  2811. }
  2812. if (!name) {
  2813. switch (osp_tokenformat) {
  2814. case TOKEN_ALGO_BOTH:
  2815. tokenalgo = "Both";
  2816. break;
  2817. case TOKEN_ALGO_UNSIGNED:
  2818. tokenalgo = "Unsigned";
  2819. break;
  2820. case TOKEN_ALGO_SIGNED:
  2821. default:
  2822. tokenalgo = "Signed";
  2823. break;
  2824. }
  2825. ast_cli(a->fd, "OSP: %s/%s/%s/%s\n",
  2826. osp_initialized ? "Initialized" : "Uninitialized",
  2827. osp_hardware ? "Accelerated" : "Normal",
  2828. osp_security ? "Enabled" : "Disabled",
  2829. tokenalgo);
  2830. }
  2831. ast_mutex_lock(&osp_lock);
  2832. for (provider = osp_providers; provider; provider = provider->next) {
  2833. if (!name || !strcasecmp(provider->name, name)) {
  2834. if (found) {
  2835. ast_cli(a->fd, "\n");
  2836. }
  2837. ast_cli(a->fd, " == OSP Provider '%s' == \n", provider->name);
  2838. if (osp_security) {
  2839. ast_cli(a->fd, "Local Private Key: %s\n", provider->privatekey);
  2840. ast_cli(a->fd, "Local Certificate: %s\n", provider->localcert);
  2841. for (i = 0; i < provider->canum; i++) {
  2842. ast_cli(a->fd, "CA Certificate %d: %s\n", i + 1, provider->cacerts[i]);
  2843. }
  2844. }
  2845. for (i = 0; i < provider->spnum; i++) {
  2846. ast_cli(a->fd, "Service Point %d: %s\n", i + 1, provider->spoints[i]);
  2847. }
  2848. ast_cli(a->fd, "Max Connections: %d\n", provider->maxconnect);
  2849. ast_cli(a->fd, "Retry Delay: %d seconds\n", provider->retrydelay);
  2850. ast_cli(a->fd, "Retry Limit: %d\n", provider->retrylimit);
  2851. ast_cli(a->fd, "Timeout: %d milliseconds\n", provider->timeout);
  2852. ast_cli(a->fd, "Source: %s\n", strlen(provider->source) ? provider->source : "<unspecified>");
  2853. ast_cli(a->fd, "Auth Policy %d\n", provider->authpolicy);
  2854. ast_cli(a->fd, "Default protocol %s\n", provider->defprotocol);
  2855. ast_cli(a->fd, "Work mode %d\n", provider->workmode);
  2856. ast_cli(a->fd, "Service type %d\n", provider->srvtype);
  2857. ast_cli(a->fd, "OSP Handle: %d\n", provider->handle);
  2858. found++;
  2859. }
  2860. }
  2861. ast_mutex_unlock(&osp_lock);
  2862. if (!found) {
  2863. if (name) {
  2864. ast_cli(a->fd, "Unable to find OSP provider '%s'\n", name);
  2865. } else {
  2866. ast_cli(a->fd, "No OSP providers configured\n");
  2867. }
  2868. }
  2869. return CLI_SUCCESS;
  2870. }
  2871. /* OSPAuth() dialplan application */
  2872. static const char app1[] = "OSPAuth";
  2873. /* OSPLookup() dialplan application */
  2874. static const char app2[] = "OSPLookup";
  2875. /* OSPNext() dialplan application */
  2876. static const char app3[] = "OSPNext";
  2877. /* OSPFinish() dialplan application */
  2878. static const char app4[] = "OSPFinish";
  2879. static struct ast_cli_entry cli_osp[] = {
  2880. AST_CLI_DEFINE(handle_cli_osp_show, "Displays OSF information")
  2881. };
  2882. static int load_module(void)
  2883. {
  2884. int res;
  2885. if (!osp_load(0))
  2886. return AST_MODULE_LOAD_DECLINE;
  2887. ast_cli_register_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
  2888. res = ast_register_application_xml(app1, ospauth_exec);
  2889. res |= ast_register_application_xml(app2, osplookup_exec);
  2890. res |= ast_register_application_xml(app3, ospnext_exec);
  2891. res |= ast_register_application_xml(app4, ospfinished_exec);
  2892. return res;
  2893. }
  2894. static int unload_module(void)
  2895. {
  2896. int res;
  2897. res = ast_unregister_application(app4);
  2898. res |= ast_unregister_application(app3);
  2899. res |= ast_unregister_application(app2);
  2900. res |= ast_unregister_application(app1);
  2901. ast_cli_unregister_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
  2902. osp_unload();
  2903. return res;
  2904. }
  2905. static int reload(void)
  2906. {
  2907. osp_load(1);
  2908. return 0;
  2909. }
  2910. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Open Settlement Protocol Applications",
  2911. .support_level = AST_MODULE_SUPPORT_EXTENDED,
  2912. .load = load_module,
  2913. .unload = unload_module,
  2914. .reload = reload,
  2915. );