app_sla.c 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2022, Naveen Albert
  5. *
  6. * Based on previous MeetMe-based SLA Implementation by:
  7. * Russell Bryant <russell@digium.com>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*! \file
  20. *
  21. * \brief Shared Line Appearances
  22. *
  23. * \author Naveen Albert <asterisk@phreaknet.org>
  24. *
  25. * \ingroup applications
  26. */
  27. /*! \li \ref app_sla.c uses configuration file \ref sla.conf
  28. * \addtogroup configuration_file Configuration Files
  29. */
  30. /*!
  31. * \page sla.conf sla.conf
  32. * \verbinclude sla.conf.sample
  33. */
  34. /*** MODULEINFO
  35. <depend>app_confbridge</depend>
  36. <support_level>extended</support_level>
  37. ***/
  38. #include "asterisk.h"
  39. #include "asterisk/lock.h"
  40. #include "asterisk/file.h"
  41. #include "asterisk/channel.h"
  42. #include "asterisk/pbx.h"
  43. #include "asterisk/module.h"
  44. #include "asterisk/config.h"
  45. #include "asterisk/app.h"
  46. #include "asterisk/cli.h"
  47. #include "asterisk/utils.h"
  48. #include "asterisk/astobj2.h"
  49. #include "asterisk/devicestate.h"
  50. #include "asterisk/dial.h"
  51. #include "asterisk/causes.h"
  52. #include "asterisk/format_compatibility.h"
  53. /*** DOCUMENTATION
  54. <application name="SLAStation" language="en_US">
  55. <synopsis>
  56. Shared Line Appearance Station.
  57. </synopsis>
  58. <syntax>
  59. <parameter name="station" required="true">
  60. <para>Station name</para>
  61. </parameter>
  62. </syntax>
  63. <description>
  64. <para>This application should be executed by an SLA station. The argument depends
  65. on how the call was initiated. If the phone was just taken off hook, then the argument
  66. <replaceable>station</replaceable> should be just the station name. If the call was
  67. initiated by pressing a line key, then the station name should be preceded by an underscore
  68. and the trunk name associated with that line button.</para>
  69. <para>For example: <literal>station1_line1</literal></para>
  70. <para>On exit, this application will set the variable <variable>SLASTATION_STATUS</variable> to
  71. one of the following values:</para>
  72. <variablelist>
  73. <variable name="SLASTATION_STATUS">
  74. <value name="FAILURE" />
  75. <value name="CONGESTION" />
  76. <value name="SUCCESS" />
  77. </variable>
  78. </variablelist>
  79. </description>
  80. </application>
  81. <application name="SLATrunk" language="en_US">
  82. <synopsis>
  83. Shared Line Appearance Trunk.
  84. </synopsis>
  85. <syntax>
  86. <parameter name="trunk" required="true">
  87. <para>Trunk name</para>
  88. </parameter>
  89. <parameter name="options">
  90. <optionlist>
  91. <option name="M" hasparams="optional">
  92. <para>Play back the specified MOH <replaceable>class</replaceable>
  93. instead of ringing</para>
  94. <argument name="class" required="true" />
  95. </option>
  96. </optionlist>
  97. </parameter>
  98. </syntax>
  99. <description>
  100. <para>This application should be executed by an SLA trunk on an inbound call. The channel calling
  101. this application should correspond to the SLA trunk with the name <replaceable>trunk</replaceable>
  102. that is being passed as an argument.</para>
  103. <para>On exit, this application will set the variable <variable>SLATRUNK_STATUS</variable> to
  104. one of the following values:</para>
  105. <variablelist>
  106. <variable name="SLATRUNK_STATUS">
  107. <value name="FAILURE" />
  108. <value name="SUCCESS" />
  109. <value name="UNANSWERED" />
  110. <value name="RINGTIMEOUT" />
  111. </variable>
  112. </variablelist>
  113. </description>
  114. </application>
  115. ***/
  116. #define SLA_CONFIG_FILE "sla.conf"
  117. #define MAX_CONFNUM 80
  118. static const char * const slastation_app = "SLAStation";
  119. static const char * const slatrunk_app = "SLATrunk";
  120. enum {
  121. /*! If set there will be no enter or leave sounds */
  122. CONFFLAG_QUIET = (1 << 0),
  123. /*! Set to have music on hold when user is alone in conference */
  124. CONFFLAG_MOH = (1 << 1),
  125. /*! If set, the channel will leave the conference if all marked users leave */
  126. CONFFLAG_MARKEDEXIT = (1 << 2),
  127. /*! If set, the user will be marked */
  128. CONFFLAG_MARKEDUSER = (1 << 3),
  129. /*! Pass DTMF through the conference */
  130. CONFFLAG_PASS_DTMF = (1 << 4),
  131. CONFFLAG_SLA_STATION = (1 << 5),
  132. CONFFLAG_SLA_TRUNK = (1 << 6),
  133. };
  134. enum {
  135. SLA_TRUNK_OPT_MOH = (1 << 0),
  136. };
  137. enum {
  138. SLA_TRUNK_OPT_ARG_MOH_CLASS = 0,
  139. SLA_TRUNK_OPT_ARG_ARRAY_SIZE = 1,
  140. };
  141. AST_APP_OPTIONS(sla_trunk_opts, BEGIN_OPTIONS
  142. AST_APP_OPTION_ARG('M', SLA_TRUNK_OPT_MOH, SLA_TRUNK_OPT_ARG_MOH_CLASS),
  143. END_OPTIONS );
  144. enum sla_which_trunk_refs {
  145. ALL_TRUNK_REFS,
  146. INACTIVE_TRUNK_REFS,
  147. };
  148. enum sla_trunk_state {
  149. SLA_TRUNK_STATE_IDLE,
  150. SLA_TRUNK_STATE_RINGING,
  151. SLA_TRUNK_STATE_UP,
  152. SLA_TRUNK_STATE_ONHOLD,
  153. SLA_TRUNK_STATE_ONHOLD_BYME,
  154. };
  155. enum sla_hold_access {
  156. /*! This means that any station can put it on hold, and any station
  157. * can retrieve the call from hold. */
  158. SLA_HOLD_OPEN,
  159. /*! This means that only the station that put the call on hold may
  160. * retrieve it from hold. */
  161. SLA_HOLD_PRIVATE,
  162. };
  163. struct sla_trunk_ref;
  164. struct sla_station {
  165. AST_RWLIST_ENTRY(sla_station) entry;
  166. AST_DECLARE_STRING_FIELDS(
  167. AST_STRING_FIELD(name);
  168. AST_STRING_FIELD(device);
  169. AST_STRING_FIELD(autocontext);
  170. );
  171. AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) trunks;
  172. struct ast_dial *dial;
  173. /*! Ring timeout for this station, for any trunk. If a ring timeout
  174. * is set for a specific trunk on this station, that will take
  175. * priority over this value. */
  176. unsigned int ring_timeout;
  177. /*! Ring delay for this station, for any trunk. If a ring delay
  178. * is set for a specific trunk on this station, that will take
  179. * priority over this value. */
  180. unsigned int ring_delay;
  181. /*! This option uses the values in the sla_hold_access enum and sets the
  182. * access control type for hold on this station. */
  183. unsigned int hold_access:1;
  184. /*! Mark used during reload processing */
  185. unsigned int mark:1;
  186. };
  187. /*!
  188. * \brief A reference to a station
  189. *
  190. * This struct looks near useless at first glance. However, its existence
  191. * in the list of stations in sla_trunk means that this station references
  192. * that trunk. We use the mark to keep track of whether it needs to be
  193. * removed from the sla_trunk's list of stations during a reload.
  194. */
  195. struct sla_station_ref {
  196. AST_LIST_ENTRY(sla_station_ref) entry;
  197. struct sla_station *station;
  198. /*! Mark used during reload processing */
  199. unsigned int mark:1;
  200. };
  201. struct sla_trunk {
  202. AST_DECLARE_STRING_FIELDS(
  203. AST_STRING_FIELD(name);
  204. AST_STRING_FIELD(device);
  205. AST_STRING_FIELD(autocontext);
  206. );
  207. AST_LIST_HEAD_NOLOCK(, sla_station_ref) stations;
  208. /*! Number of stations that use this trunk */
  209. unsigned int num_stations;
  210. /*! Number of stations currently on a call with this trunk */
  211. unsigned int active_stations;
  212. /*! Number of stations that have this trunk on hold. */
  213. unsigned int hold_stations;
  214. struct ast_channel *chan;
  215. unsigned int ring_timeout;
  216. /*! If set to 1, no station will be able to join an active call with
  217. * this trunk. */
  218. unsigned int barge_disabled:1;
  219. /*! This option uses the values in the sla_hold_access enum and sets the
  220. * access control type for hold on this trunk. */
  221. unsigned int hold_access:1;
  222. /*! Whether this trunk is currently on hold, meaning that once a station
  223. * connects to it, the trunk channel needs to have UNHOLD indicated to it. */
  224. unsigned int on_hold:1;
  225. /*! Mark used during reload processing */
  226. unsigned int mark:1;
  227. };
  228. /*!
  229. * \brief A station's reference to a trunk
  230. *
  231. * An sla_station keeps a list of trunk_refs. This holds metadata about the
  232. * stations usage of the trunk.
  233. */
  234. struct sla_trunk_ref {
  235. AST_LIST_ENTRY(sla_trunk_ref) entry;
  236. struct sla_trunk *trunk;
  237. enum sla_trunk_state state;
  238. struct ast_channel *chan;
  239. /*! Ring timeout to use when this trunk is ringing on this specific
  240. * station. This takes higher priority than a ring timeout set at
  241. * the station level. */
  242. unsigned int ring_timeout;
  243. /*! Ring delay to use when this trunk is ringing on this specific
  244. * station. This takes higher priority than a ring delay set at
  245. * the station level. */
  246. unsigned int ring_delay;
  247. /*! Mark used during reload processing */
  248. unsigned int mark:1;
  249. };
  250. static struct ao2_container *sla_stations;
  251. static struct ao2_container *sla_trunks;
  252. static const char sla_registrar[] = "SLA";
  253. /*! \brief Event types that can be queued up for the SLA thread */
  254. enum sla_event_type {
  255. /*! A station has put the call on hold */
  256. SLA_EVENT_HOLD,
  257. /*! The state of a dial has changed */
  258. SLA_EVENT_DIAL_STATE,
  259. /*! The state of a ringing trunk has changed */
  260. SLA_EVENT_RINGING_TRUNK,
  261. };
  262. struct sla_event {
  263. enum sla_event_type type;
  264. struct sla_station *station;
  265. struct sla_trunk_ref *trunk_ref;
  266. AST_LIST_ENTRY(sla_event) entry;
  267. };
  268. /*! \brief A station that failed to be dialed
  269. * \note Only used by the SLA thread. */
  270. struct sla_failed_station {
  271. struct sla_station *station;
  272. struct timeval last_try;
  273. AST_LIST_ENTRY(sla_failed_station) entry;
  274. };
  275. /*! \brief A trunk that is ringing */
  276. struct sla_ringing_trunk {
  277. struct sla_trunk *trunk;
  278. /*! The time that this trunk started ringing */
  279. struct timeval ring_begin;
  280. AST_LIST_HEAD_NOLOCK(, sla_station_ref) timed_out_stations;
  281. AST_LIST_ENTRY(sla_ringing_trunk) entry;
  282. };
  283. enum sla_station_hangup {
  284. SLA_STATION_HANGUP_NORMAL,
  285. SLA_STATION_HANGUP_TIMEOUT,
  286. };
  287. /*! \brief A station that is ringing */
  288. struct sla_ringing_station {
  289. struct sla_station *station;
  290. /*! The time that this station started ringing */
  291. struct timeval ring_begin;
  292. AST_LIST_ENTRY(sla_ringing_station) entry;
  293. };
  294. /*!
  295. * \brief A structure for data used by the sla thread
  296. */
  297. static struct {
  298. /*! The SLA thread ID */
  299. pthread_t thread;
  300. ast_cond_t cond;
  301. ast_mutex_t lock;
  302. AST_LIST_HEAD_NOLOCK(, sla_ringing_trunk) ringing_trunks;
  303. AST_LIST_HEAD_NOLOCK(, sla_ringing_station) ringing_stations;
  304. AST_LIST_HEAD_NOLOCK(, sla_failed_station) failed_stations;
  305. AST_LIST_HEAD_NOLOCK(, sla_event) event_q;
  306. unsigned int stop:1;
  307. /*! Attempt to handle CallerID, even though it is known not to work
  308. * properly in some situations. */
  309. unsigned int attempt_callerid:1;
  310. } sla = {
  311. .thread = AST_PTHREADT_NULL,
  312. };
  313. static const char *sla_hold_str(unsigned int hold_access)
  314. {
  315. const char *hold = "Unknown";
  316. switch (hold_access) {
  317. case SLA_HOLD_OPEN:
  318. hold = "Open";
  319. break;
  320. case SLA_HOLD_PRIVATE:
  321. hold = "Private";
  322. default:
  323. break;
  324. }
  325. return hold;
  326. }
  327. static char *sla_show_trunks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  328. {
  329. struct ao2_iterator i;
  330. struct sla_trunk *trunk;
  331. switch (cmd) {
  332. case CLI_INIT:
  333. e->command = "sla show trunks";
  334. e->usage =
  335. "Usage: sla show trunks\n"
  336. " This will list all trunks defined in sla.conf\n";
  337. return NULL;
  338. case CLI_GENERATE:
  339. return NULL;
  340. }
  341. ast_cli(a->fd, "\n"
  342. "=============================================================\n"
  343. "=== Configured SLA Trunks ===================================\n"
  344. "=============================================================\n"
  345. "===\n");
  346. i = ao2_iterator_init(sla_trunks, 0);
  347. for (; (trunk = ao2_iterator_next(&i)); ao2_ref(trunk, -1)) {
  348. struct sla_station_ref *station_ref;
  349. char ring_timeout[23] = "(none)";
  350. ao2_lock(trunk);
  351. if (trunk->ring_timeout) {
  352. snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
  353. }
  354. ast_cli(a->fd, "=== ---------------------------------------------------------\n"
  355. "=== Trunk Name: %s\n"
  356. "=== ==> Device: %s\n"
  357. "=== ==> AutoContext: %s\n"
  358. "=== ==> RingTimeout: %s\n"
  359. "=== ==> BargeAllowed: %s\n"
  360. "=== ==> HoldAccess: %s\n"
  361. "=== ==> Stations ...\n",
  362. trunk->name, trunk->device,
  363. S_OR(trunk->autocontext, "(none)"),
  364. ring_timeout,
  365. trunk->barge_disabled ? "No" : "Yes",
  366. sla_hold_str(trunk->hold_access));
  367. AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
  368. ast_cli(a->fd, "=== ==> Station name: %s\n", station_ref->station->name);
  369. }
  370. ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
  371. ao2_unlock(trunk);
  372. }
  373. ao2_iterator_destroy(&i);
  374. ast_cli(a->fd, "=============================================================\n\n");
  375. return CLI_SUCCESS;
  376. }
  377. static const char *trunkstate2str(enum sla_trunk_state state)
  378. {
  379. #define S(e) case e: return # e;
  380. switch (state) {
  381. S(SLA_TRUNK_STATE_IDLE)
  382. S(SLA_TRUNK_STATE_RINGING)
  383. S(SLA_TRUNK_STATE_UP)
  384. S(SLA_TRUNK_STATE_ONHOLD)
  385. S(SLA_TRUNK_STATE_ONHOLD_BYME)
  386. }
  387. return "Uknown State";
  388. #undef S
  389. }
  390. static char *sla_show_stations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  391. {
  392. struct ao2_iterator i;
  393. struct sla_station *station;
  394. switch (cmd) {
  395. case CLI_INIT:
  396. e->command = "sla show stations";
  397. e->usage =
  398. "Usage: sla show stations\n"
  399. " This will list all stations defined in sla.conf\n";
  400. return NULL;
  401. case CLI_GENERATE:
  402. return NULL;
  403. }
  404. ast_cli(a->fd, "\n"
  405. "=============================================================\n"
  406. "=== Configured SLA Stations =================================\n"
  407. "=============================================================\n"
  408. "===\n");
  409. i = ao2_iterator_init(sla_stations, 0);
  410. for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
  411. struct sla_trunk_ref *trunk_ref;
  412. char ring_timeout[16] = "(none)";
  413. char ring_delay[16] = "(none)";
  414. ao2_lock(station);
  415. if (station->ring_timeout) {
  416. snprintf(ring_timeout, sizeof(ring_timeout), "%u", station->ring_timeout);
  417. }
  418. if (station->ring_delay) {
  419. snprintf(ring_delay, sizeof(ring_delay), "%u", station->ring_delay);
  420. }
  421. ast_cli(a->fd, "=== ---------------------------------------------------------\n"
  422. "=== Station Name: %s\n"
  423. "=== ==> Device: %s\n"
  424. "=== ==> AutoContext: %s\n"
  425. "=== ==> RingTimeout: %s\n"
  426. "=== ==> RingDelay: %s\n"
  427. "=== ==> HoldAccess: %s\n"
  428. "=== ==> Trunks ...\n",
  429. station->name, station->device,
  430. S_OR(station->autocontext, "(none)"),
  431. ring_timeout, ring_delay,
  432. sla_hold_str(station->hold_access));
  433. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  434. if (trunk_ref->ring_timeout) {
  435. snprintf(ring_timeout, sizeof(ring_timeout), "%u", trunk_ref->ring_timeout);
  436. } else {
  437. strcpy(ring_timeout, "(none)");
  438. }
  439. if (trunk_ref->ring_delay) {
  440. snprintf(ring_delay, sizeof(ring_delay), "%u", trunk_ref->ring_delay);
  441. } else {
  442. strcpy(ring_delay, "(none)");
  443. }
  444. ast_cli(a->fd, "=== ==> Trunk Name: %s\n"
  445. "=== ==> State: %s\n"
  446. "=== ==> RingTimeout: %s\n"
  447. "=== ==> RingDelay: %s\n",
  448. trunk_ref->trunk->name,
  449. trunkstate2str(trunk_ref->state),
  450. ring_timeout, ring_delay);
  451. }
  452. ast_cli(a->fd, "=== ---------------------------------------------------------\n"
  453. "===\n");
  454. ao2_unlock(station);
  455. }
  456. ao2_iterator_destroy(&i);
  457. ast_cli(a->fd, "============================================================\n"
  458. "\n");
  459. return CLI_SUCCESS;
  460. }
  461. static struct ast_cli_entry cli_sla[] = {
  462. AST_CLI_DEFINE(sla_show_trunks, "Show SLA Trunks"),
  463. AST_CLI_DEFINE(sla_show_stations, "Show SLA Stations"),
  464. };
  465. static void sla_queue_event_full(enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
  466. {
  467. struct sla_event *event;
  468. if (sla.thread == AST_PTHREADT_NULL) {
  469. ao2_ref(station, -1);
  470. ao2_ref(trunk_ref, -1);
  471. return;
  472. }
  473. if (!(event = ast_calloc(1, sizeof(*event)))) {
  474. ao2_ref(station, -1);
  475. ao2_ref(trunk_ref, -1);
  476. return;
  477. }
  478. event->type = type;
  479. event->trunk_ref = trunk_ref;
  480. event->station = station;
  481. if (!lock) {
  482. AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
  483. return;
  484. }
  485. ast_mutex_lock(&sla.lock);
  486. AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
  487. ast_cond_signal(&sla.cond);
  488. ast_mutex_unlock(&sla.lock);
  489. }
  490. static void sla_queue_event_nolock(enum sla_event_type type)
  491. {
  492. sla_queue_event_full(type, NULL, NULL, 0);
  493. }
  494. static void sla_queue_event(enum sla_event_type type)
  495. {
  496. sla_queue_event_full(type, NULL, NULL, 1);
  497. }
  498. /*! \brief Queue a SLA event from the conference */
  499. static void sla_queue_event_conf(enum sla_event_type type, struct ast_channel *chan, const char *confname)
  500. {
  501. struct sla_station *station;
  502. struct sla_trunk_ref *trunk_ref = NULL;
  503. char *trunk_name;
  504. struct ao2_iterator i;
  505. trunk_name = ast_strdupa(confname);
  506. strsep(&trunk_name, "_");
  507. if (ast_strlen_zero(trunk_name)) {
  508. ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", confname);
  509. return;
  510. }
  511. i = ao2_iterator_init(sla_stations, 0);
  512. while ((station = ao2_iterator_next(&i))) {
  513. ao2_lock(station);
  514. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  515. if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name)) {
  516. ao2_ref(trunk_ref, 1);
  517. break;
  518. }
  519. }
  520. ao2_unlock(station);
  521. if (trunk_ref) {
  522. /* station reference given to sla_queue_event_full() */
  523. break;
  524. }
  525. ao2_ref(station, -1);
  526. }
  527. ao2_iterator_destroy(&i);
  528. if (!trunk_ref) {
  529. ast_debug(1, "Trunk not found for event!\n");
  530. return;
  531. }
  532. sla_queue_event_full(type, trunk_ref, station, 1);
  533. }
  534. /*!
  535. * \brief Framehook to support HOLD within the conference
  536. */
  537. struct sla_framehook_data {
  538. int framehook_id;
  539. char *confname;
  540. };
  541. static const struct ast_datastore_info sla_framehook_datastore = {
  542. .type = "app_sla",
  543. };
  544. static int remove_framehook(struct ast_channel *chan)
  545. {
  546. struct ast_datastore *datastore = NULL;
  547. struct sla_framehook_data *data;
  548. SCOPED_CHANNELLOCK(chan_lock, chan);
  549. datastore = ast_channel_datastore_find(chan, &sla_framehook_datastore, NULL);
  550. if (!datastore) {
  551. ast_log(AST_LOG_WARNING, "Cannot remove framehook from %s: HOLD_INTERCEPT not currently enabled\n", ast_channel_name(chan));
  552. return -1;
  553. }
  554. data = datastore->data;
  555. ast_free(data->confname);
  556. if (ast_framehook_detach(chan, data->framehook_id)) {
  557. ast_log(AST_LOG_WARNING, "Failed to remove framehook from channel %s\n", ast_channel_name(chan));
  558. return -1;
  559. }
  560. if (ast_channel_datastore_remove(chan, datastore)) {
  561. ast_log(AST_LOG_WARNING, "Failed to remove datastore from channel %s\n", ast_channel_name(chan));
  562. return -1;
  563. }
  564. ast_datastore_free(datastore);
  565. return 0;
  566. }
  567. static struct ast_frame *sla_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
  568. {
  569. struct sla_framehook_data *sla_data = data;
  570. if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
  571. return f;
  572. }
  573. if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HOLD) {
  574. sla_queue_event_conf(SLA_EVENT_HOLD, chan, sla_data->confname);
  575. }
  576. return f;
  577. }
  578. /*! \brief Callback function which informs upstream if we are consuming a frame of a specific type */
  579. static int sla_framehook_consume(void *data, enum ast_frame_type type)
  580. {
  581. return (type == AST_FRAME_CONTROL ? 1 : 0);
  582. }
  583. static int attach_framehook(struct ast_channel *chan, const char *confname)
  584. {
  585. struct ast_datastore *datastore;
  586. struct sla_framehook_data *data;
  587. static struct ast_framehook_interface sla_framehook_interface = {
  588. .version = AST_FRAMEHOOK_INTERFACE_VERSION,
  589. .event_cb = sla_framehook,
  590. .consume_cb = sla_framehook_consume,
  591. .disable_inheritance = 1,
  592. };
  593. SCOPED_CHANNELLOCK(chan_lock, chan);
  594. datastore = ast_channel_datastore_find(chan, &sla_framehook_datastore, NULL);
  595. if (datastore) {
  596. ast_log(AST_LOG_WARNING, "SLA framehook already set on '%s'\n", ast_channel_name(chan));
  597. return 0;
  598. }
  599. datastore = ast_datastore_alloc(&sla_framehook_datastore, NULL);
  600. if (!datastore) {
  601. return -1;
  602. }
  603. data = ast_calloc(1, sizeof(*data));
  604. if (!data) {
  605. ast_datastore_free(datastore);
  606. return -1;
  607. }
  608. data->framehook_id = ast_framehook_attach(chan, &sla_framehook_interface);
  609. data->confname = ast_strdup(confname);
  610. if (!data->confname || data->framehook_id < 0) {
  611. ast_log(AST_LOG_WARNING, "Failed to attach SLA framehook to '%s'\n", ast_channel_name(chan));
  612. ast_datastore_free(datastore);
  613. ast_free(data);
  614. return -1;
  615. }
  616. datastore->data = data;
  617. ast_channel_datastore_add(chan, datastore);
  618. return 0;
  619. }
  620. /*!
  621. * \internal
  622. * \brief Find an SLA trunk by name
  623. */
  624. static struct sla_trunk *sla_find_trunk(const char *name)
  625. {
  626. struct sla_trunk tmp_trunk = {
  627. .name = name,
  628. };
  629. return ao2_find(sla_trunks, &tmp_trunk, OBJ_POINTER);
  630. }
  631. /*!
  632. * \internal
  633. * \brief Find an SLA station by name
  634. */
  635. static struct sla_station *sla_find_station(const char *name)
  636. {
  637. struct sla_station tmp_station = {
  638. .name = name,
  639. };
  640. return ao2_find(sla_stations, &tmp_station, OBJ_POINTER);
  641. }
  642. static int sla_check_station_hold_access(const struct sla_trunk *trunk, const struct sla_station *station)
  643. {
  644. struct sla_station_ref *station_ref;
  645. struct sla_trunk_ref *trunk_ref;
  646. /* For each station that has this call on hold, check for private hold. */
  647. AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
  648. AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
  649. if (trunk_ref->trunk != trunk || station_ref->station == station) {
  650. continue;
  651. }
  652. if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME && station_ref->station->hold_access == SLA_HOLD_PRIVATE) {
  653. return 1;
  654. }
  655. return 0;
  656. }
  657. }
  658. return 0;
  659. }
  660. /*!
  661. * \brief Find a trunk reference on a station by name
  662. * \param station the station
  663. * \param name the trunk's name
  664. * \pre sla_station is locked
  665. * \return a pointer to the station's trunk reference. If the trunk
  666. * is not found, it is not idle and barge is disabled, or if
  667. * it is on hold and private hold is set, then NULL will be returned.
  668. */
  669. static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station *station, const char *name)
  670. {
  671. struct sla_trunk_ref *trunk_ref = NULL;
  672. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  673. if (strcasecmp(trunk_ref->trunk->name, name)) {
  674. continue;
  675. }
  676. if (trunk_ref->trunk->barge_disabled && trunk_ref->state == SLA_TRUNK_STATE_UP) {
  677. ast_debug(2, "Barge disabled, trunk not available\n");
  678. trunk_ref = NULL;
  679. } else if (trunk_ref->trunk->hold_stations && trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE && trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
  680. ast_debug(2, "Private hold by another station\n");
  681. trunk_ref = NULL;
  682. } else if (sla_check_station_hold_access(trunk_ref->trunk, station)) {
  683. ast_debug(2, "No hold access\n");
  684. trunk_ref = NULL;
  685. }
  686. break;
  687. }
  688. if (trunk_ref) {
  689. ao2_ref(trunk_ref, 1);
  690. }
  691. return trunk_ref;
  692. }
  693. static void sla_station_ref_destructor(void *obj)
  694. {
  695. struct sla_station_ref *station_ref = obj;
  696. if (station_ref->station) {
  697. ao2_ref(station_ref->station, -1);
  698. station_ref->station = NULL;
  699. }
  700. }
  701. static struct sla_station_ref *sla_create_station_ref(struct sla_station *station)
  702. {
  703. struct sla_station_ref *station_ref;
  704. if (!(station_ref = ao2_alloc(sizeof(*station_ref), sla_station_ref_destructor))) {
  705. return NULL;
  706. }
  707. ao2_ref(station, 1);
  708. station_ref->station = station;
  709. return station_ref;
  710. }
  711. static struct sla_ringing_station *sla_create_ringing_station(struct sla_station *station)
  712. {
  713. struct sla_ringing_station *ringing_station;
  714. if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station)))) {
  715. return NULL;
  716. }
  717. ao2_ref(station, 1);
  718. ringing_station->station = station;
  719. ringing_station->ring_begin = ast_tvnow();
  720. return ringing_station;
  721. }
  722. static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
  723. {
  724. if (ringing_station->station) {
  725. ao2_ref(ringing_station->station, -1);
  726. ringing_station->station = NULL;
  727. }
  728. ast_free(ringing_station);
  729. }
  730. static struct sla_failed_station *sla_create_failed_station(struct sla_station *station)
  731. {
  732. struct sla_failed_station *failed_station;
  733. if (!(failed_station = ast_calloc(1, sizeof(*failed_station)))) {
  734. return NULL;
  735. }
  736. ao2_ref(station, 1);
  737. failed_station->station = station;
  738. failed_station->last_try = ast_tvnow();
  739. return failed_station;
  740. }
  741. static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
  742. {
  743. if (failed_station->station) {
  744. ao2_ref(failed_station->station, -1);
  745. failed_station->station = NULL;
  746. }
  747. ast_free(failed_station);
  748. }
  749. static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
  750. {
  751. switch (state) {
  752. case SLA_TRUNK_STATE_IDLE:
  753. return AST_DEVICE_NOT_INUSE;
  754. case SLA_TRUNK_STATE_RINGING:
  755. return AST_DEVICE_RINGING;
  756. case SLA_TRUNK_STATE_UP:
  757. return AST_DEVICE_INUSE;
  758. case SLA_TRUNK_STATE_ONHOLD:
  759. case SLA_TRUNK_STATE_ONHOLD_BYME:
  760. return AST_DEVICE_ONHOLD;
  761. }
  762. return AST_DEVICE_UNKNOWN;
  763. }
  764. static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state,
  765. enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
  766. {
  767. struct sla_station *station;
  768. struct sla_trunk_ref *trunk_ref;
  769. struct ao2_iterator i;
  770. i = ao2_iterator_init(sla_stations, 0);
  771. while ((station = ao2_iterator_next(&i))) {
  772. ao2_lock(station);
  773. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  774. if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0) || trunk_ref == exclude) {
  775. continue;
  776. }
  777. trunk_ref->state = state;
  778. ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE, "SLA:%s_%s", station->name, trunk->name);
  779. break;
  780. }
  781. ao2_unlock(station);
  782. ao2_ref(station, -1);
  783. }
  784. ao2_iterator_destroy(&i);
  785. }
  786. struct run_station_args {
  787. struct sla_station *station;
  788. struct sla_trunk_ref *trunk_ref;
  789. ast_mutex_t *cond_lock;
  790. ast_cond_t *cond;
  791. };
  792. static void answer_trunk_chan(struct ast_channel *chan)
  793. {
  794. ast_raw_answer(chan); /* Do NOT use ast_answer since that waits for media using ast_waitfor_nandfds. */
  795. ast_indicate(chan, -1);
  796. }
  797. static int conf_run(struct ast_channel *chan, const char *confname, struct ast_flags *confflags, char *optargs[])
  798. {
  799. char confbridge_args[256];
  800. int res = 0;
  801. snprintf(confbridge_args, sizeof(confbridge_args), "%s", confname);
  802. res |= ast_func_write(chan, "CONFBRIDGE(user,quiet)", ast_test_flag(confflags, CONFFLAG_QUIET) ? "1" : "0");
  803. res |= ast_func_write(chan, "CONFBRIDGE(user,dtmf_passthrough)", ast_test_flag(confflags, CONFFLAG_PASS_DTMF) ? "1" : "0");
  804. res |= ast_func_write(chan, "CONFBRIDGE(user,marked)", ast_test_flag(confflags, CONFFLAG_MARKEDUSER) ? "1" : "0");
  805. res |= ast_func_write(chan, "CONFBRIDGE(user,end_marked)", ast_test_flag(confflags, CONFFLAG_MARKEDEXIT) ? "1" : "0");
  806. res |= ast_func_write(chan, "CONFBRIDGE(user,music_on_hold_when_empty)", ast_test_flag(confflags, CONFFLAG_MOH) ? "1" : "0");
  807. if (ast_test_flag(confflags, CONFFLAG_MOH) && !ast_strlen_zero(optargs[SLA_TRUNK_OPT_ARG_MOH_CLASS])) {
  808. res |= ast_func_write(chan, "CONFBRIDGE(user,music_on_hold_class)", optargs[SLA_TRUNK_OPT_ARG_MOH_CLASS]);
  809. }
  810. if (res) {
  811. ast_log(LOG_ERROR, "Failed to set up conference, aborting\n");
  812. return -1;
  813. }
  814. /* Attach a framehook that we'll use to process HOLD from stations. */
  815. if (ast_test_flag(confflags, CONFFLAG_SLA_STATION) && attach_framehook(chan, confname)) {
  816. return -1;
  817. }
  818. ast_debug(2, "Channel %s is running ConfBridge(%s)\n", ast_channel_name(chan), confbridge_args);
  819. res = ast_pbx_exec_application(chan, "ConfBridge", confbridge_args);
  820. if (ast_test_flag(confflags, CONFFLAG_SLA_STATION)) {
  821. remove_framehook(chan);
  822. }
  823. return res;
  824. }
  825. static int conf_kick_all(struct ast_channel *chan, const char *confname)
  826. {
  827. char confkick_args[256];
  828. snprintf(confkick_args, sizeof(confkick_args), "%s,all", confname);
  829. ast_debug(2, "Kicking all participants from conference %s\n", confname);
  830. if (chan) {
  831. return ast_pbx_exec_application(chan, "ConfKick", confkick_args);
  832. } else {
  833. /* We might not have a channel available to us, use a dummy channel in that case. */
  834. chan = ast_dummy_channel_alloc();
  835. if (!chan) {
  836. ast_log(LOG_WARNING, "Failed to allocate dummy channel\n");
  837. return -1;
  838. } else {
  839. int res = ast_pbx_exec_application(chan, "ConfKick", confkick_args);
  840. ast_channel_unref(chan);
  841. return res;
  842. }
  843. }
  844. }
  845. static void *run_station(void *data)
  846. {
  847. RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
  848. RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
  849. struct ast_str *conf_name = ast_str_create(16);
  850. struct ast_flags conf_flags = { 0 };
  851. {
  852. struct run_station_args *args = data;
  853. station = args->station;
  854. trunk_ref = args->trunk_ref;
  855. ast_mutex_lock(args->cond_lock);
  856. ast_cond_signal(args->cond);
  857. ast_mutex_unlock(args->cond_lock);
  858. /* args is no longer valid here. */
  859. }
  860. ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1);
  861. ast_str_set(&conf_name, 0, "SLA_%s", trunk_ref->trunk->name);
  862. ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
  863. answer_trunk_chan(trunk_ref->chan);
  864. ast_debug(2, "Station %s joining conference %s\n", station->name, ast_str_buffer(conf_name));
  865. conf_run(trunk_ref->chan, ast_str_buffer(conf_name), &conf_flags, NULL);
  866. trunk_ref->chan = NULL;
  867. if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
  868. trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
  869. conf_kick_all(NULL, ast_str_buffer(conf_name));
  870. trunk_ref->trunk->hold_stations = 0;
  871. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  872. }
  873. ast_dial_join(station->dial);
  874. ast_dial_destroy(station->dial);
  875. station->dial = NULL;
  876. ast_free(conf_name);
  877. return NULL;
  878. }
  879. static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk);
  880. static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
  881. {
  882. struct sla_station_ref *station_ref;
  883. conf_kick_all(ringing_trunk->trunk->chan, ringing_trunk->trunk->name);
  884. sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  885. while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry))) {
  886. ao2_ref(station_ref, -1);
  887. }
  888. sla_ringing_trunk_destroy(ringing_trunk);
  889. }
  890. static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
  891. {
  892. struct sla_ringing_trunk *ringing_trunk;
  893. struct sla_trunk_ref *trunk_ref;
  894. struct sla_station_ref *station_ref;
  895. ast_dial_join(ringing_station->station->dial);
  896. ast_dial_destroy(ringing_station->station->dial);
  897. ringing_station->station->dial = NULL;
  898. if (hangup == SLA_STATION_HANGUP_NORMAL) {
  899. goto done;
  900. }
  901. /* If the station is being hung up because of a timeout, then add it to the
  902. * list of timed out stations on each of the ringing trunks. This is so
  903. * that when doing further processing to figure out which stations should be
  904. * ringing, which trunk to answer, determining timeouts, etc., we know which
  905. * ringing trunks we should ignore. */
  906. AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
  907. AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
  908. if (ringing_trunk->trunk == trunk_ref->trunk) {
  909. break;
  910. }
  911. }
  912. if (!trunk_ref) {
  913. continue;
  914. }
  915. if (!(station_ref = sla_create_station_ref(ringing_station->station))) {
  916. continue;
  917. }
  918. AST_LIST_INSERT_TAIL(&ringing_trunk->timed_out_stations, station_ref, entry);
  919. }
  920. done:
  921. sla_ringing_station_destroy(ringing_station);
  922. }
  923. static void sla_dial_state_callback(struct ast_dial *dial)
  924. {
  925. sla_queue_event(SLA_EVENT_DIAL_STATE);
  926. }
  927. /*! \brief Check to see if dialing this station already timed out for this ringing trunk
  928. * \note Assumes sla.lock is locked
  929. */
  930. static int sla_check_timed_out_station(const struct sla_ringing_trunk *ringing_trunk, const struct sla_station *station)
  931. {
  932. struct sla_station_ref *timed_out_station;
  933. AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, timed_out_station, entry) {
  934. if (station == timed_out_station->station) {
  935. return 1;
  936. }
  937. }
  938. return 0;
  939. }
  940. /*! \brief Choose the highest priority ringing trunk for a station
  941. * \param station the station
  942. * \param rm remove the ringing trunk once selected
  943. * \param trunk_ref a place to store the pointer to this stations reference to
  944. * the selected trunk
  945. * \return a pointer to the selected ringing trunk, or NULL if none found
  946. * \note Assumes that sla.lock is locked
  947. */
  948. static struct sla_ringing_trunk *sla_choose_ringing_trunk(struct sla_station *station, struct sla_trunk_ref **trunk_ref, int rm)
  949. {
  950. struct sla_trunk_ref *s_trunk_ref;
  951. struct sla_ringing_trunk *ringing_trunk = NULL;
  952. AST_LIST_TRAVERSE(&station->trunks, s_trunk_ref, entry) {
  953. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
  954. /* Make sure this is the trunk we're looking for */
  955. if (s_trunk_ref->trunk != ringing_trunk->trunk) {
  956. continue;
  957. }
  958. /* This trunk on the station is ringing. But, make sure this station
  959. * didn't already time out while this trunk was ringing. */
  960. if (sla_check_timed_out_station(ringing_trunk, station)) {
  961. continue;
  962. }
  963. if (rm) {
  964. AST_LIST_REMOVE_CURRENT(entry);
  965. }
  966. if (trunk_ref) {
  967. ao2_ref(s_trunk_ref, 1);
  968. *trunk_ref = s_trunk_ref;
  969. }
  970. break;
  971. }
  972. AST_LIST_TRAVERSE_SAFE_END;
  973. if (ringing_trunk) {
  974. break;
  975. }
  976. }
  977. return ringing_trunk;
  978. }
  979. static void sla_handle_dial_state_event(void)
  980. {
  981. struct sla_ringing_station *ringing_station;
  982. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
  983. RAII_VAR(struct sla_trunk_ref *, s_trunk_ref, NULL, ao2_cleanup);
  984. struct sla_ringing_trunk *ringing_trunk = NULL;
  985. struct run_station_args args;
  986. enum ast_dial_result dial_res;
  987. pthread_t dont_care;
  988. ast_mutex_t cond_lock;
  989. ast_cond_t cond;
  990. switch ((dial_res = ast_dial_state(ringing_station->station->dial))) {
  991. case AST_DIAL_RESULT_HANGUP:
  992. case AST_DIAL_RESULT_INVALID:
  993. case AST_DIAL_RESULT_FAILED:
  994. case AST_DIAL_RESULT_TIMEOUT:
  995. case AST_DIAL_RESULT_UNANSWERED:
  996. AST_LIST_REMOVE_CURRENT(entry);
  997. sla_stop_ringing_station(ringing_station, SLA_STATION_HANGUP_NORMAL);
  998. break;
  999. case AST_DIAL_RESULT_ANSWERED:
  1000. AST_LIST_REMOVE_CURRENT(entry);
  1001. /* Find the appropriate trunk to answer. */
  1002. ast_mutex_lock(&sla.lock);
  1003. ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
  1004. ast_mutex_unlock(&sla.lock);
  1005. if (!ringing_trunk) {
  1006. /* This case happens in a bit of a race condition. If two stations answer
  1007. * the outbound call at the same time, the first one will get connected to
  1008. * the trunk. When the second one gets here, it will not see any trunks
  1009. * ringing so we have no idea what to conect it to. So, we just hang up
  1010. * on it. */
  1011. ast_debug(1, "Found no ringing trunk for station '%s' to answer!\n", ringing_station->station->name);
  1012. ast_dial_join(ringing_station->station->dial);
  1013. ast_dial_destroy(ringing_station->station->dial);
  1014. ringing_station->station->dial = NULL;
  1015. sla_ringing_station_destroy(ringing_station);
  1016. break;
  1017. }
  1018. /* Track the channel that answered this trunk */
  1019. s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
  1020. /* Actually answer the trunk */
  1021. answer_trunk_chan(ringing_trunk->trunk->chan);
  1022. sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
  1023. /* Now, start a thread that will connect this station to the trunk. The rest of
  1024. * the code here sets up the thread and ensures that it is able to save the arguments
  1025. * before they are no longer valid since they are allocated on the stack. */
  1026. ao2_ref(s_trunk_ref, 1);
  1027. args.trunk_ref = s_trunk_ref;
  1028. ao2_ref(ringing_station->station, 1);
  1029. args.station = ringing_station->station;
  1030. args.cond = &cond;
  1031. args.cond_lock = &cond_lock;
  1032. sla_ringing_trunk_destroy(ringing_trunk);
  1033. sla_ringing_station_destroy(ringing_station);
  1034. ast_mutex_init(&cond_lock);
  1035. ast_cond_init(&cond, NULL);
  1036. ast_mutex_lock(&cond_lock);
  1037. ast_pthread_create_detached_background(&dont_care, NULL, run_station, &args);
  1038. ast_cond_wait(&cond, &cond_lock);
  1039. ast_mutex_unlock(&cond_lock);
  1040. ast_mutex_destroy(&cond_lock);
  1041. ast_cond_destroy(&cond);
  1042. break;
  1043. case AST_DIAL_RESULT_TRYING:
  1044. case AST_DIAL_RESULT_RINGING:
  1045. case AST_DIAL_RESULT_PROGRESS:
  1046. case AST_DIAL_RESULT_PROCEEDING:
  1047. break;
  1048. }
  1049. if (dial_res == AST_DIAL_RESULT_ANSWERED) {
  1050. /* Queue up reprocessing ringing trunks, and then ringing stations again */
  1051. sla_queue_event(SLA_EVENT_RINGING_TRUNK);
  1052. sla_queue_event(SLA_EVENT_DIAL_STATE);
  1053. break;
  1054. }
  1055. }
  1056. AST_LIST_TRAVERSE_SAFE_END;
  1057. }
  1058. /*! \brief Check to see if this station is already ringing
  1059. * \note Assumes sla.lock is locked
  1060. */
  1061. static int sla_check_ringing_station(const struct sla_station *station)
  1062. {
  1063. struct sla_ringing_station *ringing_station;
  1064. AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_station, entry) {
  1065. if (station == ringing_station->station) {
  1066. return 1;
  1067. }
  1068. }
  1069. return 0;
  1070. }
  1071. /*! \brief Check to see if this station has failed to be dialed in the past minute
  1072. * \note assumes sla.lock is locked
  1073. */
  1074. static int sla_check_failed_station(const struct sla_station *station)
  1075. {
  1076. struct sla_failed_station *failed_station;
  1077. int res = 0;
  1078. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
  1079. if (station != failed_station->station) {
  1080. continue;
  1081. }
  1082. if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
  1083. AST_LIST_REMOVE_CURRENT(entry);
  1084. sla_failed_station_destroy(failed_station);
  1085. break;
  1086. }
  1087. res = 1;
  1088. }
  1089. AST_LIST_TRAVERSE_SAFE_END
  1090. return res;
  1091. }
  1092. /*! \brief Ring a station
  1093. * \note Assumes sla.lock is locked
  1094. */
  1095. static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
  1096. {
  1097. char *tech, *tech_data;
  1098. struct ast_dial *dial;
  1099. struct sla_ringing_station *ringing_station;
  1100. enum ast_dial_result res;
  1101. int caller_is_saved;
  1102. struct ast_party_caller caller;
  1103. if (!(dial = ast_dial_create())) {
  1104. return -1;
  1105. }
  1106. ast_dial_set_state_callback(dial, sla_dial_state_callback);
  1107. tech_data = ast_strdupa(station->device);
  1108. tech = strsep(&tech_data, "/");
  1109. if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
  1110. ast_dial_destroy(dial);
  1111. return -1;
  1112. }
  1113. /* Do we need to save off the caller ID data? */
  1114. caller_is_saved = 0;
  1115. if (!sla.attempt_callerid) {
  1116. caller_is_saved = 1;
  1117. caller = *ast_channel_caller(ringing_trunk->trunk->chan);
  1118. ast_party_caller_init(ast_channel_caller(ringing_trunk->trunk->chan));
  1119. }
  1120. res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
  1121. /* Restore saved caller ID */
  1122. if (caller_is_saved) {
  1123. ast_party_caller_free(ast_channel_caller(ringing_trunk->trunk->chan));
  1124. ast_channel_caller_set(ringing_trunk->trunk->chan, &caller);
  1125. }
  1126. if (res != AST_DIAL_RESULT_TRYING) {
  1127. struct sla_failed_station *failed_station;
  1128. ast_dial_destroy(dial);
  1129. if ((failed_station = sla_create_failed_station(station))) {
  1130. AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
  1131. }
  1132. return -1;
  1133. }
  1134. if (!(ringing_station = sla_create_ringing_station(station))) {
  1135. ast_dial_join(dial);
  1136. ast_dial_destroy(dial);
  1137. return -1;
  1138. }
  1139. station->dial = dial;
  1140. AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_station, entry);
  1141. return 0;
  1142. }
  1143. /*! \brief Check to see if a station is in use
  1144. */
  1145. static int sla_check_inuse_station(const struct sla_station *station)
  1146. {
  1147. struct sla_trunk_ref *trunk_ref;
  1148. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  1149. if (trunk_ref->chan) {
  1150. return 1;
  1151. }
  1152. }
  1153. return 0;
  1154. }
  1155. static struct sla_trunk_ref *sla_find_trunk_ref(const struct sla_station *station, const struct sla_trunk *trunk)
  1156. {
  1157. struct sla_trunk_ref *trunk_ref = NULL;
  1158. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  1159. if (trunk_ref->trunk == trunk) {
  1160. break;
  1161. }
  1162. }
  1163. ao2_ref(trunk_ref, 1);
  1164. return trunk_ref;
  1165. }
  1166. /*! \brief Calculate the ring delay for a given ringing trunk on a station
  1167. * \param station the station
  1168. * \param ringing_trunk the trunk. If NULL, the highest priority ringing trunk will be used
  1169. * \return the number of ms left before the delay is complete, or INT_MAX if there is no delay
  1170. */
  1171. static int sla_check_station_delay(struct sla_station *station, struct sla_ringing_trunk *ringing_trunk)
  1172. {
  1173. RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
  1174. unsigned int delay = UINT_MAX;
  1175. int time_left, time_elapsed;
  1176. if (!ringing_trunk) {
  1177. ringing_trunk = sla_choose_ringing_trunk(station, &trunk_ref, 0);
  1178. } else {
  1179. trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk);
  1180. }
  1181. if (!ringing_trunk || !trunk_ref) {
  1182. return delay;
  1183. }
  1184. /* If this station has a ring delay specific to the highest priority
  1185. * ringing trunk, use that. Otherwise, use the ring delay specified
  1186. * globally for the station. */
  1187. delay = trunk_ref->ring_delay;
  1188. if (!delay) {
  1189. delay = station->ring_delay;
  1190. }
  1191. if (!delay) {
  1192. return INT_MAX;
  1193. }
  1194. time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
  1195. time_left = (delay * 1000) - time_elapsed;
  1196. return time_left;
  1197. }
  1198. /*! \brief Ring stations based on current set of ringing trunks
  1199. * \note Assumes that sla.lock is locked
  1200. */
  1201. static void sla_ring_stations(void)
  1202. {
  1203. struct sla_station_ref *station_ref;
  1204. struct sla_ringing_trunk *ringing_trunk;
  1205. /* Make sure that every station that uses at least one of the ringing
  1206. * trunks, is ringing. */
  1207. AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
  1208. AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
  1209. int time_left;
  1210. /* Is this station already ringing? */
  1211. if (sla_check_ringing_station(station_ref->station)) {
  1212. continue;
  1213. }
  1214. /* Is this station already in a call? */
  1215. if (sla_check_inuse_station(station_ref->station)) {
  1216. continue;
  1217. }
  1218. /* Did we fail to dial this station earlier? If so, has it been
  1219. * a minute since we tried? */
  1220. if (sla_check_failed_station(station_ref->station)) {
  1221. continue;
  1222. }
  1223. /* If this station already timed out while this trunk was ringing,
  1224. * do not dial it again for this ringing trunk. */
  1225. if (sla_check_timed_out_station(ringing_trunk, station_ref->station)) {
  1226. continue;
  1227. }
  1228. /* Check for a ring delay in progress */
  1229. time_left = sla_check_station_delay(station_ref->station, ringing_trunk);
  1230. if (time_left != INT_MAX && time_left > 0) {
  1231. continue;
  1232. }
  1233. /* It is time to make this station begin to ring. Do it! */
  1234. sla_ring_station(ringing_trunk, station_ref->station);
  1235. }
  1236. }
  1237. /* Now, all of the stations that should be ringing, are ringing. */
  1238. }
  1239. static void sla_hangup_stations(void)
  1240. {
  1241. struct sla_trunk_ref *trunk_ref;
  1242. struct sla_ringing_station *ringing_station;
  1243. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
  1244. AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
  1245. struct sla_ringing_trunk *ringing_trunk;
  1246. ast_mutex_lock(&sla.lock);
  1247. AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
  1248. if (trunk_ref->trunk == ringing_trunk->trunk) {
  1249. break;
  1250. }
  1251. }
  1252. ast_mutex_unlock(&sla.lock);
  1253. if (ringing_trunk) {
  1254. break;
  1255. }
  1256. }
  1257. if (!trunk_ref) {
  1258. AST_LIST_REMOVE_CURRENT(entry);
  1259. ast_dial_join(ringing_station->station->dial);
  1260. ast_dial_destroy(ringing_station->station->dial);
  1261. ringing_station->station->dial = NULL;
  1262. sla_ringing_station_destroy(ringing_station);
  1263. }
  1264. }
  1265. AST_LIST_TRAVERSE_SAFE_END
  1266. }
  1267. static void sla_handle_ringing_trunk_event(void)
  1268. {
  1269. ast_mutex_lock(&sla.lock);
  1270. sla_ring_stations();
  1271. ast_mutex_unlock(&sla.lock);
  1272. /* Find stations that shouldn't be ringing anymore. */
  1273. sla_hangup_stations();
  1274. }
  1275. static void sla_handle_hold_event(struct sla_event *event)
  1276. {
  1277. ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
  1278. event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
  1279. ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s", event->station->name, event->trunk_ref->trunk->name);
  1280. sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, INACTIVE_TRUNK_REFS, event->trunk_ref);
  1281. if (event->trunk_ref->trunk->active_stations == 1) {
  1282. /* The station putting it on hold is the only one on the call, so start
  1283. * Music on hold to the trunk. */
  1284. event->trunk_ref->trunk->on_hold = 1;
  1285. ast_indicate(event->trunk_ref->trunk->chan, AST_CONTROL_HOLD);
  1286. }
  1287. ast_softhangup(event->trunk_ref->chan, AST_SOFTHANGUP_DEV);
  1288. event->trunk_ref->chan = NULL;
  1289. }
  1290. /*! \brief Process trunk ring timeouts
  1291. * \note Called with sla.lock locked
  1292. * \return non-zero if a change to the ringing trunks was made
  1293. */
  1294. static int sla_calc_trunk_timeouts(unsigned int *timeout)
  1295. {
  1296. struct sla_ringing_trunk *ringing_trunk;
  1297. int res = 0;
  1298. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
  1299. int time_left, time_elapsed;
  1300. if (!ringing_trunk->trunk->ring_timeout) {
  1301. continue;
  1302. }
  1303. time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
  1304. time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
  1305. if (time_left <= 0) {
  1306. pbx_builtin_setvar_helper(ringing_trunk->trunk->chan, "SLATRUNK_STATUS", "RINGTIMEOUT");
  1307. AST_LIST_REMOVE_CURRENT(entry);
  1308. sla_stop_ringing_trunk(ringing_trunk);
  1309. res = 1;
  1310. continue;
  1311. }
  1312. if (time_left < *timeout) {
  1313. *timeout = time_left;
  1314. }
  1315. }
  1316. AST_LIST_TRAVERSE_SAFE_END;
  1317. return res;
  1318. }
  1319. /*! \brief Process station ring timeouts
  1320. * \note Called with sla.lock locked
  1321. * \return non-zero if a change to the ringing stations was made
  1322. */
  1323. static int sla_calc_station_timeouts(unsigned int *timeout)
  1324. {
  1325. struct sla_ringing_trunk *ringing_trunk;
  1326. struct sla_ringing_station *ringing_station;
  1327. int res = 0;
  1328. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
  1329. unsigned int ring_timeout = 0;
  1330. int time_elapsed, time_left = INT_MAX, final_trunk_time_left = INT_MIN;
  1331. struct sla_trunk_ref *trunk_ref;
  1332. /* If there are any ring timeouts specified for a specific trunk
  1333. * on the station, then use the highest per-trunk ring timeout.
  1334. * Otherwise, use the ring timeout set for the entire station. */
  1335. AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
  1336. struct sla_station_ref *station_ref;
  1337. int trunk_time_elapsed, trunk_time_left;
  1338. AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
  1339. if (ringing_trunk->trunk == trunk_ref->trunk) {
  1340. break;
  1341. }
  1342. }
  1343. if (!ringing_trunk) {
  1344. continue;
  1345. }
  1346. /* If there is a trunk that is ringing without a timeout, then the
  1347. * only timeout that could matter is a global station ring timeout. */
  1348. if (!trunk_ref->ring_timeout) {
  1349. break;
  1350. }
  1351. /* This trunk on this station is ringing and has a timeout.
  1352. * However, make sure this trunk isn't still ringing from a
  1353. * previous timeout. If so, don't consider it. */
  1354. AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, station_ref, entry) {
  1355. if (station_ref->station == ringing_station->station) {
  1356. break;
  1357. }
  1358. }
  1359. if (station_ref) {
  1360. continue;
  1361. }
  1362. trunk_time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
  1363. trunk_time_left = (trunk_ref->ring_timeout * 1000) - trunk_time_elapsed;
  1364. if (trunk_time_left > final_trunk_time_left) {
  1365. final_trunk_time_left = trunk_time_left;
  1366. }
  1367. }
  1368. /* No timeout was found for ringing trunks, and no timeout for the entire station */
  1369. if (final_trunk_time_left == INT_MIN && !ringing_station->station->ring_timeout) {
  1370. continue;
  1371. }
  1372. /* Compute how much time is left for a global station timeout */
  1373. if (ringing_station->station->ring_timeout) {
  1374. ring_timeout = ringing_station->station->ring_timeout;
  1375. time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
  1376. time_left = (ring_timeout * 1000) - time_elapsed;
  1377. }
  1378. /* If the time left based on the per-trunk timeouts is smaller than the
  1379. * global station ring timeout, use that. */
  1380. if (final_trunk_time_left > INT_MIN && final_trunk_time_left < time_left) {
  1381. time_left = final_trunk_time_left;
  1382. }
  1383. /* If there is no time left, the station needs to stop ringing */
  1384. if (time_left <= 0) {
  1385. AST_LIST_REMOVE_CURRENT(entry);
  1386. sla_stop_ringing_station(ringing_station, SLA_STATION_HANGUP_TIMEOUT);
  1387. res = 1;
  1388. continue;
  1389. }
  1390. /* There is still some time left for this station to ring, so save that
  1391. * timeout if it is the first event scheduled to occur */
  1392. if (time_left < *timeout) {
  1393. *timeout = time_left;
  1394. }
  1395. }
  1396. AST_LIST_TRAVERSE_SAFE_END;
  1397. return res;
  1398. }
  1399. /*! \brief Calculate the ring delay for a station
  1400. * \note Assumes sla.lock is locked
  1401. */
  1402. static int sla_calc_station_delays(unsigned int *timeout)
  1403. {
  1404. struct sla_station *station;
  1405. int res = 0;
  1406. struct ao2_iterator i;
  1407. i = ao2_iterator_init(sla_stations, 0);
  1408. for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
  1409. struct sla_ringing_trunk *ringing_trunk;
  1410. int time_left;
  1411. /* Ignore stations already ringing */
  1412. if (sla_check_ringing_station(station)) {
  1413. continue;
  1414. }
  1415. /* Ignore stations already on a call */
  1416. if (sla_check_inuse_station(station)) {
  1417. continue;
  1418. }
  1419. /* Ignore stations that don't have one of their trunks ringing */
  1420. if (!(ringing_trunk = sla_choose_ringing_trunk(station, NULL, 0))) {
  1421. continue;
  1422. }
  1423. if ((time_left = sla_check_station_delay(station, ringing_trunk)) == INT_MAX) {
  1424. continue;
  1425. }
  1426. /* If there is no time left, then the station needs to start ringing.
  1427. * Return non-zero so that an event will be queued up an event to
  1428. * make that happen. */
  1429. if (time_left <= 0) {
  1430. res = 1;
  1431. continue;
  1432. }
  1433. if (time_left < *timeout) {
  1434. *timeout = time_left;
  1435. }
  1436. }
  1437. ao2_iterator_destroy(&i);
  1438. return res;
  1439. }
  1440. /*! \brief Calculate the time until the next known event
  1441. * \note Called with sla.lock locked */
  1442. static int sla_process_timers(struct timespec *ts)
  1443. {
  1444. unsigned int timeout = UINT_MAX;
  1445. struct timeval wait;
  1446. unsigned int change_made = 0;
  1447. /* Check for ring timeouts on ringing trunks */
  1448. if (sla_calc_trunk_timeouts(&timeout)) {
  1449. change_made = 1;
  1450. }
  1451. /* Check for ring timeouts on ringing stations */
  1452. if (sla_calc_station_timeouts(&timeout)) {
  1453. change_made = 1;
  1454. }
  1455. /* Check for station ring delays */
  1456. if (sla_calc_station_delays(&timeout)) {
  1457. change_made = 1;
  1458. }
  1459. /* queue reprocessing of ringing trunks */
  1460. if (change_made) {
  1461. sla_queue_event_nolock(SLA_EVENT_RINGING_TRUNK);
  1462. }
  1463. /* No timeout */
  1464. if (timeout == UINT_MAX) {
  1465. return 0;
  1466. }
  1467. if (ts) {
  1468. wait = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1000));
  1469. ts->tv_sec = wait.tv_sec;
  1470. ts->tv_nsec = wait.tv_usec * 1000;
  1471. }
  1472. return 1;
  1473. }
  1474. static void sla_event_destroy(struct sla_event *event)
  1475. {
  1476. if (event->trunk_ref) {
  1477. ao2_ref(event->trunk_ref, -1);
  1478. event->trunk_ref = NULL;
  1479. }
  1480. if (event->station) {
  1481. ao2_ref(event->station, -1);
  1482. event->station = NULL;
  1483. }
  1484. ast_free(event);
  1485. }
  1486. static void *sla_thread(void *data)
  1487. {
  1488. struct sla_failed_station *failed_station;
  1489. struct sla_ringing_station *ringing_station;
  1490. ast_mutex_lock(&sla.lock);
  1491. while (!sla.stop) {
  1492. struct sla_event *event;
  1493. struct timespec ts = { 0, };
  1494. unsigned int have_timeout = 0;
  1495. if (AST_LIST_EMPTY(&sla.event_q)) {
  1496. if ((have_timeout = sla_process_timers(&ts))) {
  1497. ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
  1498. } else {
  1499. ast_cond_wait(&sla.cond, &sla.lock);
  1500. }
  1501. if (sla.stop) {
  1502. break;
  1503. }
  1504. }
  1505. if (have_timeout) {
  1506. sla_process_timers(NULL);
  1507. }
  1508. while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
  1509. ast_mutex_unlock(&sla.lock);
  1510. switch (event->type) {
  1511. case SLA_EVENT_HOLD:
  1512. sla_handle_hold_event(event);
  1513. break;
  1514. case SLA_EVENT_DIAL_STATE:
  1515. sla_handle_dial_state_event();
  1516. break;
  1517. case SLA_EVENT_RINGING_TRUNK:
  1518. sla_handle_ringing_trunk_event();
  1519. break;
  1520. }
  1521. sla_event_destroy(event);
  1522. ast_mutex_lock(&sla.lock);
  1523. }
  1524. }
  1525. ast_mutex_unlock(&sla.lock);
  1526. while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry))) {
  1527. sla_ringing_station_destroy(ringing_station);
  1528. }
  1529. while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry))) {
  1530. sla_failed_station_destroy(failed_station);
  1531. }
  1532. return NULL;
  1533. }
  1534. struct dial_trunk_args {
  1535. struct sla_trunk_ref *trunk_ref;
  1536. struct sla_station *station;
  1537. ast_mutex_t *cond_lock;
  1538. ast_cond_t *cond;
  1539. };
  1540. static void *dial_trunk(void *data)
  1541. {
  1542. struct dial_trunk_args *args = data;
  1543. struct ast_dial *dial;
  1544. char *tech, *tech_data;
  1545. enum ast_dial_result dial_res;
  1546. char conf_name[MAX_CONFNUM];
  1547. struct ast_flags conf_flags = { 0 };
  1548. RAII_VAR(struct sla_trunk_ref *, trunk_ref, args->trunk_ref, ao2_cleanup);
  1549. RAII_VAR(struct sla_station *, station, args->station, ao2_cleanup);
  1550. int caller_is_saved;
  1551. struct ast_party_caller caller;
  1552. int last_state = 0;
  1553. int current_state = 0;
  1554. if (!(dial = ast_dial_create())) {
  1555. ast_mutex_lock(args->cond_lock);
  1556. ast_cond_signal(args->cond);
  1557. ast_mutex_unlock(args->cond_lock);
  1558. return NULL;
  1559. }
  1560. tech_data = ast_strdupa(trunk_ref->trunk->device);
  1561. tech = strsep(&tech_data, "/");
  1562. if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
  1563. ast_mutex_lock(args->cond_lock);
  1564. ast_cond_signal(args->cond);
  1565. ast_mutex_unlock(args->cond_lock);
  1566. ast_dial_destroy(dial);
  1567. return NULL;
  1568. }
  1569. /* Do we need to save of the caller ID data? */
  1570. caller_is_saved = 0;
  1571. if (!sla.attempt_callerid) {
  1572. caller_is_saved = 1;
  1573. caller = *ast_channel_caller(trunk_ref->chan);
  1574. ast_party_caller_init(ast_channel_caller(trunk_ref->chan));
  1575. }
  1576. dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
  1577. /* Restore saved caller ID */
  1578. if (caller_is_saved) {
  1579. ast_party_caller_free(ast_channel_caller(trunk_ref->chan));
  1580. ast_channel_caller_set(trunk_ref->chan, &caller);
  1581. }
  1582. if (dial_res != AST_DIAL_RESULT_TRYING) {
  1583. ast_mutex_lock(args->cond_lock);
  1584. ast_cond_signal(args->cond);
  1585. ast_mutex_unlock(args->cond_lock);
  1586. ast_dial_destroy(dial);
  1587. return NULL;
  1588. }
  1589. /* Wait for dial to end, while servicing the channel */
  1590. while (ast_waitfor(trunk_ref->chan, 100)) {
  1591. unsigned int done = 0;
  1592. struct ast_frame *fr = ast_read(trunk_ref->chan);
  1593. if (!fr) {
  1594. ast_debug(1, "Channel %s did not return a frame, must have hung up\n", ast_channel_name(trunk_ref->chan));
  1595. done = 1;
  1596. break;
  1597. }
  1598. ast_frfree(fr); /* Ignore while dialing */
  1599. switch ((dial_res = ast_dial_state(dial))) {
  1600. case AST_DIAL_RESULT_ANSWERED:
  1601. trunk_ref->trunk->chan = ast_dial_answered(dial);
  1602. case AST_DIAL_RESULT_HANGUP:
  1603. case AST_DIAL_RESULT_INVALID:
  1604. case AST_DIAL_RESULT_FAILED:
  1605. case AST_DIAL_RESULT_TIMEOUT:
  1606. case AST_DIAL_RESULT_UNANSWERED:
  1607. done = 1;
  1608. break;
  1609. case AST_DIAL_RESULT_TRYING:
  1610. current_state = AST_CONTROL_PROGRESS;
  1611. break;
  1612. case AST_DIAL_RESULT_RINGING:
  1613. case AST_DIAL_RESULT_PROGRESS:
  1614. case AST_DIAL_RESULT_PROCEEDING:
  1615. current_state = AST_CONTROL_RINGING;
  1616. break;
  1617. }
  1618. if (done) {
  1619. break;
  1620. }
  1621. /* check that SLA station that originated trunk call is still alive */
  1622. if (station && ast_device_state(station->device) == AST_DEVICE_NOT_INUSE) {
  1623. ast_debug(3, "Originating station device %s no longer active\n", station->device);
  1624. trunk_ref->trunk->chan = NULL;
  1625. break;
  1626. }
  1627. /* If trunk line state changed, send indication back to originating SLA Station channel */
  1628. if (current_state != last_state) {
  1629. ast_debug(3, "Indicating State Change %d to channel %s\n", current_state, ast_channel_name(trunk_ref->chan));
  1630. ast_indicate(trunk_ref->chan, current_state);
  1631. last_state = current_state;
  1632. }
  1633. }
  1634. if (!trunk_ref->trunk->chan) {
  1635. ast_mutex_lock(args->cond_lock);
  1636. ast_cond_signal(args->cond);
  1637. ast_mutex_unlock(args->cond_lock);
  1638. ast_dial_join(dial);
  1639. ast_dial_destroy(dial);
  1640. return NULL;
  1641. }
  1642. snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
  1643. ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_TRUNK);
  1644. ast_mutex_lock(args->cond_lock);
  1645. ast_cond_signal(args->cond);
  1646. ast_mutex_unlock(args->cond_lock);
  1647. ast_debug(2, "Trunk dial %s joining conference %s\n", trunk_ref->trunk->name, conf_name);
  1648. conf_run(trunk_ref->trunk->chan, conf_name, &conf_flags, NULL);
  1649. /* If the trunk is going away, it is definitely now IDLE. */
  1650. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  1651. trunk_ref->trunk->chan = NULL;
  1652. trunk_ref->trunk->on_hold = 0;
  1653. ast_dial_join(dial);
  1654. ast_dial_destroy(dial);
  1655. return NULL;
  1656. }
  1657. /*!
  1658. * \brief For a given station, choose the highest priority idle trunk
  1659. * \pre sla_station is locked
  1660. */
  1661. static struct sla_trunk_ref *sla_choose_idle_trunk(const struct sla_station *station)
  1662. {
  1663. struct sla_trunk_ref *trunk_ref = NULL;
  1664. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  1665. if (trunk_ref->state == SLA_TRUNK_STATE_IDLE) {
  1666. ao2_ref(trunk_ref, 1);
  1667. break;
  1668. }
  1669. }
  1670. return trunk_ref;
  1671. }
  1672. static int sla_station_exec(struct ast_channel *chan, const char *data)
  1673. {
  1674. char *station_name, *trunk_name;
  1675. RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
  1676. RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
  1677. char conf_name[MAX_CONFNUM];
  1678. struct ast_flags conf_flags = { 0 };
  1679. if (ast_strlen_zero(data)) {
  1680. ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
  1681. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
  1682. return 0;
  1683. }
  1684. trunk_name = ast_strdupa(data);
  1685. station_name = strsep(&trunk_name, "_");
  1686. if (ast_strlen_zero(station_name)) {
  1687. ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
  1688. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
  1689. return 0;
  1690. }
  1691. station = sla_find_station(station_name);
  1692. if (!station) {
  1693. ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
  1694. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
  1695. return 0;
  1696. }
  1697. ao2_lock(station);
  1698. if (!ast_strlen_zero(trunk_name)) {
  1699. trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
  1700. } else {
  1701. trunk_ref = sla_choose_idle_trunk(station);
  1702. }
  1703. ao2_unlock(station);
  1704. if (!trunk_ref) {
  1705. if (ast_strlen_zero(trunk_name)) {
  1706. ast_log(LOG_NOTICE, "No trunks available for call.\n");
  1707. } else {
  1708. ast_log(LOG_NOTICE, "Can't join existing call on trunk '%s' due to access controls.\n", trunk_name);
  1709. }
  1710. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
  1711. return 0;
  1712. }
  1713. if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
  1714. if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1) {
  1715. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
  1716. } else {
  1717. trunk_ref->state = SLA_TRUNK_STATE_UP;
  1718. ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "SLA:%s_%s", station->name, trunk_ref->trunk->name);
  1719. }
  1720. } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
  1721. struct sla_ringing_trunk *ringing_trunk;
  1722. ast_mutex_lock(&sla.lock);
  1723. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
  1724. if (ringing_trunk->trunk == trunk_ref->trunk) {
  1725. AST_LIST_REMOVE_CURRENT(entry);
  1726. break;
  1727. }
  1728. }
  1729. AST_LIST_TRAVERSE_SAFE_END
  1730. ast_mutex_unlock(&sla.lock);
  1731. if (ringing_trunk) {
  1732. answer_trunk_chan(ringing_trunk->trunk->chan);
  1733. sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
  1734. sla_ringing_trunk_destroy(ringing_trunk);
  1735. /* Queue up reprocessing ringing trunks, and then ringing stations again */
  1736. sla_queue_event(SLA_EVENT_RINGING_TRUNK);
  1737. sla_queue_event(SLA_EVENT_DIAL_STATE);
  1738. }
  1739. }
  1740. trunk_ref->chan = chan;
  1741. if (!trunk_ref->trunk->chan) {
  1742. ast_mutex_t cond_lock;
  1743. ast_cond_t cond;
  1744. pthread_t dont_care;
  1745. struct dial_trunk_args args = {
  1746. .trunk_ref = trunk_ref,
  1747. .station = station,
  1748. .cond_lock = &cond_lock,
  1749. .cond = &cond,
  1750. };
  1751. ao2_ref(trunk_ref, 1);
  1752. ao2_ref(station, 1);
  1753. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
  1754. /* Create a thread to dial the trunk and dump it into the conference.
  1755. * However, we want to wait until the trunk has been dialed and the
  1756. * conference is created before continuing on here.
  1757. * Don't autoservice the channel or we'll have multiple threads
  1758. * handling it. dial_trunk services the channel.
  1759. */
  1760. ast_mutex_init(&cond_lock);
  1761. ast_cond_init(&cond, NULL);
  1762. ast_mutex_lock(&cond_lock);
  1763. ast_pthread_create_detached_background(&dont_care, NULL, dial_trunk, &args);
  1764. ast_cond_wait(&cond, &cond_lock);
  1765. ast_mutex_unlock(&cond_lock);
  1766. ast_mutex_destroy(&cond_lock);
  1767. ast_cond_destroy(&cond);
  1768. if (!trunk_ref->trunk->chan) {
  1769. ast_debug(1, "Trunk didn't get created. chan: %lx\n", (unsigned long) trunk_ref->trunk->chan);
  1770. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
  1771. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  1772. trunk_ref->chan = NULL;
  1773. return 0;
  1774. }
  1775. }
  1776. if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
  1777. trunk_ref->trunk->on_hold) {
  1778. trunk_ref->trunk->on_hold = 0;
  1779. ast_indicate(trunk_ref->trunk->chan, AST_CONTROL_UNHOLD);
  1780. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
  1781. }
  1782. snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
  1783. ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
  1784. ast_answer(chan);
  1785. ast_debug(2, "Station %s joining conference %s\n", station->name, conf_name);
  1786. conf_run(chan, conf_name, &conf_flags, NULL);
  1787. trunk_ref->chan = NULL;
  1788. if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
  1789. trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
  1790. conf_kick_all(chan, conf_name);
  1791. trunk_ref->trunk->hold_stations = 0;
  1792. sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  1793. }
  1794. pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
  1795. return 0;
  1796. }
  1797. static void sla_trunk_ref_destructor(void *obj)
  1798. {
  1799. struct sla_trunk_ref *trunk_ref = obj;
  1800. if (trunk_ref->trunk) {
  1801. ao2_ref(trunk_ref->trunk, -1);
  1802. trunk_ref->trunk = NULL;
  1803. }
  1804. }
  1805. static struct sla_trunk_ref *create_trunk_ref(struct sla_trunk *trunk)
  1806. {
  1807. struct sla_trunk_ref *trunk_ref;
  1808. if (!(trunk_ref = ao2_alloc(sizeof(*trunk_ref), sla_trunk_ref_destructor))) {
  1809. return NULL;
  1810. }
  1811. ao2_ref(trunk, 1);
  1812. trunk_ref->trunk = trunk;
  1813. return trunk_ref;
  1814. }
  1815. static struct sla_ringing_trunk *queue_ringing_trunk(struct sla_trunk *trunk)
  1816. {
  1817. struct sla_ringing_trunk *ringing_trunk;
  1818. if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk)))) {
  1819. return NULL;
  1820. }
  1821. ao2_ref(trunk, 1);
  1822. ringing_trunk->trunk = trunk;
  1823. ringing_trunk->ring_begin = ast_tvnow();
  1824. sla_change_trunk_state(trunk, SLA_TRUNK_STATE_RINGING, ALL_TRUNK_REFS, NULL);
  1825. ast_mutex_lock(&sla.lock);
  1826. AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
  1827. ast_mutex_unlock(&sla.lock);
  1828. sla_queue_event(SLA_EVENT_RINGING_TRUNK);
  1829. return ringing_trunk;
  1830. }
  1831. static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
  1832. {
  1833. if (ringing_trunk->trunk) {
  1834. ao2_ref(ringing_trunk->trunk, -1);
  1835. ringing_trunk->trunk = NULL;
  1836. }
  1837. ast_free(ringing_trunk);
  1838. }
  1839. static int sla_trunk_exec(struct ast_channel *chan, const char *data)
  1840. {
  1841. char conf_name[MAX_CONFNUM];
  1842. struct ast_flags conf_flags = { 0 };
  1843. RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
  1844. struct sla_ringing_trunk *ringing_trunk;
  1845. AST_DECLARE_APP_ARGS(args,
  1846. AST_APP_ARG(trunk_name);
  1847. AST_APP_ARG(options);
  1848. );
  1849. char *opts[SLA_TRUNK_OPT_ARG_ARRAY_SIZE] = { NULL, };
  1850. struct ast_flags opt_flags = { 0 };
  1851. char *parse;
  1852. if (ast_strlen_zero(data)) {
  1853. ast_log(LOG_ERROR, "The SLATrunk application requires an argument, the trunk name\n");
  1854. return -1;
  1855. }
  1856. parse = ast_strdupa(data);
  1857. AST_STANDARD_APP_ARGS(args, parse);
  1858. if (args.argc == 2) {
  1859. if (ast_app_parse_options(sla_trunk_opts, &opt_flags, opts, args.options)) {
  1860. ast_log(LOG_ERROR, "Error parsing options for SLATrunk\n");
  1861. return -1;
  1862. }
  1863. }
  1864. trunk = sla_find_trunk(args.trunk_name);
  1865. if (!trunk) {
  1866. ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", args.trunk_name);
  1867. pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
  1868. return 0;
  1869. }
  1870. if (trunk->chan) {
  1871. ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n", args.trunk_name);
  1872. pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
  1873. return 0;
  1874. }
  1875. trunk->chan = chan;
  1876. if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
  1877. pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
  1878. return 0;
  1879. }
  1880. snprintf(conf_name, sizeof(conf_name), "SLA_%s", args.trunk_name);
  1881. ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
  1882. if (ast_test_flag(&opt_flags, SLA_TRUNK_OPT_MOH)) {
  1883. ast_indicate(chan, -1);
  1884. ast_set_flag(&conf_flags, CONFFLAG_MOH);
  1885. } else {
  1886. ast_indicate(chan, AST_CONTROL_RINGING);
  1887. }
  1888. ast_debug(2, "Trunk %s joining conference %s\n", args.trunk_name, conf_name);
  1889. conf_run(chan, conf_name, &conf_flags, opts);
  1890. trunk->chan = NULL;
  1891. trunk->on_hold = 0;
  1892. sla_change_trunk_state(trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
  1893. if (!pbx_builtin_getvar_helper(chan, "SLATRUNK_STATUS")) {
  1894. pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
  1895. }
  1896. /* Remove the entry from the list of ringing trunks if it is still there. */
  1897. ast_mutex_lock(&sla.lock);
  1898. AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
  1899. if (ringing_trunk->trunk == trunk) {
  1900. AST_LIST_REMOVE_CURRENT(entry);
  1901. break;
  1902. }
  1903. }
  1904. AST_LIST_TRAVERSE_SAFE_END;
  1905. ast_mutex_unlock(&sla.lock);
  1906. if (ringing_trunk) {
  1907. sla_ringing_trunk_destroy(ringing_trunk);
  1908. pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
  1909. /* Queue reprocessing of ringing trunks to make stations stop ringing
  1910. * that shouldn't be ringing after this trunk stopped. */
  1911. sla_queue_event(SLA_EVENT_RINGING_TRUNK);
  1912. }
  1913. return 0;
  1914. }
  1915. static enum ast_device_state sla_state(const char *data)
  1916. {
  1917. char *buf, *station_name, *trunk_name;
  1918. RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
  1919. struct sla_trunk_ref *trunk_ref;
  1920. enum ast_device_state res = AST_DEVICE_INVALID;
  1921. trunk_name = buf = ast_strdupa(data);
  1922. station_name = strsep(&trunk_name, "_");
  1923. station = sla_find_station(station_name);
  1924. if (station) {
  1925. ao2_lock(station);
  1926. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  1927. if (!strcasecmp(trunk_name, trunk_ref->trunk->name)) {
  1928. res = sla_state_to_devstate(trunk_ref->state);
  1929. break;
  1930. }
  1931. }
  1932. ao2_unlock(station);
  1933. }
  1934. if (res == AST_DEVICE_INVALID) {
  1935. ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n", trunk_name, station_name);
  1936. }
  1937. return res;
  1938. }
  1939. static int sla_trunk_release_refs(void *obj, void *arg, int flags)
  1940. {
  1941. struct sla_trunk *trunk = obj;
  1942. struct sla_station_ref *station_ref;
  1943. while ((station_ref = AST_LIST_REMOVE_HEAD(&trunk->stations, entry))) {
  1944. ao2_ref(station_ref, -1);
  1945. }
  1946. return 0;
  1947. }
  1948. static int sla_station_release_refs(void *obj, void *arg, int flags)
  1949. {
  1950. struct sla_station *station = obj;
  1951. struct sla_trunk_ref *trunk_ref;
  1952. while ((trunk_ref = AST_LIST_REMOVE_HEAD(&station->trunks, entry))) {
  1953. ao2_ref(trunk_ref, -1);
  1954. }
  1955. return 0;
  1956. }
  1957. static void sla_station_destructor(void *obj)
  1958. {
  1959. struct sla_station *station = obj;
  1960. ast_debug(1, "sla_station destructor for '%s'\n", station->name);
  1961. if (!ast_strlen_zero(station->autocontext)) {
  1962. struct sla_trunk_ref *trunk_ref;
  1963. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  1964. char exten[AST_MAX_EXTENSION];
  1965. char hint[AST_MAX_EXTENSION + 5];
  1966. snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
  1967. snprintf(hint, sizeof(hint), "SLA:%s", exten);
  1968. ast_context_remove_extension(station->autocontext, exten, 1, sla_registrar);
  1969. ast_context_remove_extension(station->autocontext, hint, PRIORITY_HINT, sla_registrar);
  1970. }
  1971. }
  1972. sla_station_release_refs(station, NULL, 0);
  1973. ast_string_field_free_memory(station);
  1974. }
  1975. static int sla_trunk_cmp(void *obj, void *arg, int flags)
  1976. {
  1977. struct sla_trunk *trunk = obj, *trunk2 = arg;
  1978. return !strcasecmp(trunk->name, trunk2->name) ? CMP_MATCH | CMP_STOP : 0;
  1979. }
  1980. static int sla_station_cmp(void *obj, void *arg, int flags)
  1981. {
  1982. struct sla_station *station = obj, *station2 = arg;
  1983. return !strcasecmp(station->name, station2->name) ? CMP_MATCH | CMP_STOP : 0;
  1984. }
  1985. static void sla_destroy(void)
  1986. {
  1987. if (sla.thread != AST_PTHREADT_NULL) {
  1988. ast_mutex_lock(&sla.lock);
  1989. sla.stop = 1;
  1990. ast_cond_signal(&sla.cond);
  1991. ast_mutex_unlock(&sla.lock);
  1992. pthread_join(sla.thread, NULL);
  1993. }
  1994. /* Drop any created contexts from the dialplan */
  1995. ast_context_destroy(NULL, sla_registrar);
  1996. ast_mutex_destroy(&sla.lock);
  1997. ast_cond_destroy(&sla.cond);
  1998. ao2_callback(sla_trunks, 0, sla_trunk_release_refs, NULL);
  1999. ao2_callback(sla_stations, 0, sla_station_release_refs, NULL);
  2000. ao2_ref(sla_trunks, -1);
  2001. sla_trunks = NULL;
  2002. ao2_ref(sla_stations, -1);
  2003. sla_stations = NULL;
  2004. }
  2005. static int sla_check_device(const char *device)
  2006. {
  2007. char *tech, *tech_data;
  2008. tech_data = ast_strdupa(device);
  2009. tech = strsep(&tech_data, "/");
  2010. if (ast_strlen_zero(tech) || ast_strlen_zero(tech_data)) {
  2011. return -1;
  2012. }
  2013. return 0;
  2014. }
  2015. static void sla_trunk_destructor(void *obj)
  2016. {
  2017. struct sla_trunk *trunk = obj;
  2018. ast_debug(1, "sla_trunk destructor for '%s'\n", trunk->name);
  2019. if (!ast_strlen_zero(trunk->autocontext)) {
  2020. ast_context_remove_extension(trunk->autocontext, "s", 1, sla_registrar);
  2021. }
  2022. sla_trunk_release_refs(trunk, NULL, 0);
  2023. ast_string_field_free_memory(trunk);
  2024. }
  2025. static int sla_build_trunk(struct ast_config *cfg, const char *cat)
  2026. {
  2027. RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
  2028. struct ast_variable *var;
  2029. const char *dev;
  2030. int existing_trunk = 0;
  2031. if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
  2032. ast_log(LOG_ERROR, "SLA Trunk '%s' defined with no device!\n", cat);
  2033. return -1;
  2034. }
  2035. if (sla_check_device(dev)) {
  2036. ast_log(LOG_ERROR, "SLA Trunk '%s' defined with invalid device '%s'!\n", cat, dev);
  2037. return -1;
  2038. }
  2039. if ((trunk = sla_find_trunk(cat))) {
  2040. trunk->mark = 0;
  2041. existing_trunk = 1;
  2042. } else if ((trunk = ao2_alloc(sizeof(*trunk), sla_trunk_destructor))) {
  2043. if (ast_string_field_init(trunk, 32)) {
  2044. return -1;
  2045. }
  2046. ast_string_field_set(trunk, name, cat);
  2047. } else {
  2048. return -1;
  2049. }
  2050. ao2_lock(trunk);
  2051. ast_string_field_set(trunk, device, dev);
  2052. for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
  2053. if (!strcasecmp(var->name, "autocontext")) {
  2054. ast_string_field_set(trunk, autocontext, var->value);
  2055. } else if (!strcasecmp(var->name, "ringtimeout")) {
  2056. if (sscanf(var->value, "%30u", &trunk->ring_timeout) != 1) {
  2057. ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for trunk '%s'\n", var->value, trunk->name);
  2058. trunk->ring_timeout = 0;
  2059. }
  2060. } else if (!strcasecmp(var->name, "barge")) {
  2061. trunk->barge_disabled = ast_false(var->value);
  2062. } else if (!strcasecmp(var->name, "hold")) {
  2063. if (!strcasecmp(var->value, "private")) {
  2064. trunk->hold_access = SLA_HOLD_PRIVATE;
  2065. } else if (!strcasecmp(var->value, "open")) {
  2066. trunk->hold_access = SLA_HOLD_OPEN;
  2067. } else {
  2068. ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n", var->value, trunk->name);
  2069. }
  2070. } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
  2071. ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", var->name, var->lineno, SLA_CONFIG_FILE);
  2072. }
  2073. }
  2074. ao2_unlock(trunk);
  2075. if (!ast_strlen_zero(trunk->autocontext)) {
  2076. if (!ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar)) {
  2077. ast_log(LOG_ERROR, "Failed to automatically find or create context '%s' for SLA!\n", trunk->autocontext);
  2078. return -1;
  2079. }
  2080. if (ast_add_extension(trunk->autocontext, 0 /* don't replace */, "s", 1,
  2081. NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free_ptr, sla_registrar)) {
  2082. ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", trunk->name);
  2083. return -1;
  2084. }
  2085. }
  2086. if (!existing_trunk) {
  2087. ao2_link(sla_trunks, trunk);
  2088. }
  2089. return 0;
  2090. }
  2091. /*!
  2092. * \internal
  2093. * \pre station is not locked
  2094. */
  2095. static void sla_add_trunk_to_station(struct sla_station *station, struct ast_variable *var)
  2096. {
  2097. RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
  2098. struct sla_trunk_ref *trunk_ref = NULL;
  2099. struct sla_station_ref *station_ref;
  2100. char *trunk_name, *options, *cur;
  2101. int existing_trunk_ref = 0;
  2102. int existing_station_ref = 0;
  2103. options = ast_strdupa(var->value);
  2104. trunk_name = strsep(&options, ",");
  2105. trunk = sla_find_trunk(trunk_name);
  2106. if (!trunk) {
  2107. ast_log(LOG_ERROR, "Trunk '%s' not found!\n", var->value);
  2108. return;
  2109. }
  2110. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  2111. if (trunk_ref->trunk == trunk) {
  2112. trunk_ref->mark = 0;
  2113. existing_trunk_ref = 1;
  2114. break;
  2115. }
  2116. }
  2117. if (!trunk_ref && !(trunk_ref = create_trunk_ref(trunk))) {
  2118. return;
  2119. }
  2120. trunk_ref->state = SLA_TRUNK_STATE_IDLE;
  2121. while ((cur = strsep(&options, ","))) {
  2122. char *name, *value = cur;
  2123. name = strsep(&value, "=");
  2124. if (!strcasecmp(name, "ringtimeout")) {
  2125. if (sscanf(value, "%30u", &trunk_ref->ring_timeout) != 1) {
  2126. ast_log(LOG_WARNING, "Invalid ringtimeout value '%s' for trunk '%s' on station '%s'\n", value, trunk->name, station->name);
  2127. trunk_ref->ring_timeout = 0;
  2128. }
  2129. } else if (!strcasecmp(name, "ringdelay")) {
  2130. if (sscanf(value, "%30u", &trunk_ref->ring_delay) != 1) {
  2131. ast_log(LOG_WARNING, "Invalid ringdelay value '%s' for trunk '%s' on station '%s'\n", value, trunk->name, station->name);
  2132. trunk_ref->ring_delay = 0;
  2133. }
  2134. } else {
  2135. ast_log(LOG_WARNING, "Invalid option '%s' for trunk '%s' on station '%s'\n", name, trunk->name, station->name);
  2136. }
  2137. }
  2138. AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
  2139. if (station_ref->station == station) {
  2140. station_ref->mark = 0;
  2141. existing_station_ref = 1;
  2142. break;
  2143. }
  2144. }
  2145. if (!station_ref && !(station_ref = sla_create_station_ref(station))) {
  2146. if (!existing_trunk_ref) {
  2147. ao2_ref(trunk_ref, -1);
  2148. } else {
  2149. trunk_ref->mark = 1;
  2150. }
  2151. return;
  2152. }
  2153. if (!existing_station_ref) {
  2154. ao2_lock(trunk);
  2155. AST_LIST_INSERT_TAIL(&trunk->stations, station_ref, entry);
  2156. ast_atomic_fetchadd_int((int *) &trunk->num_stations, 1);
  2157. ao2_unlock(trunk);
  2158. }
  2159. if (!existing_trunk_ref) {
  2160. ao2_lock(station);
  2161. AST_LIST_INSERT_TAIL(&station->trunks, trunk_ref, entry);
  2162. ao2_unlock(station);
  2163. }
  2164. }
  2165. static int sla_build_station(struct ast_config *cfg, const char *cat)
  2166. {
  2167. RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
  2168. struct ast_variable *var;
  2169. const char *dev;
  2170. int existing_station = 0;
  2171. if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
  2172. ast_log(LOG_ERROR, "SLA Station '%s' defined with no device!\n", cat);
  2173. return -1;
  2174. }
  2175. if ((station = sla_find_station(cat))) {
  2176. station->mark = 0;
  2177. existing_station = 1;
  2178. } else if ((station = ao2_alloc(sizeof(*station), sla_station_destructor))) {
  2179. if (ast_string_field_init(station, 32)) {
  2180. return -1;
  2181. }
  2182. ast_string_field_set(station, name, cat);
  2183. } else {
  2184. return -1;
  2185. }
  2186. ao2_lock(station);
  2187. ast_string_field_set(station, device, dev);
  2188. for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
  2189. if (!strcasecmp(var->name, "trunk")) {
  2190. ao2_unlock(station);
  2191. sla_add_trunk_to_station(station, var);
  2192. ao2_lock(station);
  2193. } else if (!strcasecmp(var->name, "autocontext")) {
  2194. ast_string_field_set(station, autocontext, var->value);
  2195. } else if (!strcasecmp(var->name, "ringtimeout")) {
  2196. if (sscanf(var->value, "%30u", &station->ring_timeout) != 1) {
  2197. ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for station '%s'\n", var->value, station->name);
  2198. station->ring_timeout = 0;
  2199. }
  2200. } else if (!strcasecmp(var->name, "ringdelay")) {
  2201. if (sscanf(var->value, "%30u", &station->ring_delay) != 1) {
  2202. ast_log(LOG_WARNING, "Invalid ringdelay '%s' specified for station '%s'\n", var->value, station->name);
  2203. station->ring_delay = 0;
  2204. }
  2205. } else if (!strcasecmp(var->name, "hold")) {
  2206. if (!strcasecmp(var->value, "private")) {
  2207. station->hold_access = SLA_HOLD_PRIVATE;
  2208. } else if (!strcasecmp(var->value, "open")) {
  2209. station->hold_access = SLA_HOLD_OPEN;
  2210. } else {
  2211. ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n", var->value, station->name);
  2212. }
  2213. } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
  2214. ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", var->name, var->lineno, SLA_CONFIG_FILE);
  2215. }
  2216. }
  2217. ao2_unlock(station);
  2218. if (!ast_strlen_zero(station->autocontext)) {
  2219. struct sla_trunk_ref *trunk_ref;
  2220. if (!ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar)) {
  2221. ast_log(LOG_ERROR, "Failed to automatically find or create context '%s' for SLA!\n", station->autocontext);
  2222. return -1;
  2223. }
  2224. /* The extension for when the handset goes off-hook.
  2225. * exten => station1,1,SLAStation(station1) */
  2226. if (ast_add_extension(station->autocontext, 0 /* don't replace */, station->name, 1,
  2227. NULL, NULL, slastation_app, ast_strdup(station->name), ast_free_ptr, sla_registrar)) {
  2228. ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", station->name);
  2229. return -1;
  2230. }
  2231. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  2232. char exten[AST_MAX_EXTENSION];
  2233. char hint[AST_MAX_EXTENSION + 5];
  2234. snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
  2235. snprintf(hint, sizeof(hint), "SLA:%s", exten);
  2236. /* Extension for this line button
  2237. * exten => station1_line1,1,SLAStation(station1_line1) */
  2238. if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, 1,
  2239. NULL, NULL, slastation_app, ast_strdup(exten), ast_free_ptr, sla_registrar)) {
  2240. ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", station->name);
  2241. return -1;
  2242. }
  2243. /* Hint for this line button
  2244. * exten => station1_line1,hint,SLA:station1_line1 */
  2245. if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, PRIORITY_HINT,
  2246. NULL, NULL, hint, NULL, NULL, sla_registrar)) {
  2247. ast_log(LOG_ERROR, "Failed to automatically create hint for trunk '%s'!\n", station->name);
  2248. return -1;
  2249. }
  2250. }
  2251. }
  2252. if (!existing_station) {
  2253. ao2_link(sla_stations, station);
  2254. }
  2255. return 0;
  2256. }
  2257. static int sla_trunk_mark(void *obj, void *arg, int flags)
  2258. {
  2259. struct sla_trunk *trunk = obj;
  2260. struct sla_station_ref *station_ref;
  2261. ao2_lock(trunk);
  2262. trunk->mark = 1;
  2263. AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
  2264. station_ref->mark = 1;
  2265. }
  2266. ao2_unlock(trunk);
  2267. return 0;
  2268. }
  2269. static int sla_station_mark(void *obj, void *arg, int flags)
  2270. {
  2271. struct sla_station *station = obj;
  2272. struct sla_trunk_ref *trunk_ref;
  2273. ao2_lock(station);
  2274. station->mark = 1;
  2275. AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
  2276. trunk_ref->mark = 1;
  2277. }
  2278. ao2_unlock(station);
  2279. return 0;
  2280. }
  2281. static int sla_trunk_is_marked(void *obj, void *arg, int flags)
  2282. {
  2283. struct sla_trunk *trunk = obj;
  2284. ao2_lock(trunk);
  2285. if (trunk->mark) {
  2286. /* Only remove all of the station references if the trunk itself is going away */
  2287. sla_trunk_release_refs(trunk, NULL, 0);
  2288. } else {
  2289. struct sla_station_ref *station_ref;
  2290. /* Otherwise only remove references to stations no longer in the config */
  2291. AST_LIST_TRAVERSE_SAFE_BEGIN(&trunk->stations, station_ref, entry) {
  2292. if (!station_ref->mark) {
  2293. continue;
  2294. }
  2295. AST_LIST_REMOVE_CURRENT(entry);
  2296. ao2_ref(station_ref, -1);
  2297. }
  2298. AST_LIST_TRAVERSE_SAFE_END
  2299. }
  2300. ao2_unlock(trunk);
  2301. return trunk->mark ? CMP_MATCH : 0;
  2302. }
  2303. static int sla_station_is_marked(void *obj, void *arg, int flags)
  2304. {
  2305. struct sla_station *station = obj;
  2306. ao2_lock(station);
  2307. if (station->mark) {
  2308. /* Only remove all of the trunk references if the station itself is going away */
  2309. sla_station_release_refs(station, NULL, 0);
  2310. } else {
  2311. struct sla_trunk_ref *trunk_ref;
  2312. /* Otherwise only remove references to trunks no longer in the config */
  2313. AST_LIST_TRAVERSE_SAFE_BEGIN(&station->trunks, trunk_ref, entry) {
  2314. if (!trunk_ref->mark) {
  2315. continue;
  2316. }
  2317. AST_LIST_REMOVE_CURRENT(entry);
  2318. ao2_ref(trunk_ref, -1);
  2319. }
  2320. AST_LIST_TRAVERSE_SAFE_END
  2321. }
  2322. ao2_unlock(station);
  2323. return station->mark ? CMP_MATCH : 0;
  2324. }
  2325. static int sla_in_use(void)
  2326. {
  2327. return ao2_container_count(sla_trunks) || ao2_container_count(sla_stations);
  2328. }
  2329. static int sla_load_config(int reload)
  2330. {
  2331. struct ast_config *cfg;
  2332. struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
  2333. const char *cat = NULL;
  2334. int res = 0;
  2335. const char *val;
  2336. if (!reload) {
  2337. ast_mutex_init(&sla.lock);
  2338. ast_cond_init(&sla.cond, NULL);
  2339. sla_trunks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, sla_trunk_cmp);
  2340. sla_stations = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, sla_station_cmp);
  2341. }
  2342. if (!(cfg = ast_config_load(SLA_CONFIG_FILE, config_flags))) {
  2343. return 0; /* Treat no config as normal */
  2344. } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
  2345. return 0;
  2346. } else if (cfg == CONFIG_STATUS_FILEINVALID) {
  2347. ast_log(LOG_ERROR, "Config file " SLA_CONFIG_FILE " is in an invalid format. Aborting.\n");
  2348. return 0;
  2349. }
  2350. if (reload) {
  2351. ao2_callback(sla_trunks, 0, sla_trunk_mark, NULL);
  2352. ao2_callback(sla_stations, 0, sla_station_mark, NULL);
  2353. }
  2354. if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid"))) {
  2355. sla.attempt_callerid = ast_true(val);
  2356. }
  2357. while ((cat = ast_category_browse(cfg, cat)) && !res) {
  2358. const char *type;
  2359. if (!strcasecmp(cat, "general")) {
  2360. continue;
  2361. }
  2362. if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
  2363. ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n", SLA_CONFIG_FILE);
  2364. continue;
  2365. }
  2366. if (!strcasecmp(type, "trunk")) {
  2367. res = sla_build_trunk(cfg, cat);
  2368. } else if (!strcasecmp(type, "station")) {
  2369. res = sla_build_station(cfg, cat);
  2370. } else {
  2371. ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'!\n", SLA_CONFIG_FILE, type);
  2372. }
  2373. }
  2374. ast_config_destroy(cfg);
  2375. if (reload) {
  2376. ao2_callback(sla_trunks, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, sla_trunk_is_marked, NULL);
  2377. ao2_callback(sla_stations, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, sla_station_is_marked, NULL);
  2378. }
  2379. /* Start SLA event processing thread once SLA has been configured. */
  2380. if (sla.thread == AST_PTHREADT_NULL && sla_in_use()) {
  2381. ast_pthread_create(&sla.thread, NULL, sla_thread, NULL);
  2382. }
  2383. return res;
  2384. }
  2385. static int load_config(int reload)
  2386. {
  2387. return sla_load_config(reload);
  2388. }
  2389. static int unload_module(void)
  2390. {
  2391. int res = 0;
  2392. ast_cli_unregister_multiple(cli_sla, ARRAY_LEN(cli_sla));
  2393. res |= ast_unregister_application(slastation_app);
  2394. res |= ast_unregister_application(slatrunk_app);
  2395. ast_devstate_prov_del("SLA");
  2396. sla_destroy();
  2397. return res;
  2398. }
  2399. /*!
  2400. * \brief Load the module
  2401. *
  2402. * Module loading including tests for configuration or dependencies.
  2403. * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  2404. * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
  2405. * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
  2406. * configuration file or other non-critical problem return
  2407. * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  2408. */
  2409. static int load_module(void)
  2410. {
  2411. int res = 0;
  2412. res |= load_config(0);
  2413. ast_cli_register_multiple(cli_sla, ARRAY_LEN(cli_sla));
  2414. res |= ast_register_application_xml(slastation_app, sla_station_exec);
  2415. res |= ast_register_application_xml(slatrunk_app, sla_trunk_exec);
  2416. res |= ast_devstate_prov_add("SLA", sla_state);
  2417. return res;
  2418. }
  2419. static int reload(void)
  2420. {
  2421. return load_config(1);
  2422. }
  2423. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Shared Line Appearances",
  2424. .support_level = AST_MODULE_SUPPORT_EXTENDED,
  2425. .load = load_module,
  2426. .unload = unload_module,
  2427. .reload = reload,
  2428. .load_pri = AST_MODPRI_DEVSTATE_PROVIDER,
  2429. );