This source file includes following definitions.
- sngisdn_process_con_ind
- sngisdn_process_con_cfm
- sngisdn_process_cnst_ind
- sngisdn_process_disc_ind
- sngisdn_process_rel_ind
- sngisdn_process_dat_ind
- sngisdn_process_sshl_ind
- sngisdn_process_sshl_cfm
- sngisdn_process_rmrt_ind
- sngisdn_process_rmrt_cfm
- sngisdn_process_flc_ind
- sngisdn_process_fac_ind
- sngisdn_process_sta_cfm
- sngisdn_process_srv_ind
- sngisdn_process_srv_cfm
- sngisdn_process_restart_confirm
- sngisdn_process_rst_cfm
- sngisdn_process_rst_ind
- sngisdn_cause_val_requires_disconnect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include "ftmod_sangoma_isdn.h"
36 static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
37 static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
38
39
40 void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
41 {
42 unsigned i;
43 int16_t suId = sngisdn_event->suId;
44 uint32_t suInstId = sngisdn_event->suInstId;
45 uint32_t spInstId = sngisdn_event->spInstId;
46 int16_t dChan = sngisdn_event->dChan;
47 uint8_t ces = sngisdn_event->ces;
48 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
49 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
50 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
51 ConEvnt *conEvnt = &sngisdn_event->event.conEvnt;
52
53 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
54
55 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
56
57 ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
58
59 switch (ftdmchan->state) {
60 case FTDM_CHANNEL_STATE_DOWN:
61 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ||
62 ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
63
64 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel is in USE, saving call for later processing\n");
65
66 sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
67
68
69 memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
70 sngisdn_info->glare.suId = suId;
71 sngisdn_info->glare.suInstId = suInstId;
72 sngisdn_info->glare.spInstId = spInstId;
73 sngisdn_info->glare.dChan = dChan;
74 sngisdn_info->glare.ces = ces;
75 break;
76 }
77
78 sngisdn_info->suInstId = get_unique_suInstId(suId);
79 sngisdn_info->spInstId = spInstId;
80
81 if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
82 uint8_t local_number_matched = 0;
83 for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
84 if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) {
85 local_number_matched++;
86 break;
87 }
88 }
89 if (!local_number_matched) {
90 ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val);
91
92 ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST;
93 ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
94 return;
95 }
96 }
97
98
99
100 if (sngisdn_info->glare.spInstId == spInstId) {
101 clear_call_glare_data(sngisdn_info);
102 }
103
104
105 if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
106 if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
107 sngisdn_info->ces = ces;
108 }
109 }
110
111 ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
112 g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
113 ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
114
115 ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
116
117
118 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
119 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel");
120 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL);
121 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
122 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
123 break;
124 }
125
126
127 #ifdef NETBORDER_CALL_REF
128 get_callref(ftdmchan, &conEvnt->callRef);
129 #endif
130 get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
131 get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2);
132 get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
133 get_redir_num(ftdmchan, &conEvnt->redirNmb);
134 get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
135 get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
136 get_facility_ie(ftdmchan, &conEvnt->facilityStr);
137
138 if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
139 get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
140 }
141
142 ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
143
144 if (conEvnt->bearCap[0].eh.pres) {
145 ftdmchan->caller_data.bearer_layer1 = sngisdn_get_usrInfoLyr1Prot_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
146 ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
147 }
148
149 if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
150 if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
151 uint8_t encoding = (conEvnt->ni2OctStr.str.val[2] >> 5);
152 if (encoding == 0 || encoding == 1) {
153
154 uint8_t value = (conEvnt->ni2OctStr.str.val[3] & 0x0F)*10 + ((conEvnt->ni2OctStr.str.val[3] >> 4) & 0x0F);
155 snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", value);
156 } else if (encoding == 2) {
157
158 snprintf(ftdmchan->caller_data.aniII, 5, "%c", conEvnt->ni2OctStr.str.val[3]);
159 }
160 }
161 }
162
163
164 if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
165
166 uint16_t ret_val;
167 char retrieved_str[255];
168
169 ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
170
171
172
173
174
175
176
177 if (ret_val == 1) {
178 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
179 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
180
181 if (signal_data->facility_timeout) {
182 ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
183 sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
184 }
185 break;
186 } else if (ret_val == 0) {
187 strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
188 }
189 }
190
191 if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) {
192 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
193 } else {
194 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
195 }
196 break;
197 case FTDM_CHANNEL_STATE_TERMINATING:
198 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in TERMINATING state, saving SETUP info for later processing\n");
199 ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare\n");
200
201 sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
202
203
204 memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
205 sngisdn_info->glare.suId = suId;
206 sngisdn_info->glare.suInstId = suInstId;
207 sngisdn_info->glare.spInstId = spInstId;
208 sngisdn_info->glare.dChan = dChan;
209 sngisdn_info->glare.ces = ces;
210
211 break;
212 case FTDM_CHANNEL_STATE_DIALING:
213 if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
214
215 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP in DIALING state, rejecting inbound call\n");
216 sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL);
217
218 sngisdn_info->glare.suId = suId;
219 sngisdn_info->glare.suInstId = get_unique_suInstId(suId);
220 sngisdn_info->glare.spInstId = spInstId;
221
222 sngisdn_info->glare.dChan = dChan;
223 sngisdn_info->glare.ces = ces;
224 ftdmchan->caller_data.hangup_cause = 0x2C;
225 ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL);
226 } else {
227 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in DIALING state, saving SETUP info for later processing\n");
228
229
230 ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare");
231 sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
232
233
234 memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
235 sngisdn_info->glare.suId = suId;
236 sngisdn_info->glare.suInstId = suInstId;
237 sngisdn_info->glare.spInstId = spInstId;
238 sngisdn_info->glare.dChan = dChan;
239 sngisdn_info->glare.ces = ces;
240
241 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
242 }
243 break;
244 case FTDM_CHANNEL_STATE_RESET:
245 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
246 break;
247 default:
248 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
249 break;
250 }
251 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
252 return;
253 }
254
255
256 void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
257 {
258 int16_t suId = sngisdn_event->suId;
259 uint32_t suInstId = sngisdn_event->suInstId;
260 uint32_t spInstId = sngisdn_event->spInstId;
261 uint8_t ces = sngisdn_event->ces;
262 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
263 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
264 CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
265
266 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
267
268 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
269
270 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces);
271
272 if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
273 ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) {
274
275 if(sngisdn_info->ces == CES_MNGMNT) {
276
277 sngisdn_info->ces = ces;
278 } else {
279
280 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call already assigned, ignoring connect\n");
281 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
282 return;
283 }
284 }
285
286 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
287 switch(ftdmchan->state) {
288 case FTDM_CHANNEL_STATE_PROCEED:
289 case FTDM_CHANNEL_STATE_RINGING:
290 case FTDM_CHANNEL_STATE_PROGRESS:
291 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
292 case FTDM_CHANNEL_STATE_DIALING:
293 #ifdef NETBORDER_CALL_REF
294 get_callref(ftdmchan, &cnStEvnt->callRef);
295 #endif
296 get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
297 get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
298 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
299 break;
300 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
301 case FTDM_CHANNEL_STATE_HANGUP:
302
303 break;
304 case FTDM_CHANNEL_STATE_RESET:
305 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
306 break;
307 default:
308 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
309
310
311 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
312 break;
313 }
314 } else {
315 switch(ftdmchan->state) {
316 case FTDM_CHANNEL_STATE_UP:
317
318
319 break;
320 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
321
322 break;
323 case FTDM_CHANNEL_STATE_RESET:
324 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
325 break;
326 default:
327 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
328
329
330 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
331 break;
332 }
333 }
334
335 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
336 return;
337 }
338
339 void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
340 {
341 int16_t suId = sngisdn_event->suId;
342 uint32_t suInstId = sngisdn_event->suInstId;
343 uint32_t spInstId = sngisdn_event->spInstId;
344 uint8_t ces = sngisdn_event->ces;
345 uint8_t evntType = sngisdn_event->evntType;
346
347 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
348 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
349
350 CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
351
352 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
353
354 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
355
356 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n",
357 (evntType == MI_ALERTING)?"ALERT":
358 (evntType == MI_CALLPROC)?"PROCEED":
359 (evntType == MI_PROGRESS)?"PROGRESS":
360 (evntType == MI_SETUPACK)?"SETUP ACK":
361 (evntType == MI_INFO)?"INFO":"UNKNOWN",
362 suId, suInstId, spInstId, ces);
363
364 switch(evntType) {
365 case MI_CALLPROC:
366 case MI_PROGRESS:
367 case MI_ALERTING:
368 #ifdef NETBORDER_CALL_REF
369 get_callref(ftdmchan, &cnStEvnt->callRef);
370 #endif
371 get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
372 get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
373
374 if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) {
375 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
376 ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
377
378 sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
379 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
380 goto sngisdn_process_cnst_ind_end;
381 }
382
383 switch(ftdmchan->state) {
384 case FTDM_CHANNEL_STATE_DIALING:
385 case FTDM_CHANNEL_STATE_PROCEED:
386 case FTDM_CHANNEL_STATE_PROGRESS:
387 case FTDM_CHANNEL_STATE_RINGING:
388 if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
389 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
390 sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
391 } else {
392 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media not available\n");
393 }
394 switch (evntType) {
395 case MI_CALLPROC:
396 if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
397 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
398 }
399 break;
400 case MI_ALERTING:
401 if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
402 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
403 }
404 break;
405 case MI_PROGRESS:
406 if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
407 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
408 } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
409 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
410 }
411 break;
412 default:
413
414 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
415 }
416 break;
417 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
418
419
420 break;
421 case FTDM_CHANNEL_STATE_RESET:
422 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
423 break;
424 default:
425 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
426
427
428 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
429 break;
430 }
431 break;
432 case MI_SETUPACK:
433 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP_ACK, but overlap sending not implemented (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
434 break;
435 case MI_INFO:
436 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
437
438 if (cnStEvnt->cdPtyNmb.eh.pres) {
439 switch(ftdmchan->state) {
440 case FTDM_CHANNEL_STATE_COLLECT:
441 {
442 ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
443 ftdm_size_t num_digits;
444
445 get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb);
446 num_digits = strlen(ftdmchan->caller_data.dnis.digits);
447
448 if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
449 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
450 } else {
451 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %d of %d digits\n", num_digits, min_digits);
452 }
453 }
454 break;
455 case FTDM_CHANNEL_STATE_RING:
456 case FTDM_CHANNEL_STATE_RINGING:
457 case FTDM_CHANNEL_STATE_PROCEED:
458 case FTDM_CHANNEL_STATE_PROGRESS:
459 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
460 case FTDM_CHANNEL_STATE_UP:
461 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
462 break;
463 case FTDM_CHANNEL_STATE_RESET:
464 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
465 break;
466 default:
467 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
468 break;
469 }
470 }
471
472 break;
473 default:
474 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unhandled STATUS event\n");
475 break;
476 }
477
478 sngisdn_process_cnst_ind_end:
479 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
480 return;
481 }
482
483 void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
484 {
485 int16_t suId = sngisdn_event->suId;
486 uint32_t suInstId = sngisdn_event->suInstId;
487 uint32_t spInstId = sngisdn_event->spInstId;
488 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
489 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
490
491 DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
492
493 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
494
495 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
496
497 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
498 switch (ftdmchan->state) {
499 case FTDM_CHANNEL_STATE_RING:
500 case FTDM_CHANNEL_STATE_RINGING:
501 case FTDM_CHANNEL_STATE_DIALING:
502 case FTDM_CHANNEL_STATE_PROCEED:
503 case FTDM_CHANNEL_STATE_PROGRESS:
504 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
505 case FTDM_CHANNEL_STATE_UP:
506 get_facility_ie(ftdmchan, &discEvnt->facilityStr);
507
508 if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
509 ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
510 } else {
511 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "DISCONNECT did not have a cause code\n");
512 ftdmchan->caller_data.hangup_cause = 0;
513 }
514 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_REL);
515 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
516 break;
517 case FTDM_CHANNEL_STATE_COLLECT:
518 case FTDM_CHANNEL_STATE_GET_CALLERID:
519 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
520 break;
521 case FTDM_CHANNEL_STATE_DOWN:
522
523 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT but we are in DOWN state\n");
524 break;
525 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
526
527
528 break;
529 case FTDM_CHANNEL_STATE_RESET:
530 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
531 break;
532 default:
533 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
534 ftdm_channel_state2str(ftdmchan->state));
535
536
537
538 ftdm_set_flag(sngisdn_info, FLAG_REMOTE_REL);
539 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
540 break;
541 }
542
543 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
544 return;
545 }
546
547 void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
548 {
549 int16_t suId = sngisdn_event->suId;
550 uint32_t suInstId = sngisdn_event->suInstId;
551 uint32_t spInstId = sngisdn_event->spInstId;
552 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
553 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
554
555 RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
556
557 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
558
559 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
560
561 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
562
563 if ((suInstId && (sngisdn_info->glare.suInstId == suInstId)) ||
564 (spInstId && (sngisdn_info->glare.spInstId == spInstId))) {
565
566
567 ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL);
568 clear_call_glare_data(sngisdn_info);
569
570 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
571 return;
572 }
573
574
575 switch (ftdmchan->state) {
576 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
577
578 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
579 break;
580 case FTDM_CHANNEL_STATE_DOWN:
581
582 break;
583 case FTDM_CHANNEL_STATE_DIALING:
584
585 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
586 sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
587 }
588
589 case FTDM_CHANNEL_STATE_PROCEED:
590 case FTDM_CHANNEL_STATE_PROGRESS:
591 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
592 case FTDM_CHANNEL_STATE_UP:
593 case FTDM_CHANNEL_STATE_RING:
594 case FTDM_CHANNEL_STATE_RINGING:
595
596
597
598 if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId ||
599 ((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) {
600
601 get_facility_ie(ftdmchan, &relEvnt->facilityStr);
602
603 if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
604 ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
605 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
606 } else {
607 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n");
608 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL;
609 }
610
611 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
612 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
613
614 } else {
615 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "RELEASE was for previous call (suInstId:%u spInstId:%u)\n", suInstId, spInstId);
616 }
617 break;
618 case FTDM_CHANNEL_STATE_COLLECT:
619 case FTDM_CHANNEL_STATE_GET_CALLERID:
620 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
621 break;
622 case FTDM_CHANNEL_STATE_TERMINATING:
623 if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE) &&
624 sngisdn_info->glare.suInstId != suInstId) {
625
626
627 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received RELEASE for local glared call\n");
628 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
629 } else {
630 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received release before we could clear local call\n");
631
632 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
633
634 }
635 break;
636 case FTDM_CHANNEL_STATE_RESET:
637 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
638 break;
639 default:
640 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
641 ftdm_channel_state2str(ftdmchan->state));
642
643 break;
644 }
645
646
647 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
648 return;
649 }
650
651 void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
652 {
653 int16_t suId = sngisdn_event->suId;
654 uint32_t suInstId = sngisdn_event->suInstId;
655 uint32_t spInstId = sngisdn_event->spInstId;
656
657 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
658 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
659
660 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
661
662
663
664
665 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DATA IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
666 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
667 return;
668 }
669
670 void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
671 {
672 int16_t suId = sngisdn_event->suId;
673 uint32_t suInstId = sngisdn_event->suInstId;
674 uint32_t spInstId = sngisdn_event->spInstId;
675
676 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
677 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
678
679 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
680
681
682
683
684 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
685 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
686 return;
687 }
688
689 void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
690 {
691 int16_t suId = sngisdn_event->suId;
692 uint32_t suInstId = sngisdn_event->suInstId;
693 uint32_t spInstId = sngisdn_event->spInstId;
694
695 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
696 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
697
698 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
699
700
701
702
703 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
704 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
705 return;
706 }
707
708 void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
709 {
710 int16_t suId = sngisdn_event->suId;
711 uint32_t suInstId = sngisdn_event->suInstId;
712 uint32_t spInstId = sngisdn_event->spInstId;
713
714 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
715 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
716
717 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
718
719
720
721
722 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
723 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
724 return;
725 }
726
727 void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
728 {
729 int16_t suId = sngisdn_event->suId;
730 uint32_t suInstId = sngisdn_event->suInstId;
731 uint32_t spInstId = sngisdn_event->spInstId;
732
733 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
734 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
735
736 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
737
738
739
740
741 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
742 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
743 return;
744 }
745
746 void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
747 {
748 int16_t suId = sngisdn_event->suId;
749 uint32_t suInstId = sngisdn_event->suInstId;
750 uint32_t spInstId = sngisdn_event->spInstId;
751
752 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
753 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
754
755 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
756
757
758
759
760 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
761 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
762 return;
763 }
764
765 void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
766 {
767 int16_t suId = sngisdn_event->suId;
768 uint32_t suInstId = sngisdn_event->suInstId;
769 uint32_t spInstId = sngisdn_event->spInstId;
770
771 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
772 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
773 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
774
775 FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
776
777 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
778
779 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
780
781 switch (ftdmchan->state) {
782 case FTDM_CHANNEL_STATE_GET_CALLERID:
783
784
785 if (facEvnt->facElmt.facStr.pres) {
786 char retrieved_str[255];
787
788
789
790
791
792
793
794 if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
795 strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
796 } else {
797 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
798 }
799 if (signal_data->facility_timeout) {
800
801 ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
802 }
803 }
804
805 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
806 break;
807 case FTDM_CHANNEL_STATE_RING:
808
809 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n");
810 break;
811 case FTDM_CHANNEL_STATE_UP:
812 {
813 ftdm_sigmsg_t sigev;
814 if (facEvnt->facElmt.facStr.pres) {
815 get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2);
816 }
817 memset(&sigev, 0, sizeof(sigev));
818 sigev.chan_id = ftdmchan->chan_id;
819 sigev.span_id = ftdmchan->span_id;
820 sigev.channel = ftdmchan;
821
822 sigev.event_id = FTDM_SIGEVENT_FACILITY;
823 ftdm_span_send_signal(ftdmchan->span, &sigev);
824 }
825 break;
826 default:
827
828 break;
829 }
830 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
831 return;
832 }
833
834 void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
835 {
836 int16_t suId = sngisdn_event->suId;
837 uint32_t suInstId = sngisdn_event->suInstId;
838 uint32_t spInstId = sngisdn_event->spInstId;
839 sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
840 ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
841
842 StaEvnt *staEvnt = &sngisdn_event->event.staEvnt;
843
844 uint8_t call_state = 0;
845
846 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
847
848 if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
849 call_state = staEvnt->callSte.callGlblSte.val;
850 }
851
852 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
853
854 ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
855
856 if (staEvnt->causeDgn[0].eh.pres && staEvnt->causeDgn[0].causeVal.pres) {
857 if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
858 call_state = staEvnt->callSte.callGlblSte.val;
859 } else {
860 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received STATUS without call state\n");
861 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
862 return;
863 }
864 switch (staEvnt->causeDgn[0].causeVal.val) {
865 case FTDM_CAUSE_RESPONSE_TO_STATUS_ENQUIRY:
866 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Status Check OK:%d", call_state);
867 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
868 return;
869 case FTDM_CAUSE_WRONG_CALL_STATE:
870 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Message incompatible with call state (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
871 break;
872 case FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
873 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Recovery on timer expire (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
874 break;
875 default:
876 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "STATUS CONFIRM (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
877 break;
878 }
879
880
881 ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
882
883 switch(call_state) {
884
885 case 0:
886 switch (ftdmchan->state) {
887 case FTDM_CHANNEL_STATE_COLLECT:
888 case FTDM_CHANNEL_STATE_DIALING:
889 case FTDM_CHANNEL_STATE_UP:
890 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
891 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
892 break;
893 case FTDM_CHANNEL_STATE_TERMINATING:
894
895
896 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
897 break;
898 case FTDM_CHANNEL_STATE_HANGUP:
899
900
901
902 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n");
903 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
904 break;
905 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
906
907
908 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
909 break;
910 case FTDM_CHANNEL_STATE_DOWN:
911
912 break;
913 default:
914 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
915 break;
916 }
917 break;
918 case 1:
919 switch (ftdmchan->state) {
920 case FTDM_CHANNEL_STATE_UP:
921
922 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
923 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
924 break;
925 }
926
927 default:
928 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
929 break;
930 }
931 break;
932 case 2:
933 switch (ftdmchan->state) {
934 case FTDM_CHANNEL_STATE_COLLECT:
935
936
937 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
938 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
939 break;
940 case FTDM_CHANNEL_STATE_PROCEED:
941 case FTDM_CHANNEL_STATE_PROGRESS:
942 case FTDM_CHANNEL_STATE_RINGING:
943 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
944 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
945 sngisdn_snd_disconnect(ftdmchan);
946 break;
947 case FTDM_CHANNEL_STATE_DOWN:
948 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
949
950 sngisdn_snd_disconnect(ftdmchan);
951 break;
952 default:
953 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
954 break;
955 }
956 break;
957 case 3:
958 switch (ftdmchan->state) {
959 case FTDM_CHANNEL_STATE_PROCEED:
960 case FTDM_CHANNEL_STATE_PROGRESS:
961 case FTDM_CHANNEL_STATE_RINGING:
962
963 ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
964 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n");
965 sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
966 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
967
968 break;
969 case FTDM_CHANNEL_STATE_UP:
970
971 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
972 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
973 break;
974 }
975
976 default:
977 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
978 break;
979 }
980 break;
981 case 8:
982 switch (ftdmchan->state) {
983 case FTDM_CHANNEL_STATE_UP:
984
985
986 break;
987 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
988
989 sngisdn_snd_disconnect(ftdmchan);
990 break;
991 default:
992 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
993 break;
994 }
995 break;
996 case 9:
997 switch (ftdmchan->state) {
998 case FTDM_CHANNEL_STATE_RINGING:
999 case FTDM_CHANNEL_STATE_PROGRESS:
1000 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
1001 case FTDM_CHANNEL_STATE_GET_CALLERID:
1002
1003 break;
1004 case FTDM_CHANNEL_STATE_UP:
1005
1006 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
1007 break;
1008 default:
1009 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1010 break;
1011 }
1012 break;
1013 case 10:
1014 switch (ftdmchan->state) {
1015 case FTDM_CHANNEL_STATE_UP:
1016
1017
1018 break;
1019 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1020
1021 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
1022 break;
1023 default:
1024 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1025 break;
1026 }
1027 break;
1028 case 12:
1029 switch (ftdmchan->state) {
1030 case FTDM_CHANNEL_STATE_TERMINATING:
1031
1032 break;
1033 default:
1034 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1035 break;
1036 }
1037 break;
1038 case 22:
1039 switch (ftdmchan->state) {
1040 case FTDM_CHANNEL_STATE_UP:
1041
1042 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
1043 break;
1044 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1045
1046 break;
1047 default:
1048 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1049
1050 break;
1051 }
1052 break;
1053 case 25:
1054 switch (ftdmchan->state) {
1055 case FTDM_CHANNEL_STATE_COLLECT:
1056
1057 break;
1058 default:
1059 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1060
1061 break;
1062 }
1063 break;
1064 default:
1065 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1066
1067 break;
1068 }
1069 }
1070
1071 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1072 return;
1073 }
1074
1075
1076 void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
1077 {
1078 int16_t suId = sngisdn_event->suId;
1079 int16_t dChan = sngisdn_event->dChan;
1080 uint8_t ces = sngisdn_event->ces;
1081
1082 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1083
1084
1085
1086
1087 ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE IND (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
1088 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1089 return;
1090 }
1091
1092 void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
1093 {
1094 int16_t suId = sngisdn_event->suId;
1095 int16_t dChan = sngisdn_event->dChan;
1096 uint8_t ces = sngisdn_event->ces;
1097
1098 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1099
1100
1101
1102
1103 ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE CFM (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
1104 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1105 return;
1106 }
1107
1108 static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
1109 {
1110 switch (ftdmchan->state) {
1111 case FTDM_CHANNEL_STATE_RESET:
1112 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1113 break;
1114 case FTDM_CHANNEL_STATE_DOWN:
1115
1116 break;
1117 default:
1118 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
1119 ftdm_channel_state2str(ftdmchan->state));
1120 }
1121
1122 return;
1123 }
1124
1125
1126 void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
1127 {
1128 int16_t suId = sngisdn_event->suId;
1129 int16_t dChan = sngisdn_event->dChan;
1130 uint8_t ces = sngisdn_event->ces;
1131 uint8_t evntType = sngisdn_event->evntType;
1132 uint8_t chan_no = 0;
1133 Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
1134
1135 sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1];
1136 if (!signal_data) {
1137 ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
1138 return;
1139 }
1140
1141 if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
1142 ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
1143 return;
1144 }
1145
1146 switch(rstEvnt->rstInd.rstClass.val) {
1147 case IN_CL_INDCHAN:
1148 if (rstEvnt->chanId.eh.pres) {
1149 if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
1150 if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
1151 chan_no = rstEvnt->chanId.infoChanSel.val;
1152 }
1153 } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
1154 if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
1155 chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
1156 }
1157 }
1158 }
1159 if (!chan_no) {
1160 ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
1161 return;
1162 }
1163 break;
1164 case IN_CL_SNGINT:
1165 case IN_CL_ALLINT:
1166
1167
1168
1169 break;
1170 default:
1171 ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
1172 return;
1173 }
1174
1175 if (chan_no) {
1176 if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
1177 ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
1178 } else {
1179 ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
1180 sngisdn_process_restart_confirm(ftdmchan);
1181 }
1182 } else {
1183 ftdm_iterator_t *chaniter = NULL;
1184 ftdm_iterator_t *curr = NULL;
1185
1186 chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
1187 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
1188 sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
1189 }
1190 ftdm_iterator_free(chaniter);
1191 }
1192
1193 ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
1194 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1195 return;
1196 }
1197
1198
1199 void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
1200 {
1201 int16_t suId = sngisdn_event->suId;
1202 int16_t dChan = sngisdn_event->dChan;
1203 uint8_t ces = sngisdn_event->ces;
1204 uint8_t evntType = sngisdn_event->evntType;
1205
1206 ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1207
1208
1209
1210
1211 ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces,
1212 (evntType == IN_LNK_DWN)?"LNK_DOWN":
1213 (evntType == IN_LNK_UP)?"LNK_UP":
1214 (evntType == IN_INDCHAN)?"b-channel":
1215 (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
1216 (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
1217 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1218 return;
1219 }
1220
1221 static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
1222 {
1223 sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
1224
1225 if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) {
1226 return FTDM_FAIL;
1227 }
1228
1229
1230 if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT &&
1231 signal_data->switchtype != SNGISDN_SWITCH_5ESS) {
1232
1233 return FTDM_FAIL;
1234 }
1235
1236
1237 switch(causeDgn->causeVal.val) {
1238 case 17:
1239 case 18:
1240 case 19:
1241 case 21:
1242 case 27:
1243 case 31:
1244 case 34:
1245 case 41:
1246 case 42:
1247 case 47:
1248 case 58:
1249 case 63:
1250 case 65:
1251 case 79:
1252 return FTDM_SUCCESS;
1253 }
1254 return FTDM_FAIL;
1255 }