1 /*
2 * Copyright (c) 2010, Sangoma Technologies
3 * David Yat Sin <davidy@sangoma.com>
4 * Moises Silva <moy@sangoma.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of the original author; nor the names of any contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #include "ftmod_sangoma_isdn.h"
37
38 void stack_resp_hdr_init(Header *hdr);
39
40 ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span);
41 ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span);
42
43 ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span);
44
45 ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
46 ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
47
48
49 extern ftdm_sngisdn_data_t g_sngisdn_data;
50
51 ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
52
53
sngisdn_stack_start(ftdm_span_t * span)54 ftdm_status_t sngisdn_stack_start(ftdm_span_t *span)
55 {
56 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
57
58 if (signal_data->dchan) {
59 if (sngisdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) {
60 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name);
61 return FTDM_FAIL;
62 }
63 ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name);
64 }
65
66 /* Try to find an alternative for this */
67 /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1,
68 so we need to give some time before activating q931, as q931 will send a
69 LdUiDatConReq when activated, and this requires the Mac SAP to be already
70 bound first */
71 ftdm_sleep(500);
72
73 if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) {
74 g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1;
75 if (sngisdn_activate_cc(span) != FTDM_SUCCESS) {
76 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack CC\n", span->name);
77 return FTDM_FAIL;
78 }
79 ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name);
80 }
81
82 if (sngisdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) {
83 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name);
84 return FTDM_FAIL;
85 }
86 ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q931 activated\n", span->name);
87
88 ftdm_log(FTDM_LOG_INFO, "%s:Stack activated\n",span->name);
89 return FTDM_SUCCESS;
90 }
91
sngisdn_stack_stop(ftdm_span_t * span)92 ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span)
93 {
94 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
95 /* Stop L1 first, so we do not receive any more frames */
96 if (!signal_data->dchan) {
97 return FTDM_SUCCESS;
98 }
99 if (sngisdn_deactivate_phy(span) != FTDM_SUCCESS) {
100 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name);
101 return FTDM_FAIL;
102 }
103
104 if (sngisdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
105 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name);
106 return FTDM_FAIL;
107 }
108
109 if (sngisdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) {
110 ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name);
111 return FTDM_FAIL;
112 }
113
114 ftdm_log(FTDM_LOG_INFO, "%s:Signalling stopped\n", span->name);
115 return FTDM_SUCCESS;
116 }
117
118
sngisdn_activate_phy(ftdm_span_t * span)119 ftdm_status_t sngisdn_activate_phy(ftdm_span_t *span)
120 {
121
122 /* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */
123
124 return FTDM_SUCCESS;
125 }
126
sngisdn_deactivate_phy(ftdm_span_t * span)127 ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span)
128 {
129 L1Mngmt cntrl;
130 Pst pst;
131
132 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
133
134 /* initalize the post structure */
135 stack_pst_init(&pst);
136
137 /* insert the destination Entity */
138 pst.dstEnt = ENTL1;
139
140 /* initalize the control structure */
141 memset(&cntrl, 0, sizeof(cntrl));
142
143 /* initalize the control header */
144 stack_hdr_init(&cntrl.hdr);
145
146 cntrl.hdr.msgType = TCNTRL; /* configuration */
147 cntrl.hdr.entId.ent = ENTL1; /* entity */
148 cntrl.hdr.entId.inst = S_INST; /* instance */
149 cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
150
151 cntrl.t.cntrl.action = AUBND_DIS;
152 cntrl.t.cntrl.subAction = SAELMNT;
153
154 cntrl.t.cntrl.sapId = signal_data->link_id;
155
156 if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
157 return FTDM_FAIL;
158 }
159 return FTDM_SUCCESS;
160 }
161
sngisdn_wake_up_phy(ftdm_span_t * span)162 ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span)
163 {
164 L1Mngmt cntrl;
165 Pst pst;
166
167 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
168
169 /* initalize the post structure */
170 stack_pst_init(&pst);
171
172 /* insert the destination Entity */
173 pst.dstEnt = ENTL1;
174
175 /* initalize the control structure */
176 memset(&cntrl, 0, sizeof(cntrl));
177
178 /* initalize the control header */
179 stack_hdr_init(&cntrl.hdr);
180
181 cntrl.hdr.msgType = TCNTRL; /* configuration */
182 cntrl.hdr.entId.ent = ENTL1; /* entity */
183 cntrl.hdr.entId.inst = S_INST; /* instance */
184 cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
185
186 cntrl.t.cntrl.action = AENA;
187 cntrl.t.cntrl.subAction = SAELMNT;
188
189 cntrl.t.cntrl.sapId = signal_data->link_id;
190
191 if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
192 return FTDM_FAIL;
193 }
194 return FTDM_SUCCESS;
195 }
196
sngisdn_activate_cc(ftdm_span_t * span)197 ftdm_status_t sngisdn_activate_cc(ftdm_span_t *span)
198 {
199 CcMngmt cntrl;
200 Pst pst;
201
202 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
203
204 /* initalize the post structure */
205 stack_pst_init(&pst);
206
207 /* insert the destination Entity */
208 pst.dstEnt = ENTCC;
209
210 /* initalize the control structure */
211 memset(&cntrl, 0, sizeof(cntrl));
212
213 /* initalize the control header */
214 stack_hdr_init(&cntrl.hdr);
215
216 cntrl.hdr.msgType = TCNTRL; /* configuration */
217 cntrl.hdr.entId.ent = ENTCC; /* entity */
218 cntrl.hdr.entId.inst = S_INST; /* instance */
219 cntrl.hdr.elmId.elmnt = STTSAP; /* physical sap */
220
221 cntrl.t.cntrl.action = ABND_ENA;
222 cntrl.t.cntrl.subAction = SAELMNT;
223
224 cntrl.t.cntrl.sapId = signal_data->cc_id;
225 if (sng_isdn_cc_cntrl(&pst, &cntrl)) {
226 return FTDM_FAIL;
227 }
228 return FTDM_SUCCESS;
229 }
230
sngisdn_activate_trace(ftdm_span_t * span,sngisdn_tracetype_t trace_opt)231 ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt)
232 {
233 sngisdn_span_data_t *signal_data = sngisdn_dchan((sngisdn_span_data_t*)span->signal_data);
234
235 if (!signal_data) {
236 ftdm_log(FTDM_LOG_ERROR, "%s:Span is not used by signalling module\n", span->name);
237 return FTDM_FAIL;
238 }
239
240 switch (trace_opt) {
241 case SNGISDN_TRACE_DISABLE:
242 if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) {
243 ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name);
244 sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921);
245
246 if (sngisdn_cntrl_q921(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) {
247 ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name);
248 }
249 }
250 if (sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q931)) {
251 ftdm_log(FTDM_LOG_INFO, "%s:Disabling q921 trace\n", signal_data->ftdm_span->name);
252 sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q931);
253
254 if (sngisdn_cntrl_q931(signal_data->ftdm_span, ADISIMM, SATRC) != FTDM_SUCCESS) {
255 ftdm_log(FTDM_LOG_INFO, "%s:Failed to disable q921 trace\n", signal_data->ftdm_span->name);
256 }
257 }
258 break;
259 case SNGISDN_TRACE_Q921:
260 if (!sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q921)) {
261 ftdm_log(FTDM_LOG_INFO, "%s:Enabling q921 trace\n", signal_data->ftdm_span->name);
262 sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q921);
263
264 if (sngisdn_cntrl_q921(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) {
265 ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q921 trace\n", signal_data->ftdm_span->name);
266 }
267 }
268 break;
269 case SNGISDN_TRACE_Q931:
270 if (!sngisdn_test_trace_flag(signal_data, SNGISDN_TRACE_Q931)) {
271 ftdm_log(FTDM_LOG_INFO, "s%d Enabling q931 trace\n", signal_data->link_id);
272 sngisdn_set_trace_flag(signal_data, SNGISDN_TRACE_Q931);
273
274 if (sngisdn_cntrl_q931(signal_data->ftdm_span, AENA, SATRC) != FTDM_SUCCESS) {
275 ftdm_log(FTDM_LOG_INFO, "%s:Failed to enable q931 trace\n", signal_data->ftdm_span->name);
276 }
277 }
278 break;
279 }
280 return FTDM_SUCCESS;
281 }
282
283
sngisdn_cntrl_q931(ftdm_span_t * span,uint8_t action,uint8_t subaction)284 ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
285 {
286 InMngmt cntrl;
287 Pst pst;
288 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
289
290 /* initalize the post structure */
291 stack_pst_init(&pst);
292
293 /* insert the destination Entity */
294 pst.dstEnt = ENTIN;
295
296 /* initalize the control structure */
297 memset(&cntrl, 0, sizeof(cntrl));
298
299 /* initalize the control header */
300 stack_hdr_init(&cntrl.hdr);
301
302 cntrl.hdr.msgType = TCNTRL; /* configuration */
303 cntrl.hdr.entId.ent = ENTIN; /* entity */
304 cntrl.hdr.entId.inst = S_INST; /* instance */
305 cntrl.hdr.elmId.elmnt = STDLSAP; /* physical sap */
306
307 cntrl.t.cntrl.action = action;
308 cntrl.t.cntrl.subAction = subaction;
309
310 if (action == AENA && subaction == SATRC) {
311 cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */
312 }
313
314 cntrl.t.cntrl.sapId = signal_data->link_id;
315 cntrl.t.cntrl.ces = 0;
316
317 if(sng_isdn_q931_cntrl(&pst, &cntrl)) {
318 return FTDM_FAIL;
319 }
320 return FTDM_SUCCESS;
321
322 }
323
sngisdn_cntrl_q921(ftdm_span_t * span,uint8_t action,uint8_t subaction)324 ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction)
325 {
326 BdMngmt cntrl;
327 Pst pst;
328 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
329
330 /* initalize the post structure */
331 stack_pst_init(&pst);
332
333 /* insert the destination Entity */
334 pst.dstEnt = ENTLD;
335
336 /* initalize the control structure */
337 memset(&cntrl, 0, sizeof(cntrl));
338
339 /* initalize the control header */
340 stack_hdr_init(&cntrl.hdr);
341 /* build control request */
342 cntrl.hdr.msgType = TCNTRL;
343 cntrl.hdr.entId.ent = ENTLD;
344 cntrl.hdr.entId.inst = S_INST;
345
346 #if (SMBD_LMINT3 || BD_LMINT3)
347 stack_resp_hdr_init(&cntrl.hdr);
348 #endif /* _LMINT3 */
349
350 cntrl.hdr.elmId.elmnt = STMSAP;
351 cntrl.t.cntrl.action = action;
352 cntrl.t.cntrl.subAction = subaction;
353
354 #if (SMBD_LMINT3 || BD_LMINT3)
355 cntrl.t.cntrl.lnkNmb = signal_data->link_id;
356 cntrl.t.cntrl.sapi = NOTUSED;
357 cntrl.t.cntrl.tei = NOTUSED;
358 #else /* _LMINT3 */
359 cntrl.hdr.elmId.elmntInst1 = signal_data->link_id;
360 cntrl.hdr.elmId.elmntInst2 = NOTUSED;
361 cntrl.hdr.elmId.elmntInst3 = NOTUSED;
362 #endif /* _LMINT3 */
363
364 cntrl.t.cntrl.logInt = NOTUSED;
365 cntrl.t.cntrl.trcLen = NOTUSED;
366 if (action == AENA && subaction == SATRC) {
367 cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */
368 }
369
370 SGetDateTime(&(cntrl.t.cntrl.dt));
371 if(sng_isdn_q921_cntrl(&pst, &cntrl)) {
372 return FTDM_FAIL;
373 }
374
375 return FTDM_SUCCESS;
376 }
377
378
stack_resp_hdr_init(Header * hdr)379 void stack_resp_hdr_init(Header *hdr)
380 {
381 hdr->response.selector = 0;
382 hdr->response.mem.region = RTESPEC;
383 hdr->response.mem.pool = S_POOL;
384 hdr->response.prior = PRIOR0;
385 hdr->response.route = RTESPEC;
386
387 return;
388 }
389
390
391
392 /* For Emacs:
393 * Local Variables:
394 * mode:c
395 * indent-tabs-mode:t
396 * tab-width:4
397 * c-basic-offset:4
398 * End:
399 * For VIM:
400 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
401 */
402
403 /******************************************************************************/
404