app_osplookup.c 105 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167
  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 + strlen(": ") + strlen(OSP_SIP_HEADER)];
  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 + strlen(": ") + strlen(OSP_SIP_HEADER)];
  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. );