sig_ss7.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2010 Digium, Inc.
  5. *
  6. * Richard Mudgett <rmudgett@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 SS7 signaling module.
  21. *
  22. * \author Matthew Fredrickson <creslin@digium.com>
  23. * \author Richard Mudgett <rmudgett@digium.com>
  24. *
  25. * See Also:
  26. * \arg \ref AstCREDITS
  27. */
  28. /*** MODULEINFO
  29. <support_level>core</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. #if defined(HAVE_SS7)
  33. #include <signal.h>
  34. #include "asterisk/pbx.h"
  35. #include "asterisk/causes.h"
  36. #include "asterisk/musiconhold.h"
  37. #include "asterisk/cli.h"
  38. #include "asterisk/transcap.h"
  39. #include "sig_ss7.h"
  40. #if defined(LIBSS7_ABI_COMPATIBILITY)
  41. #error "Your installed libss7 is not compatible"
  42. #endif
  43. /* ------------------------------------------------------------------- */
  44. static const char *sig_ss7_call_level2str(enum sig_ss7_call_level level)
  45. {
  46. switch (level) {
  47. case SIG_SS7_CALL_LEVEL_IDLE:
  48. return "Idle";
  49. case SIG_SS7_CALL_LEVEL_ALLOCATED:
  50. return "Allocated";
  51. case SIG_SS7_CALL_LEVEL_CONTINUITY:
  52. return "Continuity";
  53. case SIG_SS7_CALL_LEVEL_SETUP:
  54. return "Setup";
  55. case SIG_SS7_CALL_LEVEL_PROCEEDING:
  56. return "Proceeding";
  57. case SIG_SS7_CALL_LEVEL_ALERTING:
  58. return "Alerting";
  59. case SIG_SS7_CALL_LEVEL_CONNECT:
  60. return "Connect";
  61. case SIG_SS7_CALL_LEVEL_GLARE:
  62. return "Glare";
  63. }
  64. return "Unknown";
  65. }
  66. static void sig_ss7_unlock_private(struct sig_ss7_chan *p)
  67. {
  68. if (p->calls->unlock_private) {
  69. p->calls->unlock_private(p->chan_pvt);
  70. }
  71. }
  72. static void sig_ss7_lock_private(struct sig_ss7_chan *p)
  73. {
  74. if (p->calls->lock_private) {
  75. p->calls->lock_private(p->chan_pvt);
  76. }
  77. }
  78. static void sig_ss7_deadlock_avoidance_private(struct sig_ss7_chan *p)
  79. {
  80. if (p->calls->deadlock_avoidance_private) {
  81. p->calls->deadlock_avoidance_private(p->chan_pvt);
  82. } else {
  83. /* Fallback to the old way if callback not present. */
  84. sig_ss7_unlock_private(p);
  85. sched_yield();
  86. sig_ss7_lock_private(p);
  87. }
  88. }
  89. void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
  90. {
  91. p->inalarm = in_alarm;
  92. if (p->calls->set_alarm) {
  93. p->calls->set_alarm(p->chan_pvt, in_alarm);
  94. }
  95. }
  96. static void sig_ss7_set_dialing(struct sig_ss7_chan *p, int is_dialing)
  97. {
  98. if (p->calls->set_dialing) {
  99. p->calls->set_dialing(p->chan_pvt, is_dialing);
  100. }
  101. }
  102. static void sig_ss7_set_digital(struct sig_ss7_chan *p, int is_digital)
  103. {
  104. if (p->calls->set_digital) {
  105. p->calls->set_digital(p->chan_pvt, is_digital);
  106. }
  107. }
  108. static void sig_ss7_set_outgoing(struct sig_ss7_chan *p, int is_outgoing)
  109. {
  110. p->outgoing = is_outgoing;
  111. if (p->calls->set_outgoing) {
  112. p->calls->set_outgoing(p->chan_pvt, is_outgoing);
  113. }
  114. }
  115. static void sig_ss7_set_inservice(struct sig_ss7_chan *p, int is_inservice)
  116. {
  117. if (p->calls->set_inservice) {
  118. p->calls->set_inservice(p->chan_pvt, is_inservice);
  119. }
  120. }
  121. static void sig_ss7_set_locallyblocked(struct sig_ss7_chan *p, int is_blocked)
  122. {
  123. p->locallyblocked = is_blocked;
  124. if (p->calls->set_locallyblocked) {
  125. p->calls->set_locallyblocked(p->chan_pvt, is_blocked);
  126. }
  127. }
  128. static void sig_ss7_set_remotelyblocked(struct sig_ss7_chan *p, int is_blocked)
  129. {
  130. p->remotelyblocked = is_blocked;
  131. if (p->calls->set_remotelyblocked) {
  132. p->calls->set_remotelyblocked(p->chan_pvt, is_blocked);
  133. }
  134. }
  135. /*!
  136. * \internal
  137. * \brief Open the SS7 channel media path.
  138. * \since 1.8.12
  139. *
  140. * \param p Channel private control structure.
  141. *
  142. * \return Nothing
  143. */
  144. static void sig_ss7_open_media(struct sig_ss7_chan *p)
  145. {
  146. if (p->calls->open_media) {
  147. p->calls->open_media(p->chan_pvt);
  148. }
  149. }
  150. /*!
  151. * \internal
  152. * \brief Set the caller id information in the parent module.
  153. * \since 1.8
  154. *
  155. * \param p sig_ss7 channel structure.
  156. *
  157. * \return Nothing
  158. */
  159. static void sig_ss7_set_caller_id(struct sig_ss7_chan *p)
  160. {
  161. struct ast_party_caller caller;
  162. if (p->calls->set_callerid) {
  163. ast_party_caller_init(&caller);
  164. caller.id.name.str = p->cid_name;
  165. caller.id.name.presentation = p->callingpres;
  166. caller.id.name.valid = 1;
  167. caller.id.number.str = p->cid_num;
  168. caller.id.number.plan = p->cid_ton;
  169. caller.id.number.presentation = p->callingpres;
  170. caller.id.number.valid = 1;
  171. if (!ast_strlen_zero(p->cid_subaddr)) {
  172. caller.id.subaddress.valid = 1;
  173. //caller.id.subaddress.type = 0;/* nsap */
  174. //caller.id.subaddress.odd_even_indicator = 0;
  175. caller.id.subaddress.str = p->cid_subaddr;
  176. }
  177. caller.ani.number.str = p->cid_ani;
  178. //caller.ani.number.plan = p->xxx;
  179. //caller.ani.number.presentation = p->xxx;
  180. caller.ani.number.valid = 1;
  181. caller.ani2 = p->cid_ani2;
  182. p->calls->set_callerid(p->chan_pvt, &caller);
  183. }
  184. }
  185. /*!
  186. * \internal
  187. * \brief Set the Dialed Number Identifier.
  188. * \since 1.8
  189. *
  190. * \param p sig_ss7 channel structure.
  191. * \param dnid Dialed Number Identifier string.
  192. *
  193. * \return Nothing
  194. */
  195. static void sig_ss7_set_dnid(struct sig_ss7_chan *p, const char *dnid)
  196. {
  197. if (p->calls->set_dnid) {
  198. p->calls->set_dnid(p->chan_pvt, dnid);
  199. }
  200. }
  201. static int sig_ss7_play_tone(struct sig_ss7_chan *p, enum sig_ss7_tone tone)
  202. {
  203. int res;
  204. if (p->calls->play_tone) {
  205. res = p->calls->play_tone(p->chan_pvt, tone);
  206. } else {
  207. res = -1;
  208. }
  209. return res;
  210. }
  211. static int sig_ss7_set_echocanceller(struct sig_ss7_chan *p, int enable)
  212. {
  213. if (p->calls->set_echocanceller) {
  214. return p->calls->set_echocanceller(p->chan_pvt, enable);
  215. }
  216. return -1;
  217. }
  218. static void sig_ss7_loopback(struct sig_ss7_chan *p, int enable)
  219. {
  220. if (p->loopedback != enable) {
  221. p->loopedback = enable;
  222. if (p->calls->set_loopback) {
  223. p->calls->set_loopback(p->chan_pvt, enable);
  224. }
  225. }
  226. }
  227. static struct ast_channel *sig_ss7_new_ast_channel(struct sig_ss7_chan *p, int state, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor)
  228. {
  229. struct ast_channel *ast;
  230. if (p->calls->new_ast_channel) {
  231. ast = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor);
  232. } else {
  233. return NULL;
  234. }
  235. if (!ast) {
  236. return NULL;
  237. }
  238. if (!p->owner) {
  239. p->owner = ast;
  240. }
  241. p->alreadyhungup = 0;
  242. ast->transfercapability = transfercapability;
  243. pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY",
  244. ast_transfercapability2str(transfercapability));
  245. if (transfercapability & AST_TRANS_CAP_DIGITAL) {
  246. sig_ss7_set_digital(p, 1);
  247. }
  248. return ast;
  249. }
  250. static void sig_ss7_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
  251. {
  252. if (linkset->calls->handle_link_exception) {
  253. linkset->calls->handle_link_exception(linkset, which);
  254. }
  255. }
  256. /*!
  257. * \internal
  258. * \brief Determine if a private channel structure is available.
  259. *
  260. * \param pvt Channel to determine if available.
  261. *
  262. * \return TRUE if the channel is available.
  263. */
  264. static int sig_ss7_is_chan_available(struct sig_ss7_chan *pvt)
  265. {
  266. if (!pvt->inalarm && !pvt->owner && !pvt->ss7call
  267. && pvt->call_level == SIG_SS7_CALL_LEVEL_IDLE
  268. && !pvt->locallyblocked && !pvt->remotelyblocked) {
  269. return 1;
  270. }
  271. return 0;
  272. }
  273. /*!
  274. * \internal
  275. * \brief Obtain the sig_ss7 owner channel lock if the owner exists.
  276. * \since 1.8
  277. *
  278. * \param ss7 SS7 linkset control structure.
  279. * \param chanpos Channel position in the span.
  280. *
  281. * \note Assumes the ss7->lock is already obtained.
  282. * \note Assumes the sig_ss7_lock_private(ss7->pvts[chanpos]) is already obtained.
  283. *
  284. * \return Nothing
  285. */
  286. static void sig_ss7_lock_owner(struct sig_ss7_linkset *ss7, int chanpos)
  287. {
  288. for (;;) {
  289. if (!ss7->pvts[chanpos]->owner) {
  290. /* There is no owner lock to get. */
  291. break;
  292. }
  293. if (!ast_channel_trylock(ss7->pvts[chanpos]->owner)) {
  294. /* We got the lock */
  295. break;
  296. }
  297. /* Avoid deadlock */
  298. sig_ss7_unlock_private(ss7->pvts[chanpos]);
  299. DEADLOCK_AVOIDANCE(&ss7->lock);
  300. sig_ss7_lock_private(ss7->pvts[chanpos]);
  301. }
  302. }
  303. /*!
  304. * \internal
  305. * \brief Queue the given frame onto the owner channel.
  306. * \since 1.8
  307. *
  308. * \param ss7 SS7 linkset control structure.
  309. * \param chanpos Channel position in the span.
  310. * \param frame Frame to queue onto the owner channel.
  311. *
  312. * \note Assumes the ss7->lock is already obtained.
  313. * \note Assumes the sig_ss7_lock_private(ss7->pvts[chanpos]) is already obtained.
  314. *
  315. * \return Nothing
  316. */
  317. static void sig_ss7_queue_frame(struct sig_ss7_linkset *ss7, int chanpos, struct ast_frame *frame)
  318. {
  319. sig_ss7_lock_owner(ss7, chanpos);
  320. if (ss7->pvts[chanpos]->owner) {
  321. ast_queue_frame(ss7->pvts[chanpos]->owner, frame);
  322. ast_channel_unlock(ss7->pvts[chanpos]->owner);
  323. }
  324. }
  325. /*!
  326. * \internal
  327. * \brief Queue a control frame of the specified subclass onto the owner channel.
  328. * \since 1.8
  329. *
  330. * \param ss7 SS7 linkset control structure.
  331. * \param chanpos Channel position in the span.
  332. * \param subclass Control frame subclass to queue onto the owner channel.
  333. *
  334. * \note Assumes the ss7->lock is already obtained.
  335. * \note Assumes the sig_ss7_lock_private(ss7->pvts[chanpos]) is already obtained.
  336. *
  337. * \return Nothing
  338. */
  339. static void sig_ss7_queue_control(struct sig_ss7_linkset *ss7, int chanpos, int subclass)
  340. {
  341. struct ast_frame f = {AST_FRAME_CONTROL, };
  342. struct sig_ss7_chan *p = ss7->pvts[chanpos];
  343. if (p->calls->queue_control) {
  344. p->calls->queue_control(p->chan_pvt, subclass);
  345. }
  346. f.subclass.integer = subclass;
  347. sig_ss7_queue_frame(ss7, chanpos, &f);
  348. }
  349. /*!
  350. * \internal
  351. * \brief Find the channel position by CIC/DPC.
  352. *
  353. * \param linkset SS7 linkset control structure.
  354. * \param cic Circuit Identification Code
  355. * \param dpc Destination Point Code
  356. *
  357. * \retval chanpos on success.
  358. * \retval -1 on error.
  359. */
  360. static int ss7_find_cic(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc)
  361. {
  362. int i;
  363. int winner = -1;
  364. for (i = 0; i < linkset->numchans; i++) {
  365. if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && linkset->pvts[i]->cic == cic)) {
  366. winner = i;
  367. break;
  368. }
  369. }
  370. return winner;
  371. }
  372. /*!
  373. * \internal
  374. * \brief Find the channel position by CIC/DPC and gripe if not found.
  375. *
  376. * \param linkset SS7 linkset control structure.
  377. * \param cic Circuit Identification Code
  378. * \param dpc Destination Point Code
  379. * \param msg_name Message type name that failed.
  380. *
  381. * \retval chanpos on success.
  382. * \retval -1 on error.
  383. */
  384. static int ss7_find_cic_gripe(struct sig_ss7_linkset *linkset, int cic, unsigned int dpc, const char *msg_name)
  385. {
  386. int chanpos;
  387. chanpos = ss7_find_cic(linkset, cic, dpc);
  388. if (chanpos < 0) {
  389. ast_log(LOG_WARNING, "Linkset %d: SS7 %s requested unconfigured CIC/DPC %d/%d.\n",
  390. linkset->span, msg_name, cic, dpc);
  391. return -1;
  392. }
  393. return chanpos;
  394. }
  395. static void ss7_handle_cqm(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc)
  396. {
  397. unsigned char status[32];
  398. struct sig_ss7_chan *p = NULL;
  399. int i, offset;
  400. for (i = 0; i < linkset->numchans; i++) {
  401. if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
  402. p = linkset->pvts[i];
  403. offset = p->cic - startcic;
  404. status[offset] = 0;
  405. if (p->locallyblocked)
  406. status[offset] |= (1 << 0) | (1 << 4);
  407. if (p->remotelyblocked)
  408. status[offset] |= (1 << 1) | (1 << 5);
  409. if (p->ss7call) {
  410. if (p->outgoing)
  411. status[offset] |= (1 << 3);
  412. else
  413. status[offset] |= (1 << 2);
  414. } else
  415. status[offset] |= 0x3 << 2;
  416. }
  417. }
  418. if (p)
  419. isup_cqr(linkset->ss7, startcic, endcic, dpc, status);
  420. else
  421. ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n");
  422. }
  423. static inline void ss7_hangup_cics(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc)
  424. {
  425. int i;
  426. for (i = 0; i < linkset->numchans; i++) {
  427. if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
  428. sig_ss7_lock_private(linkset->pvts[i]);
  429. sig_ss7_lock_owner(linkset, i);
  430. if (linkset->pvts[i]->owner) {
  431. ast_softhangup_nolock(linkset->pvts[i]->owner, AST_SOFTHANGUP_DEV);
  432. ast_channel_unlock(linkset->pvts[i]->owner);
  433. }
  434. sig_ss7_unlock_private(linkset->pvts[i]);
  435. }
  436. }
  437. }
  438. static inline void ss7_block_cics(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block)
  439. {
  440. int i;
  441. /* XXX the use of state here seems questionable about matching up with the linkset channels */
  442. for (i = 0; i < linkset->numchans; i++) {
  443. if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
  444. if (state) {
  445. if (state[i])
  446. sig_ss7_set_remotelyblocked(linkset->pvts[i], block);
  447. } else
  448. sig_ss7_set_remotelyblocked(linkset->pvts[i], block);
  449. }
  450. }
  451. }
  452. static void ss7_inservice(struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc)
  453. {
  454. int i;
  455. for (i = 0; i < linkset->numchans; i++) {
  456. if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))))
  457. sig_ss7_set_inservice(linkset->pvts[i], 1);
  458. }
  459. }
  460. static void ss7_reset_linkset(struct sig_ss7_linkset *linkset)
  461. {
  462. int i, startcic = -1, endcic, dpc;
  463. if (linkset->numchans <= 0)
  464. return;
  465. startcic = linkset->pvts[0]->cic;
  466. /* DB: CIC's DPC fix */
  467. dpc = linkset->pvts[0]->dpc;
  468. for (i = 0; i < linkset->numchans; i++) {
  469. if (linkset->pvts[i+1] && linkset->pvts[i+1]->dpc == dpc && ((linkset->pvts[i+1]->cic - linkset->pvts[i]->cic) == 1) && (linkset->pvts[i]->cic - startcic < 31)) {
  470. continue;
  471. } else {
  472. endcic = linkset->pvts[i]->cic;
  473. ast_verbose("Resetting CICs %d to %d\n", startcic, endcic);
  474. isup_grs(linkset->ss7, startcic, endcic, dpc);
  475. /* DB: CIC's DPC fix */
  476. if (linkset->pvts[i+1]) {
  477. startcic = linkset->pvts[i+1]->cic;
  478. dpc = linkset->pvts[i+1]->dpc;
  479. }
  480. }
  481. }
  482. }
  483. /* This function is assumed to be called with the private channel lock and linkset lock held */
  484. static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *linkset)
  485. {
  486. struct ss7 *ss7 = linkset->ss7;
  487. int law;
  488. struct ast_channel *c;
  489. char tmp[256];
  490. if (!(linkset->flags & LINKSET_FLAG_EXPLICITACM)) {
  491. p->call_level = SIG_SS7_CALL_LEVEL_PROCEEDING;
  492. isup_acm(ss7, p->ss7call);
  493. } else {
  494. p->call_level = SIG_SS7_CALL_LEVEL_SETUP;
  495. }
  496. /* Companding law is determined by SS7 signaling type. */
  497. if (linkset->type == SS7_ITU) {
  498. law = SIG_SS7_ALAW;
  499. } else {
  500. law = SIG_SS7_ULAW;
  501. }
  502. /*
  503. * Release the SS7 lock while we create the channel so other
  504. * threads can send messages. We must also release the private
  505. * lock to prevent deadlock while creating the channel.
  506. */
  507. ast_mutex_unlock(&linkset->lock);
  508. sig_ss7_unlock_private(p);
  509. c = sig_ss7_new_ast_channel(p, AST_STATE_RING, law, 0, p->exten, NULL);
  510. if (!c) {
  511. ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
  512. ast_mutex_lock(&linkset->lock);
  513. sig_ss7_lock_private(p);
  514. isup_rel(linkset->ss7, p->ss7call, AST_CAUSE_SWITCH_CONGESTION);
  515. p->call_level = SIG_SS7_CALL_LEVEL_IDLE;
  516. p->alreadyhungup = 1;
  517. return;
  518. }
  519. /* Hold the channel and private lock while we setup the channel. */
  520. ast_channel_lock(c);
  521. sig_ss7_lock_private(p);
  522. sig_ss7_set_echocanceller(p, 1);
  523. /*
  524. * It is reasonably safe to set the following
  525. * channel variables while the channel private
  526. * structure is locked. The PBX has not been
  527. * started yet and it is unlikely that any other task
  528. * will do anything with the channel we have just
  529. * created.
  530. *
  531. * We only reference these variables in the context of the ss7_linkset function
  532. * when receiving either and IAM or a COT message.
  533. */
  534. if (!ast_strlen_zero(p->charge_number)) {
  535. pbx_builtin_setvar_helper(c, "SS7_CHARGE_NUMBER", p->charge_number);
  536. /* Clear this after we set it */
  537. p->charge_number[0] = 0;
  538. }
  539. if (!ast_strlen_zero(p->gen_add_number)) {
  540. pbx_builtin_setvar_helper(c, "SS7_GENERIC_ADDRESS", p->gen_add_number);
  541. /* Clear this after we set it */
  542. p->gen_add_number[0] = 0;
  543. }
  544. if (!ast_strlen_zero(p->jip_number)) {
  545. pbx_builtin_setvar_helper(c, "SS7_JIP", p->jip_number);
  546. /* Clear this after we set it */
  547. p->jip_number[0] = 0;
  548. }
  549. if (!ast_strlen_zero(p->gen_dig_number)) {
  550. pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGITS", p->gen_dig_number);
  551. /* Clear this after we set it */
  552. p->gen_dig_number[0] = 0;
  553. }
  554. if (!ast_strlen_zero(p->orig_called_num)) {
  555. pbx_builtin_setvar_helper(c, "SS7_ORIG_CALLED_NUM", p->orig_called_num);
  556. /* Clear this after we set it */
  557. p->orig_called_num[0] = 0;
  558. }
  559. snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_type);
  560. pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGTYPE", tmp);
  561. /* Clear this after we set it */
  562. p->gen_dig_type = 0;
  563. snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_scheme);
  564. pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGSCHEME", tmp);
  565. /* Clear this after we set it */
  566. p->gen_dig_scheme = 0;
  567. if (!ast_strlen_zero(p->lspi_ident)) {
  568. pbx_builtin_setvar_helper(c, "SS7_LSPI_IDENT", p->lspi_ident);
  569. /* Clear this after we set it */
  570. p->lspi_ident[0] = 0;
  571. }
  572. snprintf(tmp, sizeof(tmp), "%d", p->call_ref_ident);
  573. pbx_builtin_setvar_helper(c, "SS7_CALLREF_IDENT", tmp);
  574. /* Clear this after we set it */
  575. p->call_ref_ident = 0;
  576. snprintf(tmp, sizeof(tmp), "%d", p->call_ref_pc);
  577. pbx_builtin_setvar_helper(c, "SS7_CALLREF_PC", tmp);
  578. /* Clear this after we set it */
  579. p->call_ref_pc = 0;
  580. snprintf(tmp, sizeof(tmp), "%d", p->calling_party_cat);
  581. pbx_builtin_setvar_helper(c, "SS7_CALLING_PARTY_CATEGORY", tmp);
  582. /* Clear this after we set it */
  583. p->calling_party_cat = 0;
  584. if (!ast_strlen_zero(p->redirecting_num)) {
  585. pbx_builtin_setvar_helper(c, "SS7_REDIRECTING_NUMBER", p->redirecting_num);
  586. /* Clear this after we set it */
  587. p->redirecting_num[0] = 0;
  588. }
  589. if (!ast_strlen_zero(p->generic_name)) {
  590. pbx_builtin_setvar_helper(c, "SS7_GENERIC_NAME", p->generic_name);
  591. /* Clear this after we set it */
  592. p->generic_name[0] = 0;
  593. }
  594. sig_ss7_unlock_private(p);
  595. ast_channel_unlock(c);
  596. if (ast_pbx_start(c)) {
  597. ast_log(LOG_WARNING, "Unable to start PBX on %s (CIC %d)\n", c->name, p->cic);
  598. ast_hangup(c);
  599. } else {
  600. ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
  601. }
  602. /* Must return with linkset and private lock. */
  603. ast_mutex_lock(&linkset->lock);
  604. sig_ss7_lock_private(p);
  605. }
  606. static void ss7_apply_plan_to_number(char *buf, size_t size, const struct sig_ss7_linkset *ss7, const char *number, const unsigned nai)
  607. {
  608. if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */
  609. if (size) {
  610. *buf = '\0';
  611. }
  612. return;
  613. }
  614. switch (nai) {
  615. case SS7_NAI_INTERNATIONAL:
  616. snprintf(buf, size, "%s%s", ss7->internationalprefix, number);
  617. break;
  618. case SS7_NAI_NATIONAL:
  619. snprintf(buf, size, "%s%s", ss7->nationalprefix, number);
  620. break;
  621. case SS7_NAI_SUBSCRIBER:
  622. snprintf(buf, size, "%s%s", ss7->subscriberprefix, number);
  623. break;
  624. case SS7_NAI_UNKNOWN:
  625. snprintf(buf, size, "%s%s", ss7->unknownprefix, number);
  626. break;
  627. default:
  628. snprintf(buf, size, "%s", number);
  629. break;
  630. }
  631. }
  632. static int ss7_pres_scr2cid_pres(char presentation_ind, char screening_ind)
  633. {
  634. return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
  635. }
  636. /* This is a thread per linkset that handles all received events from libss7. */
  637. void *ss7_linkset(void *data)
  638. {
  639. int res, i;
  640. struct timeval *next = NULL, tv;
  641. struct sig_ss7_linkset *linkset = (struct sig_ss7_linkset *) data;
  642. struct ss7 *ss7 = linkset->ss7;
  643. ss7_event *e = NULL;
  644. struct sig_ss7_chan *p;
  645. int chanpos;
  646. struct pollfd pollers[SIG_SS7_NUM_DCHANS];
  647. int nextms = 0;
  648. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  649. ss7_set_debug(ss7, SIG_SS7_DEBUG_DEFAULT);
  650. ast_mutex_lock(&linkset->lock);
  651. ss7_start(ss7);
  652. ast_mutex_unlock(&linkset->lock);
  653. for (;;) {
  654. ast_mutex_lock(&linkset->lock);
  655. if ((next = ss7_schedule_next(ss7))) {
  656. tv = ast_tvnow();
  657. tv.tv_sec = next->tv_sec - tv.tv_sec;
  658. tv.tv_usec = next->tv_usec - tv.tv_usec;
  659. if (tv.tv_usec < 0) {
  660. tv.tv_usec += 1000000;
  661. tv.tv_sec -= 1;
  662. }
  663. if (tv.tv_sec < 0) {
  664. tv.tv_sec = 0;
  665. tv.tv_usec = 0;
  666. }
  667. nextms = tv.tv_sec * 1000;
  668. nextms += tv.tv_usec / 1000;
  669. }
  670. for (i = 0; i < linkset->numsigchans; i++) {
  671. pollers[i].fd = linkset->fds[i];
  672. pollers[i].events = ss7_pollflags(ss7, linkset->fds[i]);
  673. pollers[i].revents = 0;
  674. }
  675. ast_mutex_unlock(&linkset->lock);
  676. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  677. pthread_testcancel();
  678. res = poll(pollers, linkset->numsigchans, nextms);
  679. pthread_testcancel();
  680. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  681. if ((res < 0) && (errno != EINTR)) {
  682. ast_log(LOG_ERROR, "poll(%s)\n", strerror(errno));
  683. } else if (!res) {
  684. ast_mutex_lock(&linkset->lock);
  685. ss7_schedule_run(ss7);
  686. ast_mutex_unlock(&linkset->lock);
  687. continue;
  688. }
  689. ast_mutex_lock(&linkset->lock);
  690. for (i = 0; i < linkset->numsigchans; i++) {
  691. if (pollers[i].revents & POLLPRI) {
  692. sig_ss7_handle_link_exception(linkset, i);
  693. }
  694. if (pollers[i].revents & POLLIN) {
  695. res = ss7_read(ss7, pollers[i].fd);
  696. }
  697. if (pollers[i].revents & POLLOUT) {
  698. res = ss7_write(ss7, pollers[i].fd);
  699. if (res < 0) {
  700. ast_debug(1, "Error in write %s\n", strerror(errno));
  701. }
  702. }
  703. }
  704. while ((e = ss7_check_event(ss7))) {
  705. if (linkset->debug) {
  706. ast_verbose("Linkset %d: Processing event: %s\n",
  707. linkset->span, ss7_event2str(e->e));
  708. }
  709. switch (e->e) {
  710. case SS7_EVENT_UP:
  711. if (linkset->state != LINKSET_STATE_UP) {
  712. ast_verbose("--- SS7 Up ---\n");
  713. ss7_reset_linkset(linkset);
  714. }
  715. linkset->state = LINKSET_STATE_UP;
  716. break;
  717. case SS7_EVENT_DOWN:
  718. ast_verbose("--- SS7 Down ---\n");
  719. linkset->state = LINKSET_STATE_DOWN;
  720. for (i = 0; i < linkset->numchans; i++) {
  721. p = linkset->pvts[i];
  722. if (p) {
  723. sig_ss7_set_alarm(p, 1);
  724. }
  725. }
  726. break;
  727. case MTP2_LINK_UP:
  728. ast_verbose("MTP2 link up (SLC %d)\n", e->gen.data);
  729. break;
  730. case MTP2_LINK_DOWN:
  731. ast_log(LOG_WARNING, "MTP2 link down (SLC %d)\n", e->gen.data);
  732. break;
  733. case ISUP_EVENT_CPG:
  734. chanpos = ss7_find_cic_gripe(linkset, e->cpg.cic, e->cpg.opc, "CPG");
  735. if (chanpos < 0) {
  736. break;
  737. }
  738. p = linkset->pvts[chanpos];
  739. sig_ss7_lock_private(p);
  740. switch (e->cpg.event) {
  741. case CPG_EVENT_ALERTING:
  742. if (p->call_level < SIG_SS7_CALL_LEVEL_ALERTING) {
  743. p->call_level = SIG_SS7_CALL_LEVEL_ALERTING;
  744. }
  745. sig_ss7_lock_owner(linkset, chanpos);
  746. if (p->owner) {
  747. ast_setstate(p->owner, AST_STATE_RINGING);
  748. ast_channel_unlock(p->owner);
  749. }
  750. sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_RINGING);
  751. break;
  752. case CPG_EVENT_PROGRESS:
  753. case CPG_EVENT_INBANDINFO:
  754. {
  755. ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic);
  756. sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_PROGRESS);
  757. p->progress = 1;
  758. sig_ss7_set_dialing(p, 0);
  759. sig_ss7_open_media(p);
  760. }
  761. break;
  762. default:
  763. ast_debug(1, "Do not handle CPG with event type 0x%x\n", e->cpg.event);
  764. break;
  765. }
  766. sig_ss7_unlock_private(p);
  767. break;
  768. case ISUP_EVENT_RSC:
  769. ast_verbose("Resetting CIC %d\n", e->rsc.cic);
  770. chanpos = ss7_find_cic_gripe(linkset, e->rsc.cic, e->rsc.opc, "RSC");
  771. if (chanpos < 0) {
  772. break;
  773. }
  774. p = linkset->pvts[chanpos];
  775. sig_ss7_lock_private(p);
  776. sig_ss7_set_inservice(p, 1);
  777. sig_ss7_set_remotelyblocked(p, 0);
  778. isup_set_call_dpc(e->rsc.call, p->dpc);
  779. sig_ss7_lock_owner(linkset, chanpos);
  780. p->ss7call = NULL;
  781. if (p->owner) {
  782. ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
  783. ast_channel_unlock(p->owner);
  784. }
  785. sig_ss7_unlock_private(p);
  786. isup_rlc(ss7, e->rsc.call);
  787. break;
  788. case ISUP_EVENT_GRS:
  789. ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
  790. chanpos = ss7_find_cic_gripe(linkset, e->grs.startcic, e->grs.opc, "GRS");
  791. if (chanpos < 0) {
  792. break;
  793. }
  794. p = linkset->pvts[chanpos];
  795. isup_gra(ss7, e->grs.startcic, e->grs.endcic, e->grs.opc);
  796. ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0);
  797. ss7_hangup_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc);
  798. break;
  799. case ISUP_EVENT_CQM:
  800. ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic);
  801. ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic, e->cqm.opc);
  802. break;
  803. case ISUP_EVENT_GRA:
  804. ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
  805. ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
  806. ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status, 1);
  807. break;
  808. case ISUP_EVENT_IAM:
  809. ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
  810. chanpos = ss7_find_cic_gripe(linkset, e->iam.cic, e->iam.opc, "IAM");
  811. if (chanpos < 0) {
  812. isup_rel(ss7, e->iam.call, -1);
  813. break;
  814. }
  815. p = linkset->pvts[chanpos];
  816. sig_ss7_lock_private(p);
  817. sig_ss7_lock_owner(linkset, chanpos);
  818. if (p->call_level != SIG_SS7_CALL_LEVEL_IDLE) {
  819. /*
  820. * Detected glare/dual-seizure
  821. *
  822. * Always abort both calls since we can't implement the dual
  823. * seizure procedures due to our channel assignment architecture
  824. * and the fact that we cannot tell libss7 to discard its call
  825. * structure to ignore the incoming IAM.
  826. */
  827. ast_debug(1,
  828. "Linkset %d: SS7 IAM glare on CIC/DPC %d/%d. Dropping both calls.\n",
  829. linkset->span, e->iam.cic, e->iam.opc);
  830. if (p->call_level == SIG_SS7_CALL_LEVEL_ALLOCATED) {
  831. /*
  832. * We have not sent our IAM yet and we never will at this point.
  833. */
  834. p->alreadyhungup = 1;
  835. isup_rel(ss7, e->iam.call, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
  836. }
  837. p->call_level = SIG_SS7_CALL_LEVEL_GLARE;
  838. if (p->owner) {
  839. p->owner->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
  840. ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
  841. ast_channel_unlock(p->owner);
  842. }
  843. sig_ss7_unlock_private(p);
  844. break;
  845. }
  846. /*
  847. * The channel should not have an owner at this point since we
  848. * are in the process of creating an owner for it.
  849. */
  850. ast_assert(!p->owner);
  851. if (!sig_ss7_is_chan_available(p)) {
  852. /* Circuit is likely blocked or in alarm. */
  853. isup_rel(ss7, e->iam.call, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
  854. sig_ss7_unlock_private(p);
  855. break;
  856. }
  857. /* Mark channel as in use so no outgoing call will steal it. */
  858. p->call_level = SIG_SS7_CALL_LEVEL_ALLOCATED;
  859. p->ss7call = e->iam.call;
  860. isup_set_call_dpc(p->ss7call, p->dpc);
  861. if ((p->use_callerid) && (!ast_strlen_zero(e->iam.calling_party_num))) {
  862. ss7_apply_plan_to_number(p->cid_num, sizeof(p->cid_num), linkset, e->iam.calling_party_num, e->iam.calling_nai);
  863. p->callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
  864. } else
  865. p->cid_num[0] = 0;
  866. /* Set DNID */
  867. if (!ast_strlen_zero(e->iam.called_party_num)) {
  868. ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset,
  869. e->iam.called_party_num, e->iam.called_nai);
  870. } else {
  871. p->exten[0] = '\0';
  872. }
  873. sig_ss7_set_dnid(p, p->exten);
  874. if (p->immediate) {
  875. p->exten[0] = 's';
  876. p->exten[1] = '\0';
  877. } else if (!ast_strlen_zero(e->iam.called_party_num)) {
  878. char *st;
  879. ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, e->iam.called_party_num, e->iam.called_nai);
  880. st = strchr(p->exten, '#');
  881. if (st) {
  882. *st = '\0';
  883. }
  884. } else {
  885. p->exten[0] = '\0';
  886. }
  887. p->cid_ani[0] = '\0';
  888. if ((p->use_callerid) && (!ast_strlen_zero(e->iam.generic_name)))
  889. ast_copy_string(p->cid_name, e->iam.generic_name, sizeof(p->cid_name));
  890. else
  891. p->cid_name[0] = '\0';
  892. p->cid_ani2 = e->iam.oli_ani2;
  893. p->cid_ton = 0;
  894. ast_copy_string(p->charge_number, e->iam.charge_number, sizeof(p->charge_number));
  895. ast_copy_string(p->gen_add_number, e->iam.gen_add_number, sizeof(p->gen_add_number));
  896. p->gen_add_type = e->iam.gen_add_type;
  897. p->gen_add_nai = e->iam.gen_add_nai;
  898. p->gen_add_pres_ind = e->iam.gen_add_pres_ind;
  899. p->gen_add_num_plan = e->iam.gen_add_num_plan;
  900. ast_copy_string(p->gen_dig_number, e->iam.gen_dig_number, sizeof(p->gen_dig_number));
  901. p->gen_dig_type = e->iam.gen_dig_type;
  902. p->gen_dig_scheme = e->iam.gen_dig_scheme;
  903. ast_copy_string(p->jip_number, e->iam.jip_number, sizeof(p->jip_number));
  904. ast_copy_string(p->orig_called_num, e->iam.orig_called_num, sizeof(p->orig_called_num));
  905. ast_copy_string(p->redirecting_num, e->iam.redirecting_num, sizeof(p->redirecting_num));
  906. ast_copy_string(p->generic_name, e->iam.generic_name, sizeof(p->generic_name));
  907. p->calling_party_cat = e->iam.calling_party_cat;
  908. sig_ss7_set_caller_id(p);
  909. if (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
  910. if (e->iam.cot_check_required) {
  911. p->call_level = SIG_SS7_CALL_LEVEL_CONTINUITY;
  912. sig_ss7_loopback(p, 1);
  913. } else {
  914. ss7_start_call(p, linkset);
  915. }
  916. } else {
  917. ast_debug(1, "Call on CIC for unconfigured extension %s\n", p->exten);
  918. p->alreadyhungup = 1;
  919. isup_rel(ss7, e->iam.call, AST_CAUSE_UNALLOCATED);
  920. }
  921. sig_ss7_unlock_private(p);
  922. break;
  923. case ISUP_EVENT_COT:
  924. chanpos = ss7_find_cic_gripe(linkset, e->cot.cic, e->cot.opc, "COT");
  925. if (chanpos < 0) {
  926. isup_rel(ss7, e->cot.call, -1);
  927. break;
  928. }
  929. p = linkset->pvts[chanpos];
  930. sig_ss7_lock_private(p);
  931. if (p->loopedback) {
  932. sig_ss7_loopback(p, 0);
  933. ss7_start_call(p, linkset);
  934. }
  935. sig_ss7_unlock_private(p);
  936. break;
  937. case ISUP_EVENT_CCR:
  938. ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic);
  939. chanpos = ss7_find_cic_gripe(linkset, e->ccr.cic, e->ccr.opc, "CCR");
  940. if (chanpos < 0) {
  941. break;
  942. }
  943. p = linkset->pvts[chanpos];
  944. sig_ss7_lock_private(p);
  945. sig_ss7_loopback(p, 1);
  946. sig_ss7_unlock_private(p);
  947. isup_lpa(linkset->ss7, e->ccr.cic, p->dpc);
  948. break;
  949. case ISUP_EVENT_CVT:
  950. ast_debug(1, "Got CVT request on CIC %d\n", e->cvt.cic);
  951. chanpos = ss7_find_cic_gripe(linkset, e->cvt.cic, e->cvt.opc, "CVT");
  952. if (chanpos < 0) {
  953. break;
  954. }
  955. p = linkset->pvts[chanpos];
  956. sig_ss7_lock_private(p);
  957. sig_ss7_loopback(p, 1);
  958. sig_ss7_unlock_private(p);
  959. isup_cvr(linkset->ss7, e->cvt.cic, p->dpc);
  960. break;
  961. case ISUP_EVENT_REL:
  962. chanpos = ss7_find_cic_gripe(linkset, e->rel.cic, e->rel.opc, "REL");
  963. if (chanpos < 0) {
  964. /* Continue hanging up the call anyway. */
  965. isup_rlc(ss7, e->rel.call);
  966. break;
  967. }
  968. p = linkset->pvts[chanpos];
  969. sig_ss7_lock_private(p);
  970. sig_ss7_lock_owner(linkset, chanpos);
  971. if (p->owner) {
  972. p->owner->hangupcause = e->rel.cause;
  973. ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
  974. ast_channel_unlock(p->owner);
  975. }
  976. /* End the loopback if we have one */
  977. sig_ss7_loopback(p, 0);
  978. isup_rlc(ss7, e->rel.call);
  979. p->ss7call = NULL;
  980. sig_ss7_unlock_private(p);
  981. break;
  982. case ISUP_EVENT_ACM:
  983. chanpos = ss7_find_cic_gripe(linkset, e->acm.cic, e->acm.opc, "ACM");
  984. if (chanpos < 0) {
  985. isup_rel(ss7, e->acm.call, -1);
  986. break;
  987. }
  988. {
  989. p = linkset->pvts[chanpos];
  990. ast_debug(1, "Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->cic);
  991. if (e->acm.call_ref_ident > 0) {
  992. p->rlt = 1; /* Setting it but not using it here*/
  993. }
  994. sig_ss7_lock_private(p);
  995. sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_PROCEEDING);
  996. if (p->call_level < SIG_SS7_CALL_LEVEL_PROCEEDING) {
  997. p->call_level = SIG_SS7_CALL_LEVEL_PROCEEDING;
  998. }
  999. sig_ss7_set_dialing(p, 0);
  1000. /* Send alerting if subscriber is free */
  1001. if (e->acm.called_party_status_ind == 1) {
  1002. if (p->call_level < SIG_SS7_CALL_LEVEL_ALERTING) {
  1003. p->call_level = SIG_SS7_CALL_LEVEL_ALERTING;
  1004. }
  1005. sig_ss7_lock_owner(linkset, chanpos);
  1006. if (p->owner) {
  1007. ast_setstate(p->owner, AST_STATE_RINGING);
  1008. ast_channel_unlock(p->owner);
  1009. }
  1010. sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_RINGING);
  1011. }
  1012. sig_ss7_unlock_private(p);
  1013. }
  1014. break;
  1015. case ISUP_EVENT_CGB:
  1016. chanpos = ss7_find_cic_gripe(linkset, e->cgb.startcic, e->cgb.opc, "CGB");
  1017. if (chanpos < 0) {
  1018. break;
  1019. }
  1020. p = linkset->pvts[chanpos];
  1021. ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, 1);
  1022. isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, e->cgb.type);
  1023. break;
  1024. case ISUP_EVENT_CGU:
  1025. chanpos = ss7_find_cic_gripe(linkset, e->cgu.startcic, e->cgu.opc, "CGU");
  1026. if (chanpos < 0) {
  1027. break;
  1028. }
  1029. p = linkset->pvts[chanpos];
  1030. ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, 0);
  1031. isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, e->cgu.type);
  1032. break;
  1033. case ISUP_EVENT_UCIC:
  1034. chanpos = ss7_find_cic_gripe(linkset, e->ucic.cic, e->ucic.opc, "UCIC");
  1035. if (chanpos < 0) {
  1036. break;
  1037. }
  1038. p = linkset->pvts[chanpos];
  1039. ast_debug(1, "Unequiped Circuit Id Code on CIC %d\n", e->ucic.cic);
  1040. sig_ss7_lock_private(p);
  1041. sig_ss7_set_remotelyblocked(p, 1);
  1042. sig_ss7_set_inservice(p, 0);
  1043. sig_ss7_unlock_private(p);/* doesn't require a SS7 acknowledgement */
  1044. break;
  1045. case ISUP_EVENT_BLO:
  1046. chanpos = ss7_find_cic_gripe(linkset, e->blo.cic, e->blo.opc, "BLO");
  1047. if (chanpos < 0) {
  1048. break;
  1049. }
  1050. p = linkset->pvts[chanpos];
  1051. ast_debug(1, "Blocking CIC %d\n", e->blo.cic);
  1052. sig_ss7_lock_private(p);
  1053. sig_ss7_set_remotelyblocked(p, 1);
  1054. sig_ss7_unlock_private(p);
  1055. isup_bla(linkset->ss7, e->blo.cic, p->dpc);
  1056. break;
  1057. case ISUP_EVENT_BLA:
  1058. chanpos = ss7_find_cic_gripe(linkset, e->bla.cic, e->bla.opc, "BLA");
  1059. if (chanpos < 0) {
  1060. break;
  1061. }
  1062. ast_debug(1, "Blocking CIC %d\n", e->bla.cic);
  1063. p = linkset->pvts[chanpos];
  1064. sig_ss7_lock_private(p);
  1065. sig_ss7_set_locallyblocked(p, 1);
  1066. sig_ss7_unlock_private(p);
  1067. break;
  1068. case ISUP_EVENT_UBL:
  1069. chanpos = ss7_find_cic_gripe(linkset, e->ubl.cic, e->ubl.opc, "UBL");
  1070. if (chanpos < 0) {
  1071. break;
  1072. }
  1073. p = linkset->pvts[chanpos];
  1074. ast_debug(1, "Unblocking CIC %d\n", e->ubl.cic);
  1075. sig_ss7_lock_private(p);
  1076. sig_ss7_set_remotelyblocked(p, 0);
  1077. sig_ss7_unlock_private(p);
  1078. isup_uba(linkset->ss7, e->ubl.cic, p->dpc);
  1079. break;
  1080. case ISUP_EVENT_UBA:
  1081. chanpos = ss7_find_cic_gripe(linkset, e->uba.cic, e->uba.opc, "UBA");
  1082. if (chanpos < 0) {
  1083. break;
  1084. }
  1085. p = linkset->pvts[chanpos];
  1086. ast_debug(1, "Unblocking CIC %d\n", e->uba.cic);
  1087. sig_ss7_lock_private(p);
  1088. sig_ss7_set_locallyblocked(p, 0);
  1089. sig_ss7_unlock_private(p);
  1090. break;
  1091. case ISUP_EVENT_CON:
  1092. case ISUP_EVENT_ANM:
  1093. if (e->e == ISUP_EVENT_CON) {
  1094. chanpos = ss7_find_cic_gripe(linkset, e->con.cic, e->con.opc, "CON");
  1095. if (chanpos < 0) {
  1096. isup_rel(ss7, e->con.call, -1);
  1097. break;
  1098. }
  1099. } else {
  1100. chanpos = ss7_find_cic_gripe(linkset, e->anm.cic, e->anm.opc, "ANM");
  1101. if (chanpos < 0) {
  1102. isup_rel(ss7, e->anm.call, -1);
  1103. break;
  1104. }
  1105. }
  1106. {
  1107. p = linkset->pvts[chanpos];
  1108. sig_ss7_lock_private(p);
  1109. if (p->call_level < SIG_SS7_CALL_LEVEL_CONNECT) {
  1110. p->call_level = SIG_SS7_CALL_LEVEL_CONNECT;
  1111. }
  1112. sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_ANSWER);
  1113. sig_ss7_set_dialing(p, 0);
  1114. sig_ss7_open_media(p);
  1115. sig_ss7_set_echocanceller(p, 1);
  1116. sig_ss7_unlock_private(p);
  1117. }
  1118. break;
  1119. case ISUP_EVENT_RLC:
  1120. /* XXX Call ptr should be passed up from libss7! */
  1121. chanpos = ss7_find_cic_gripe(linkset, e->rlc.cic, e->rlc.opc, "RLC");
  1122. if (chanpos < 0) {
  1123. break;
  1124. }
  1125. {
  1126. p = linkset->pvts[chanpos];
  1127. sig_ss7_lock_private(p);
  1128. if (p->alreadyhungup) {
  1129. if (!p->owner) {
  1130. p->call_level = SIG_SS7_CALL_LEVEL_IDLE;
  1131. }
  1132. p->ss7call = NULL;
  1133. }
  1134. sig_ss7_unlock_private(p);
  1135. }
  1136. break;
  1137. case ISUP_EVENT_FAA:
  1138. /*!
  1139. * \todo The handling of the SS7 FAA message is not good and I
  1140. * don't know enough to handle it correctly.
  1141. */
  1142. chanpos = ss7_find_cic_gripe(linkset, e->faa.cic, e->faa.opc, "FAA");
  1143. if (chanpos < 0) {
  1144. isup_rel(linkset->ss7, e->faa.call, -1);
  1145. break;
  1146. }
  1147. {
  1148. /* XXX FAR and FAA used for something dealing with transfers? */
  1149. p = linkset->pvts[chanpos];
  1150. ast_debug(1, "FAA received on CIC %d\n", e->faa.cic);
  1151. sig_ss7_lock_private(p);
  1152. if (p->alreadyhungup){
  1153. if (!p->owner) {
  1154. p->call_level = SIG_SS7_CALL_LEVEL_IDLE;
  1155. }
  1156. /* XXX We seem to be leaking the isup call structure here. */
  1157. p->ss7call = NULL;
  1158. ast_log(LOG_NOTICE, "Received FAA and we haven't sent FAR. Ignoring.\n");
  1159. }
  1160. sig_ss7_unlock_private(p);
  1161. }
  1162. break;
  1163. default:
  1164. ast_debug(1, "Unknown event %s\n", ss7_event2str(e->e));
  1165. break;
  1166. }
  1167. }
  1168. ast_mutex_unlock(&linkset->lock);
  1169. }
  1170. return 0;
  1171. }
  1172. static inline void ss7_rel(struct sig_ss7_linkset *ss7)
  1173. {
  1174. ast_mutex_unlock(&ss7->lock);
  1175. }
  1176. static void ss7_grab(struct sig_ss7_chan *pvt, struct sig_ss7_linkset *ss7)
  1177. {
  1178. /* Grab the lock first */
  1179. while (ast_mutex_trylock(&ss7->lock)) {
  1180. /* Avoid deadlock */
  1181. sig_ss7_deadlock_avoidance_private(pvt);
  1182. }
  1183. /* Then break the poll */
  1184. if (ss7->master != AST_PTHREADT_NULL) {
  1185. pthread_kill(ss7->master, SIGURG);
  1186. }
  1187. }
  1188. /*!
  1189. * \brief Notify the SS7 layer that the link is in alarm.
  1190. * \since 1.8
  1191. *
  1192. * \param linkset Controlling linkset for the channel.
  1193. * \param which Link index of the signaling channel.
  1194. *
  1195. * \return Nothing
  1196. */
  1197. void sig_ss7_link_alarm(struct sig_ss7_linkset *linkset, int which)
  1198. {
  1199. linkset->linkstate[which] |= (LINKSTATE_DOWN | LINKSTATE_INALARM);
  1200. linkset->linkstate[which] &= ~LINKSTATE_UP;
  1201. ss7_link_alarm(linkset->ss7, linkset->fds[which]);
  1202. }
  1203. /*!
  1204. * \brief Notify the SS7 layer that the link is no longer in alarm.
  1205. * \since 1.8
  1206. *
  1207. * \param linkset Controlling linkset for the channel.
  1208. * \param which Link index of the signaling channel.
  1209. *
  1210. * \return Nothing
  1211. */
  1212. void sig_ss7_link_noalarm(struct sig_ss7_linkset *linkset, int which)
  1213. {
  1214. linkset->linkstate[which] &= ~(LINKSTATE_INALARM | LINKSTATE_DOWN);
  1215. linkset->linkstate[which] |= LINKSTATE_STARTING;
  1216. ss7_link_noalarm(linkset->ss7, linkset->fds[which]);
  1217. }
  1218. /*!
  1219. * \brief Setup and add a SS7 link channel.
  1220. * \since 1.8
  1221. *
  1222. * \param linkset Controlling linkset for the channel.
  1223. * \param which Link index of the signaling channel.
  1224. * \param ss7type Switch type of the linkset
  1225. * \param transport Signaling transport of channel.
  1226. * \param inalarm Non-zero if the channel is in alarm.
  1227. * \param networkindicator User configuration parameter.
  1228. * \param pointcode User configuration parameter.
  1229. * \param adjpointcode User configuration parameter.
  1230. *
  1231. * \retval 0 on success.
  1232. * \retval -1 on error.
  1233. */
  1234. int sig_ss7_add_sigchan(struct sig_ss7_linkset *linkset, int which, int ss7type, int transport, int inalarm, int networkindicator, int pointcode, int adjpointcode)
  1235. {
  1236. if (!linkset->ss7) {
  1237. linkset->type = ss7type;
  1238. linkset->ss7 = ss7_new(ss7type);
  1239. if (!linkset->ss7) {
  1240. ast_log(LOG_ERROR, "Can't create new SS7!\n");
  1241. return -1;
  1242. }
  1243. }
  1244. ss7_set_network_ind(linkset->ss7, networkindicator);
  1245. ss7_set_pc(linkset->ss7, pointcode);
  1246. if (ss7_add_link(linkset->ss7, transport, linkset->fds[which])) {
  1247. ast_log(LOG_WARNING, "Could not add SS7 link!\n");
  1248. }
  1249. if (inalarm) {
  1250. linkset->linkstate[which] = LINKSTATE_DOWN | LINKSTATE_INALARM;
  1251. ss7_link_alarm(linkset->ss7, linkset->fds[which]);
  1252. } else {
  1253. linkset->linkstate[which] = LINKSTATE_DOWN;
  1254. ss7_link_noalarm(linkset->ss7, linkset->fds[which]);
  1255. }
  1256. ss7_set_adjpc(linkset->ss7, linkset->fds[which], adjpointcode);
  1257. return 0;
  1258. }
  1259. /*!
  1260. * \brief Determine if the specified channel is available for an outgoing call.
  1261. * \since 1.8
  1262. *
  1263. * \param p Signaling private structure pointer.
  1264. *
  1265. * \retval TRUE if the channel is available.
  1266. */
  1267. int sig_ss7_available(struct sig_ss7_chan *p)
  1268. {
  1269. int available;
  1270. if (!p->ss7) {
  1271. /* Something is wrong here. A SS7 channel without the ss7 pointer? */
  1272. return 0;
  1273. }
  1274. /* Only have to deal with the linkset lock. */
  1275. ast_mutex_lock(&p->ss7->lock);
  1276. available = sig_ss7_is_chan_available(p);
  1277. if (available) {
  1278. p->call_level = SIG_SS7_CALL_LEVEL_ALLOCATED;
  1279. }
  1280. ast_mutex_unlock(&p->ss7->lock);
  1281. return available;
  1282. }
  1283. static unsigned char cid_pres2ss7pres(int cid_pres)
  1284. {
  1285. return (cid_pres >> 5) & 0x03;
  1286. }
  1287. static unsigned char cid_pres2ss7screen(int cid_pres)
  1288. {
  1289. return cid_pres & 0x03;
  1290. }
  1291. /*!
  1292. * \brief Dial out using the specified SS7 channel.
  1293. * \since 1.8
  1294. *
  1295. * \param p Signaling private structure pointer.
  1296. * \param ast Asterisk channel structure pointer.
  1297. * \param rdest Dialstring.
  1298. *
  1299. * \retval 0 on success.
  1300. * \retval -1 on error.
  1301. */
  1302. int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, char *rdest)
  1303. {
  1304. char ss7_called_nai;
  1305. int called_nai_strip;
  1306. char ss7_calling_nai;
  1307. int calling_nai_strip;
  1308. const char *charge_str = NULL;
  1309. const char *gen_address = NULL;
  1310. const char *gen_digits = NULL;
  1311. const char *gen_dig_type = NULL;
  1312. const char *gen_dig_scheme = NULL;
  1313. const char *gen_name = NULL;
  1314. const char *jip_digits = NULL;
  1315. const char *lspi_ident = NULL;
  1316. const char *rlt_flag = NULL;
  1317. const char *call_ref_id = NULL;
  1318. const char *call_ref_pc = NULL;
  1319. const char *send_far = NULL;
  1320. char *c;
  1321. char *l;
  1322. char dest[256];
  1323. ast_copy_string(dest, rdest, sizeof(dest));
  1324. c = strchr(dest, '/');
  1325. if (c) {
  1326. c++;
  1327. } else {
  1328. c = "";
  1329. }
  1330. if (strlen(c) < p->stripmsd) {
  1331. ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
  1332. return -1;
  1333. }
  1334. if (!p->hidecallerid) {
  1335. l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL;
  1336. } else {
  1337. l = NULL;
  1338. }
  1339. ss7_grab(p, p->ss7);
  1340. if (p->call_level != SIG_SS7_CALL_LEVEL_ALLOCATED) {
  1341. /* Call collision before sending IAM. Abort call. */
  1342. ss7_rel(p->ss7);
  1343. return -1;
  1344. }
  1345. p->ss7call = isup_new_call(p->ss7->ss7);
  1346. if (!p->ss7call) {
  1347. ss7_rel(p->ss7);
  1348. ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n");
  1349. return -1;
  1350. }
  1351. called_nai_strip = 0;
  1352. ss7_called_nai = p->ss7->called_nai;
  1353. if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */
  1354. if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
  1355. called_nai_strip = strlen(p->ss7->internationalprefix);
  1356. ss7_called_nai = SS7_NAI_INTERNATIONAL;
  1357. } else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
  1358. called_nai_strip = strlen(p->ss7->nationalprefix);
  1359. ss7_called_nai = SS7_NAI_NATIONAL;
  1360. } else {
  1361. ss7_called_nai = SS7_NAI_SUBSCRIBER;
  1362. }
  1363. }
  1364. isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7);
  1365. calling_nai_strip = 0;
  1366. ss7_calling_nai = p->ss7->calling_nai;
  1367. if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */
  1368. if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
  1369. calling_nai_strip = strlen(p->ss7->internationalprefix);
  1370. ss7_calling_nai = SS7_NAI_INTERNATIONAL;
  1371. } else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
  1372. calling_nai_strip = strlen(p->ss7->nationalprefix);
  1373. ss7_calling_nai = SS7_NAI_NATIONAL;
  1374. } else {
  1375. ss7_calling_nai = SS7_NAI_SUBSCRIBER;
  1376. }
  1377. }
  1378. isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
  1379. p->use_callingpres ? cid_pres2ss7pres(ast->connected.id.number.presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
  1380. p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number.presentation) : SS7_SCREENING_USER_PROVIDED);
  1381. isup_set_oli(p->ss7call, ast->connected.ani2);
  1382. isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
  1383. /* Set the charge number if it is set */
  1384. charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
  1385. if (charge_str)
  1386. isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
  1387. gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
  1388. if (gen_address)
  1389. isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
  1390. gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
  1391. gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
  1392. gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
  1393. if (gen_digits)
  1394. isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
  1395. gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
  1396. if (gen_name)
  1397. isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
  1398. jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
  1399. if (jip_digits)
  1400. isup_set_jip_digits(p->ss7call, jip_digits);
  1401. lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
  1402. if (lspi_ident)
  1403. isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00);
  1404. rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
  1405. if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
  1406. isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
  1407. }
  1408. call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
  1409. call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
  1410. if (call_ref_id && call_ref_pc) {
  1411. isup_set_callref(p->ss7call, atoi(call_ref_id),
  1412. call_ref_pc ? atoi(call_ref_pc) : 0);
  1413. }
  1414. send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR");
  1415. if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 ))
  1416. (isup_far(p->ss7->ss7, p->ss7call));
  1417. p->call_level = SIG_SS7_CALL_LEVEL_SETUP;
  1418. isup_iam(p->ss7->ss7, p->ss7call);
  1419. sig_ss7_set_dialing(p, 1);
  1420. ast_setstate(ast, AST_STATE_DIALING);
  1421. ss7_rel(p->ss7);
  1422. return 0;
  1423. }
  1424. /*!
  1425. * \brief SS7 hangup channel.
  1426. * \since 1.8
  1427. *
  1428. * \param p Signaling private structure pointer.
  1429. * \param ast Asterisk channel structure pointer.
  1430. *
  1431. * \retval 0 on success.
  1432. * \retval -1 on error.
  1433. */
  1434. int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
  1435. {
  1436. int res = 0;
  1437. if (!ast->tech_pvt) {
  1438. ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
  1439. return 0;
  1440. }
  1441. p->owner = NULL;
  1442. sig_ss7_set_dialing(p, 0);
  1443. sig_ss7_set_outgoing(p, 0);
  1444. p->progress = 0;
  1445. p->rlt = 0;
  1446. p->exten[0] = '\0';
  1447. /* Perform low level hangup if no owner left */
  1448. ss7_grab(p, p->ss7);
  1449. p->call_level = SIG_SS7_CALL_LEVEL_IDLE;
  1450. if (p->ss7call) {
  1451. if (!p->alreadyhungup) {
  1452. const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
  1453. int icause = ast->hangupcause ? ast->hangupcause : -1;
  1454. if (cause) {
  1455. if (atoi(cause)) {
  1456. icause = atoi(cause);
  1457. }
  1458. }
  1459. isup_rel(p->ss7->ss7, p->ss7call, icause);
  1460. p->alreadyhungup = 1;
  1461. }
  1462. }
  1463. ss7_rel(p->ss7);
  1464. return res;
  1465. }
  1466. /*!
  1467. * \brief SS7 answer channel.
  1468. * \since 1.8
  1469. *
  1470. * \param p Signaling private structure pointer.
  1471. * \param ast Asterisk channel structure pointer.
  1472. *
  1473. * \retval 0 on success.
  1474. * \retval -1 on error.
  1475. */
  1476. int sig_ss7_answer(struct sig_ss7_chan *p, struct ast_channel *ast)
  1477. {
  1478. int res;
  1479. ss7_grab(p, p->ss7);
  1480. if (p->call_level < SIG_SS7_CALL_LEVEL_CONNECT) {
  1481. p->call_level = SIG_SS7_CALL_LEVEL_CONNECT;
  1482. }
  1483. sig_ss7_open_media(p);
  1484. res = isup_anm(p->ss7->ss7, p->ss7call);
  1485. ss7_rel(p->ss7);
  1486. return res;
  1487. }
  1488. /*!
  1489. * \brief Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links.
  1490. * \since 1.8
  1491. *
  1492. * \param oldchan Old channel pointer to replace.
  1493. * \param newchan New channel pointer to set.
  1494. * \param pchan Signaling private structure pointer.
  1495. *
  1496. * \return Nothing
  1497. */
  1498. void sig_ss7_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan)
  1499. {
  1500. if (pchan->owner == oldchan) {
  1501. pchan->owner = newchan;
  1502. }
  1503. }
  1504. /*!
  1505. * \brief SS7 answer channel.
  1506. * \since 1.8
  1507. *
  1508. * \param p Signaling private structure pointer.
  1509. * \param chan Asterisk channel structure pointer.
  1510. * \param condition AST control frame subtype.
  1511. * \param data AST control frame payload contents.
  1512. * \param datalen Length of payload contents.
  1513. *
  1514. * \retval 0 on success.
  1515. * \retval -1 on error or indication condition not handled.
  1516. */
  1517. int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
  1518. {
  1519. int res = -1;
  1520. switch (condition) {
  1521. case AST_CONTROL_BUSY:
  1522. if (p->call_level < SIG_SS7_CALL_LEVEL_CONNECT) {
  1523. chan->hangupcause = AST_CAUSE_USER_BUSY;
  1524. ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
  1525. res = 0;
  1526. break;
  1527. }
  1528. res = sig_ss7_play_tone(p, SIG_SS7_TONE_BUSY);
  1529. break;
  1530. case AST_CONTROL_RINGING:
  1531. ss7_grab(p, p->ss7);
  1532. if (p->call_level < SIG_SS7_CALL_LEVEL_ALERTING && !p->outgoing) {
  1533. p->call_level = SIG_SS7_CALL_LEVEL_ALERTING;
  1534. if ((isup_far(p->ss7->ss7, p->ss7call)) != -1) {
  1535. p->rlt = 1;
  1536. }
  1537. /* No need to send CPG if call will be RELEASE */
  1538. if (p->rlt != 1) {
  1539. isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_ALERTING);
  1540. }
  1541. }
  1542. ss7_rel(p->ss7);
  1543. res = sig_ss7_play_tone(p, SIG_SS7_TONE_RINGTONE);
  1544. if (chan->_state != AST_STATE_UP && chan->_state != AST_STATE_RING) {
  1545. ast_setstate(chan, AST_STATE_RINGING);
  1546. }
  1547. break;
  1548. case AST_CONTROL_PROCEEDING:
  1549. ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
  1550. ss7_grab(p, p->ss7);
  1551. /* This IF sends the FAR for an answered ALEG call */
  1552. if (chan->_state == AST_STATE_UP && (p->rlt != 1)){
  1553. if ((isup_far(p->ss7->ss7, p->ss7call)) != -1) {
  1554. p->rlt = 1;
  1555. }
  1556. }
  1557. if (p->call_level < SIG_SS7_CALL_LEVEL_PROCEEDING && !p->outgoing) {
  1558. p->call_level = SIG_SS7_CALL_LEVEL_PROCEEDING;
  1559. isup_acm(p->ss7->ss7, p->ss7call);
  1560. }
  1561. ss7_rel(p->ss7);
  1562. /* don't continue in ast_indicate */
  1563. res = 0;
  1564. break;
  1565. case AST_CONTROL_PROGRESS:
  1566. ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
  1567. ss7_grab(p, p->ss7);
  1568. if (!p->progress && p->call_level < SIG_SS7_CALL_LEVEL_ALERTING && !p->outgoing) {
  1569. p->progress = 1;/* No need to send inband-information progress again. */
  1570. isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_INBANDINFO);
  1571. ss7_rel(p->ss7);
  1572. /* enable echo canceler here on SS7 calls */
  1573. sig_ss7_set_echocanceller(p, 1);
  1574. } else {
  1575. ss7_rel(p->ss7);
  1576. }
  1577. /* don't continue in ast_indicate */
  1578. res = 0;
  1579. break;
  1580. case AST_CONTROL_INCOMPLETE:
  1581. if (p->call_level < SIG_SS7_CALL_LEVEL_CONNECT) {
  1582. chan->hangupcause = AST_CAUSE_INVALID_NUMBER_FORMAT;
  1583. ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
  1584. res = 0;
  1585. break;
  1586. }
  1587. /* Wait for DTMF digits to complete the dialed number. */
  1588. res = 0;
  1589. break;
  1590. case AST_CONTROL_CONGESTION:
  1591. if (p->call_level < SIG_SS7_CALL_LEVEL_CONNECT) {
  1592. chan->hangupcause = AST_CAUSE_CONGESTION;
  1593. ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
  1594. res = 0;
  1595. break;
  1596. }
  1597. res = sig_ss7_play_tone(p, SIG_SS7_TONE_CONGESTION);
  1598. break;
  1599. case AST_CONTROL_HOLD:
  1600. ast_moh_start(chan, data, p->mohinterpret);
  1601. break;
  1602. case AST_CONTROL_UNHOLD:
  1603. ast_moh_stop(chan);
  1604. break;
  1605. case AST_CONTROL_SRCUPDATE:
  1606. res = 0;
  1607. break;
  1608. case -1:
  1609. res = sig_ss7_play_tone(p, -1);
  1610. break;
  1611. }
  1612. return res;
  1613. }
  1614. /*!
  1615. * \brief SS7 channel request.
  1616. * \since 1.8
  1617. *
  1618. * \param p Signaling private structure pointer.
  1619. * \param law Companding law preferred
  1620. * \param requestor Asterisk channel requesting a channel to dial (Can be NULL)
  1621. * \param transfercapability
  1622. *
  1623. * \retval ast_channel on success.
  1624. * \retval NULL on error.
  1625. */
  1626. struct ast_channel *sig_ss7_request(struct sig_ss7_chan *p, enum sig_ss7_law law, const struct ast_channel *requestor, int transfercapability)
  1627. {
  1628. struct ast_channel *ast;
  1629. /* Companding law is determined by SS7 signaling type. */
  1630. if (p->ss7->type == SS7_ITU) {
  1631. law = SIG_SS7_ALAW;
  1632. } else {
  1633. law = SIG_SS7_ULAW;
  1634. }
  1635. sig_ss7_set_outgoing(p, 1);
  1636. ast = sig_ss7_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
  1637. if (!ast) {
  1638. sig_ss7_set_outgoing(p, 0);
  1639. /* Release the allocated channel. Only have to deal with the linkset lock. */
  1640. ast_mutex_lock(&p->ss7->lock);
  1641. p->call_level = SIG_SS7_CALL_LEVEL_IDLE;
  1642. ast_mutex_unlock(&p->ss7->lock);
  1643. }
  1644. return ast;
  1645. }
  1646. /*!
  1647. * \brief Delete the sig_ss7 private channel structure.
  1648. * \since 1.8
  1649. *
  1650. * \param doomed sig_ss7 private channel structure to delete.
  1651. *
  1652. * \return Nothing
  1653. */
  1654. void sig_ss7_chan_delete(struct sig_ss7_chan *doomed)
  1655. {
  1656. ast_free(doomed);
  1657. }
  1658. #define SIG_SS7_SC_HEADER "%-4s %4s %-4s %-3s %-3s %-10s %-4s %s\n"
  1659. #define SIG_SS7_SC_LINE "%4d %4d %-4s %-3s %-3s %-10s %-4s %s"
  1660. void sig_ss7_cli_show_channels_header(int fd)
  1661. {
  1662. ast_cli(fd, SIG_SS7_SC_HEADER, "link", "", "Chan", "Lcl", "Rem", "Call", "SS7", "Channel");
  1663. ast_cli(fd, SIG_SS7_SC_HEADER, "set", "Chan", "Idle", "Blk", "Blk", "Level", "Call", "Name");
  1664. }
  1665. void sig_ss7_cli_show_channels(int fd, struct sig_ss7_linkset *linkset)
  1666. {
  1667. char line[256];
  1668. int idx;
  1669. struct sig_ss7_chan *pvt;
  1670. ast_mutex_lock(&linkset->lock);
  1671. for (idx = 0; idx < linkset->numchans; ++idx) {
  1672. if (!linkset->pvts[idx]) {
  1673. continue;
  1674. }
  1675. pvt = linkset->pvts[idx];
  1676. sig_ss7_lock_private(pvt);
  1677. sig_ss7_lock_owner(linkset, idx);
  1678. snprintf(line, sizeof(line), SIG_SS7_SC_LINE,
  1679. linkset->span,
  1680. pvt->channel,
  1681. sig_ss7_is_chan_available(pvt) ? "Yes" : "No",
  1682. pvt->locallyblocked ? "Yes" : "No",
  1683. pvt->remotelyblocked ? "Yes" : "No",
  1684. sig_ss7_call_level2str(pvt->call_level),
  1685. pvt->ss7call ? "Yes" : "No",
  1686. pvt->owner ? pvt->owner->name : "");
  1687. if (pvt->owner) {
  1688. ast_channel_unlock(pvt->owner);
  1689. }
  1690. sig_ss7_unlock_private(pvt);
  1691. ast_mutex_unlock(&linkset->lock);
  1692. ast_cli(fd, "%s\n", line);
  1693. ast_mutex_lock(&linkset->lock);
  1694. }
  1695. ast_mutex_unlock(&linkset->lock);
  1696. }
  1697. /*!
  1698. * \brief Create a new sig_ss7 private channel structure.
  1699. * \since 1.8
  1700. *
  1701. * \param pvt_data Upper layer private data structure.
  1702. * \param callback Callbacks to the upper layer.
  1703. * \param ss7 Controlling linkset for the channel.
  1704. *
  1705. * \retval sig_ss7_chan on success.
  1706. * \retval NULL on error.
  1707. */
  1708. struct sig_ss7_chan *sig_ss7_chan_new(void *pvt_data, struct sig_ss7_callback *callback, struct sig_ss7_linkset *ss7)
  1709. {
  1710. struct sig_ss7_chan *pvt;
  1711. pvt = ast_calloc(1, sizeof(*pvt));
  1712. if (!pvt) {
  1713. return pvt;
  1714. }
  1715. pvt->calls = callback;
  1716. pvt->chan_pvt = pvt_data;
  1717. pvt->ss7 = ss7;
  1718. return pvt;
  1719. }
  1720. /*!
  1721. * \brief Initialize the SS7 linkset control.
  1722. * \since 1.8
  1723. *
  1724. * \param ss7 SS7 linkset control structure.
  1725. *
  1726. * \return Nothing
  1727. */
  1728. void sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
  1729. {
  1730. int idx;
  1731. memset(ss7, 0, sizeof(*ss7));
  1732. ast_mutex_init(&ss7->lock);
  1733. ss7->master = AST_PTHREADT_NULL;
  1734. for (idx = 0; idx < ARRAY_LEN(ss7->fds); ++idx) {
  1735. ss7->fds[idx] = -1;
  1736. }
  1737. }
  1738. /* ------------------------------------------------------------------- */
  1739. #endif /* defined(HAVE_SS7) */
  1740. /* end sig_ss7.c */