This source file includes following definitions.
- isdn_pcap_is_open
- isdn_pcap_capture_both
- isdn_pcap_capture_l3only
- isdn_pcap_open
- isdn_pcap_close
- isdn_pcap_start
- isdn_pcap_stop
- isdn_pcap_write
- ftdm_time_now
- FIO_CHANNEL_GET_SIG_STATUS_FUNCTION
- FIO_SPAN_GET_SIG_STATUS_FUNCTION
- FIO_CHANNEL_OUTGOING_CALL_FUNCTION
- FIO_CHANNEL_REQUEST_FUNCTION
- ftdm_isdn_931_err
- ftdm_isdn_call_event
- __isdn_get_number
- ftdm_isdn_931_34
- ftdm_isdn_921_23
- ftdm_isdn_921_21
- state_advance
- check_state
- process_event
- check_events
- teletone_handler
- ftdm_isdn_tones_run
- ftdm_isdn_run
- q931_rx_32
- ftdm_isdn_q921_log
- ftdm_isdn_q931_log
- ftdm_isdn_stop
- ftdm_isdn_start
- parse_loglevel
- parse_opts
- parse_dialect
- FIO_API_FUNCTION
- parse_mode
- FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION
- FIO_IO_LOAD_FUNCTION
- FIO_SIG_LOAD_FUNCTION
- FIO_SIG_UNLOAD_FUNCTION
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 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36 #include <private/ftdm_core.h>
37 #include <libisdn/Q931.h>
38 #include <libisdn/Q921.h>
39
40 #ifdef WIN32
41 #include <windows.h>
42 #else
43 #include <sys/time.h>
44 #endif
45
46 #include "ftmod_isdn.h"
47
48 #define LINE "--------------------------------------------------------------------------------"
49
50
51 #define FTDM_SPAN_IS_NT(x) (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT)
52
53 #define DEFAULT_NATIONAL_PREFIX "0"
54 #define DEFAULT_INTERNATIONAL_PREFIX "00"
55
56
57
58
59
60
61 #ifdef HAVE_PCAP
62 #include <arpa/inet.h>
63 #include <pcap.h>
64
65 #define PCAP_SNAPLEN 1500
66
67 struct pcap_context {
68 pcap_dumper_t *dump;
69 pcap_t *handle;
70 char *filename;
71 };
72
73 static inline ftdm_status_t isdn_pcap_is_open(struct ftdm_isdn_data *isdn)
74 {
75 return (isdn->pcap) ? 1 : 0;
76 }
77
78 static inline ftdm_status_t isdn_pcap_capture_both(struct ftdm_isdn_data *isdn)
79 {
80 return ((isdn->flags & (FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY)) == FTDM_ISDN_CAPTURE) ? 1 : 0;
81 }
82
83 static inline ftdm_status_t isdn_pcap_capture_l3only(struct ftdm_isdn_data *isdn)
84 {
85 return ((isdn->flags & FTDM_ISDN_CAPTURE) && (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY)) ? 1 : 0;
86 }
87
88 static ftdm_status_t isdn_pcap_open(struct ftdm_isdn_data *isdn, char *filename)
89 {
90 struct pcap_context *pcap = NULL;
91
92 if (!isdn || ftdm_strlen_zero(filename))
93 return FTDM_FAIL;
94
95 pcap = malloc(sizeof(struct pcap_context));
96 if (!pcap) {
97 ftdm_log(FTDM_LOG_ERROR, "Failed to allocate isdn pcap context\n");
98 return FTDM_FAIL;
99 }
100
101 memset(pcap, 0, sizeof(struct pcap_context));
102
103 pcap->filename = strdup(filename);
104
105 pcap->handle = pcap_open_dead(DLT_LINUX_LAPD, PCAP_SNAPLEN);
106 if (!pcap->handle) {
107 ftdm_log(FTDM_LOG_ERROR, "Failed to open pcap handle\n");
108 goto error;
109 }
110
111 pcap->dump = pcap_dump_open(pcap->handle, pcap->filename);
112 if (!pcap->dump) {
113 ftdm_log(FTDM_LOG_ERROR, "Failed to open capture file: '%s'\n", pcap_geterr(pcap->handle));
114 goto error;
115 }
116
117 ftdm_log(FTDM_LOG_INFO, "Capture file '%s' opened\n", pcap->filename);
118
119 isdn->pcap = pcap;
120
121 return FTDM_SUCCESS;
122 error:
123 if (pcap->handle)
124 pcap_close(pcap->handle);
125 if (pcap->filename)
126 free(pcap->filename);
127
128 free(pcap);
129
130 return FTDM_FAIL;
131 }
132
133 static ftdm_status_t isdn_pcap_close(struct ftdm_isdn_data *isdn)
134 {
135 struct pcap_context *pcap = NULL;
136 long size;
137
138 if (!isdn || !isdn->pcap)
139 return FTDM_FAIL;
140
141 pcap = isdn->pcap;
142
143 isdn->flags &= ~(FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY);
144 isdn->pcap = NULL;
145
146 pcap_dump_flush(pcap->dump);
147
148 size = pcap_dump_ftell(pcap->dump);
149 ftdm_log(FTDM_LOG_INFO, "File '%s' captured %ld bytes of data\n", pcap->filename, size);
150
151 pcap_dump_close(pcap->dump);
152 pcap_close(pcap->handle);
153
154 free(pcap->filename);
155 free(pcap);
156
157 return FTDM_SUCCESS;
158 }
159
160 static inline void isdn_pcap_start(struct ftdm_isdn_data *isdn)
161 {
162 if (!isdn->pcap)
163 return;
164
165 isdn->flags |= FTDM_ISDN_CAPTURE;
166 }
167
168 static inline void isdn_pcap_stop(struct ftdm_isdn_data *isdn)
169 {
170 isdn->flags &= ~FTDM_ISDN_CAPTURE;
171 }
172
173 #ifndef ETH_P_LAPD
174 #define ETH_P_LAPD 0x0030
175 #endif
176
177 struct isdn_sll_hdr {
178 uint16_t slltype;
179 uint16_t sllhatype;
180 uint16_t slladdrlen;
181 uint8_t slladdr[8];
182 uint16_t sllproto;
183 };
184
185
186
187
188 enum {
189 ISDN_PCAP_INCOMING = 0,
190 ISDN_PCAP_INCOMING_BCAST = 1,
191 ISDN_PCAP_OUTGOING = 4,
192 };
193
194 static ftdm_status_t isdn_pcap_write(struct ftdm_isdn_data *isdn, unsigned char *buf, ftdm_ssize_t len, int direction)
195 {
196 unsigned char frame[PCAP_SNAPLEN];
197 struct pcap_context *pcap;
198 struct isdn_sll_hdr *sll_hdr = (struct isdn_sll_hdr *)frame;
199 struct pcap_pkthdr hdr;
200 int offset = sizeof(struct isdn_sll_hdr);
201 int nbytes;
202
203 if (!isdn || !isdn->pcap || !buf || !len)
204 return FTDM_FAIL;
205
206 pcap = isdn->pcap;
207
208
209 sll_hdr->slltype = htons(direction);
210 sll_hdr->sllhatype = 0;
211 sll_hdr->slladdrlen = 1;
212 sll_hdr->slladdr[0] = (isdn->mode == Q921_NT) ? 1 : 0;
213 sll_hdr->sllproto = htons(ETH_P_LAPD);
214
215 #if 0
216
217 if (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY) {
218
219 memcpy(frame + offset, q921_fake_frame, sizeof(q921_fake_frame));
220 offset += sizeof(q921_fake_frame);
221 }
222 #endif
223
224
225 nbytes = (len > (PCAP_SNAPLEN - offset)) ? (PCAP_SNAPLEN - offset) : len;
226 memcpy(frame + offset, buf, nbytes);
227
228
229 memset(&hdr, 0, sizeof(struct pcap_pkthdr));
230 gettimeofday(&hdr.ts, NULL);
231 hdr.caplen = offset + nbytes;
232 hdr.len = hdr.caplen;
233
234
235 pcap_dump((unsigned char *)pcap->dump, &hdr, frame);
236
237 return FTDM_SUCCESS;
238 }
239 #endif
240
241
242 static L2ULONG ftdm_time_now(void)
243 {
244 return (L2ULONG)ftdm_current_time_in_ms();
245 }
246
247
248
249
250
251
252
253 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(isdn_get_channel_sig_status)
254 {
255 *status = FTDM_SIG_STATE_DOWN;
256
257 ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
258 if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
259 *status = FTDM_SIG_STATE_UP;
260 }
261 return FTDM_SUCCESS;
262 }
263
264
265
266
267
268
269
270 static FIO_SPAN_GET_SIG_STATUS_FUNCTION(isdn_get_span_sig_status)
271 {
272 *status = FTDM_SIG_STATE_DOWN;
273
274 ftdm_isdn_data_t *isdn_data = span->signal_data;
275 if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
276 *status = FTDM_SIG_STATE_UP;
277 }
278 return FTDM_SUCCESS;
279 }
280
281
282
283
284
285
286 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
287 {
288 ftdm_status_t status = FTDM_SUCCESS;
289 ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
290 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
291 return status;
292 }
293
294
295
296
297
298
299
300 #ifdef __TODO__
301 static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
302 {
303 Q931mes_Generic *gen = (Q931mes_Generic *) caller_data->raw_data;
304 Q931ie_BearerCap BearerCap;
305 Q931ie_ChanID ChanID = { 0 };
306 Q931ie_CallingNum CallingNum;
307 Q931ie_CallingNum *ptrCallingNum;
308 Q931ie_CalledNum CalledNum;
309 Q931ie_CalledNum *ptrCalledNum;
310 Q931ie_Display Display, *ptrDisplay;
311 Q931ie_HLComp HLComp;
312 Q931ie_ProgInd Progress;
313 ftdm_status_t status = FTDM_FAIL;
314 ftdm_isdn_data_t *isdn_data = span->signal_data;
315 int sanity = 60000;
316 int codec = 0;
317
318
319
320
321 ftdm_channel_command(span->channels[chan_id], FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
322
323
324
325
326 Q931InitMesGeneric(gen);
327 gen->MesType = Q931mes_SETUP;
328 gen->CRVFlag = 0;
329
330
331
332
333 Q931InitIEBearerCap(&BearerCap);
334 BearerCap.CodStand = Q931_CODING_ITU;
335 BearerCap.ITC = Q931_ITC_SPEECH;
336 BearerCap.TransMode = 0;
337 BearerCap.ITR = Q931_ITR_64K;
338 BearerCap.Layer1Ident = 1;
339 BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? Q931_UIL1P_G711A : Q931_UIL1P_G711U;
340 gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap);
341
342
343
344
345 Q931InitIEChanID(&ChanID);
346 ChanID.IntType = FTDM_SPAN_IS_BRI(span) ? 0 : 1;
347
348 if (!FTDM_SPAN_IS_NT(span)) {
349 ChanID.PrefExcl = (isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL) ? 0 : 1;
350 } else {
351 ChanID.PrefExcl = 1;
352 }
353
354 if (ChanID.IntType) {
355 ChanID.InfoChanSel = 1;
356 ChanID.ChanMapType = 3;
357 ChanID.ChanSlot = (unsigned char)chan_id;
358 } else {
359 ChanID.InfoChanSel = (unsigned char)chan_id & 0x03;
360 }
361 gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
362
363
364
365
366 Q931InitIEProgInd(&Progress);
367 Progress.CodStand = Q931_CODING_ITU;
368 Progress.Location = 0;
369 Progress.ProgDesc = 3;
370 gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress);
371
372
373
374
375 if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(span)) {
376 Q931InitIEDisplay(&Display);
377 Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name);
378 gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display);
379 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
380 ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name)+1);
381 }
382
383
384
385
386 Q931InitIECallingNum(&CallingNum);
387 CallingNum.TypNum = Q931_TON_UNKNOWN;
388 CallingNum.NumPlanID = Q931_NUMPLAN_E164;
389 CallingNum.PresInd = Q931_PRES_ALLOWED;
390 CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
391 CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits);
392 gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum);
393 ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
394 ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits)+1);
395
396
397
398
399
400 Q931InitIECalledNum(&CalledNum);
401 CalledNum.TypNum = Q931_TON_UNKNOWN;
402 CalledNum.NumPlanID = Q931_NUMPLAN_E164;
403 CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits);
404 gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum);
405 ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
406 ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits)+1);
407
408
409
410
411 Q931InitIEHLComp(&HLComp);
412 HLComp.CodStand = Q931_CODING_ITU;
413 HLComp.Interpret = 4;
414 HLComp.PresMeth = 1;
415 HLComp.HLCharID = 1;
416 gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp);
417
418 caller_data->call_state = FTDM_CALLER_STATE_DIALING;
419 Q931Rx43(&isdn_data->q931, gen, gen->Size);
420
421 isdn_data->outbound_crv[gen->CRV] = caller_data;
422
423
424 while (ftdm_running() && caller_data->call_state == FTDM_CALLER_STATE_DIALING) {
425 ftdm_sleep(1);
426
427 if (!--sanity) {
428 caller_data->call_state = FTDM_CALLER_STATE_FAIL;
429 break;
430 }
431 }
432 isdn_data->outbound_crv[gen->CRV] = NULL;
433
434 if (caller_data->call_state == FTDM_CALLER_STATE_SUCCESS) {
435 ftdm_channel_t *new_chan = NULL;
436 int fail = 1;
437
438 new_chan = NULL;
439 if (caller_data->chan_id > 0 && caller_data->chan_id <= ftdm_span_get_chan_count(span)) {
440 new_chan = ftdm_span_get_channel(span, caller_data->chan_id);
441 }
442
443 if (new_chan && (status = ftdm_channel_open_chan(new_chan) == FTDM_SUCCESS)) {
444 if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE) || new_chan->state != FTDM_CHANNEL_STATE_DOWN) {
445 if (new_chan->state == FTDM_CHANNEL_STATE_DOWN || new_chan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
446 int x = 0;
447 ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n");
448
449 for (x = 0; x < 200; x++) {
450 if (!ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
451 break;
452 }
453 ftdm_sleep(5);
454 }
455 }
456 if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
457 ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
458 new_chan->span_id,
459 new_chan->chan_id,
460 new_chan->physical_span_id,
461 new_chan->physical_chan_id
462 );
463 new_chan = NULL;
464 }
465 }
466
467 if (new_chan && new_chan->state == FTDM_CHANNEL_STATE_DOWN) {
468 isdn_data->channels_local_crv[gen->CRV] = new_chan;
469 memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data));
470 ftdm_set_flag(new_chan, FTDM_CHANNEL_OUTBOUND);
471 ftdm_set_state_locked(new_chan, FTDM_CHANNEL_STATE_DIALING);
472 switch(gen->MesType) {
473 case Q931mes_ALERTING:
474 new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA;
475 break;
476 case Q931mes_CONNECT:
477 new_chan->init_state = FTDM_CHANNEL_STATE_UP;
478 break;
479 default:
480 new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS;
481 break;
482 }
483
484 fail = 0;
485 }
486 }
487
488 if (!fail) {
489 *ftdmchan = new_chan;
490 return FTDM_SUCCESS;
491 } else {
492 Q931ie_Cause cause;
493 gen->MesType = Q931mes_DISCONNECT;
494 cause.IEId = Q931ie_CAUSE;
495 cause.Size = sizeof(Q931ie_Cause);
496 cause.CodStand = 0;
497 cause.Location = 1;
498 cause.Recom = 1;
499
500 cause.Value = (unsigned char) FTDM_CAUSE_WRONG_CALL_STATE;
501 *cause.Diag = '\0';
502 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
503 Q931Rx43(&isdn_data->q931, gen, gen->Size);
504
505 if (gen->CRV) {
506 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
507 }
508
509 if (new_chan) {
510 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
511 } else {
512 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
513 }
514 }
515 }
516
517 *ftdmchan = NULL;
518 return FTDM_FAIL;
519
520 }
521 #endif
522
523 static L3INT ftdm_isdn_931_err(void *pvt, L3INT id, L3INT p1, L3INT p2)
524 {
525 ftdm_log(FTDM_LOG_ERROR, "ERROR: [%s] [%d] [%d]\n", q931_error_to_name(id), p1, p2);
526 return 0;
527 }
528
529
530
531
532
533
534 static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *event, void *priv)
535 {
536 Q931_TrunkInfo_t *trunk = NULL;
537 ftdm_isdn_data_t *isdn_data = NULL;
538 ftdm_span_t *zspan = NULL;
539 assert(call);
540 assert(event);
541
542 trunk = Q931CallGetTrunk(call);
543 assert(trunk);
544
545 zspan = Q931CallGetPrivate(call);
546 if (!zspan) {
547 zspan = priv;
548 Q931CallSetPrivate(call, zspan);
549 }
550 assert(zspan);
551
552 isdn_data = zspan->signal_data;
553
554 if (Q931CallIsGlobal(call)) {
555
556
557
558 ftdm_log(FTDM_LOG_DEBUG, "Received global event from Q.931\n");
559 } else {
560 ftdm_channel_t *ftdmchan = NULL;
561 ftdm_sigmsg_t sig;
562 int call_crv = Q931CallGetCRV(call);
563 int type;
564
565
566
567
568 ftdm_log(FTDM_LOG_DEBUG, "Received call-specific event from Q.931 for call %d [%hu]\n", Q931CallGetCRV(call), Q931CallGetCRV(call));
569
570
571
572
573
574 ftdmchan = Q931CallIsOutgoing(call) ? isdn_data->channels_local_crv[call_crv] : isdn_data->channels_remote_crv[call_crv];
575 if (ftdmchan) {
576 memset(&sig, 0, sizeof(ftdm_sigmsg_t));
577 sig.chan_id = ftdmchan->chan_id;
578 sig.span_id = ftdmchan->span_id;
579 sig.channel = ftdmchan;
580 }
581
582 type = Q931CallEventGetType(event);
583
584 if (type == Q931_EVENT_TYPE_CRV) {
585
586 ftdm_log(FTDM_LOG_DEBUG, "\tCRV event\n");
587
588 switch (Q931CallEventGetId(event)) {
589 case Q931_EVENT_RELEASE_CRV:
590 {
591
592 if (!ftdmchan) {
593 ftdm_log(FTDM_LOG_DEBUG, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
594 return;
595 }
596
597 if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
598 ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
599 ftdm_channel_get_span_id(ftdmchan),
600 ftdm_channel_get_id(ftdmchan));
601
602
603
604
605 if (!sig.channel->caller_data.hangup_cause) {
606 sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
607 }
608
609 sig.event_id = FTDM_SIGEVENT_STOP;
610 ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
611
612
613 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
614 }
615 return;
616 }
617 break;
618 default:
619 ftdm_log(FTDM_LOG_ERROR, "Unknown CRV event: %d\n", Q931CallEventGetId(event));
620 return;
621 }
622 }
623 else if (type == Q931_EVENT_TYPE_TIMER) {
624 struct Q931_CallTimerEvent *timer_evt = Q931CallEventGetData(event);
625
626 ftdm_log(FTDM_LOG_DEBUG, "\tTimer event\n");
627 assert(timer_evt->id);
628
629 switch (timer_evt->id) {
630 case Q931_TIMER_T303:
631
632
633
634
635
636
637 {
638
639 if (!ftdmchan) {
640 ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
641 return;
642 }
643
644 ftdm_log(FTDM_LOG_DEBUG, "Call setup failed on channel %d:%d\n",
645 ftdm_channel_get_span_id(ftdmchan),
646 ftdm_channel_get_id(ftdmchan));
647
648
649
650
651 sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NETWORK_OUT_OF_ORDER;
652
653 sig.event_id = FTDM_SIGEVENT_STOP;
654 ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
655
656
657 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
658 return;
659 }
660 break;
661
662 default:
663 ftdm_log(FTDM_LOG_ERROR, "Unhandled timer event %d\n", timer_evt->id);
664 }
665 }
666 else if (type == Q931_EVENT_TYPE_MESSAGE) {
667 struct Q931_CallMessageEvent *msg_evt = Q931CallEventGetData(event);
668
669 ftdm_log(FTDM_LOG_DEBUG, "\tMessage event\n");
670 assert(msg_evt);
671
672
673
674
675 switch (Q931CallEventGetId(event)) {
676 case Q931_EVENT_SETUP_CONFIRM:
677 case Q931_EVENT_SETUP_COMPLETE_INDICATION:
678 {
679
680 if (!ftdmchan) {
681 ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
682 return;
683 }
684 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
685 }
686 break;
687
688 default:
689 ftdm_log(FTDM_LOG_DEBUG, "Not yet handled message event %d\n", Q931CallEventGetId(event));
690 }
691 }
692 else {
693 ftdm_log(FTDM_LOG_ERROR, "Unknown event type %d\n", type);
694 }
695 }
696 }
697
698
699
700
701 static void __isdn_get_number(const char *digits, const int ton, char *buf, int size)
702 {
703 int offset = 0;
704
705 if (!digits || !buf || size <= 0)
706 return;
707
708 switch (ton) {
709 case Q931_TON_NATIONAL:
710 offset = strlen(DEFAULT_NATIONAL_PREFIX);
711 memcpy(buf, DEFAULT_NATIONAL_PREFIX, offset);
712 break;
713 case Q931_TON_INTERNATIONAL:
714 offset = strlen(DEFAULT_INTERNATIONAL_PREFIX);
715 memcpy(buf, DEFAULT_INTERNATIONAL_PREFIX, offset);
716 break;
717 default:
718 break;
719 }
720
721 strncpy(&buf[offset], digits, size - (offset + 1));
722 buf[size - 1] = '\0';
723 }
724
725 #define isdn_get_number(num, buf) \
726 __isdn_get_number((const char *)(num)->Digit, (num)->TypNum, (char *)buf, sizeof(buf))
727
728
729
730
731
732
733 static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic *msg, int mlen)
734 {
735 Q931mes_Generic *gen = (Q931mes_Generic *) msg;
736 ftdm_span_t *span = (ftdm_span_t *) pvt;
737 ftdm_isdn_data_t *isdn_data = span->signal_data;
738 ftdm_channel_t *ftdmchan = NULL;
739 int chan_id = 0;
740 int chan_hunt = 0;
741
742 if (Q931IsIEPresent(gen->ChanID)) {
743 Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
744
745 if (chanid->IntType)
746 chan_id = chanid->ChanSlot;
747 else
748 chan_id = chanid->InfoChanSel;
749
750
751 if (chanid->InfoChanSel == 3) {
752 chan_hunt++;
753 }
754 } else if (FTDM_SPAN_IS_NT(span)) {
755
756 chan_hunt++;
757 }
758
759 assert(span != NULL);
760 assert(isdn_data != NULL);
761
762
763
764
765
766 #ifdef __OLD__
767 if (gen->CRV) {
768 struct Q931_Call *call;
769
770 call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
771 if (call && !Q931CallGetPrivate(call)) {
772 ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
773 Q931CallSetPrivate(call, span);
774 }
775 }
776 #else
777 if (call && !Q931CallGetPrivate(call)) {
778 ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
779 Q931CallSetPrivate(call, span);
780 }
781 #endif
782 ftdm_log(FTDM_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d] CRV: %d (%#hx, CTX: %s)\n", gen->MesType, gen->Size, gen->CRV, gen->CRV, gen->CRVFlag ? "Terminator" : "Originator");
783
784 #ifdef __TODO_OR_REMOVE__
785 if (gen->CRVFlag && (caller_data = isdn_data->outbound_crv[gen->CRV])) {
786 if (chan_id) {
787 caller_data->chan_id = chan_id;
788 }
789
790 switch(gen->MesType) {
791 case Q931mes_STATUS:
792 case Q931mes_CALL_PROCEEDING:
793 break;
794 case Q931mes_ALERTING:
795 case Q931mes_PROGRESS:
796 case Q931mes_CONNECT:
797 caller_data->call_state = FTDM_CALLER_STATE_SUCCESS;
798 break;
799 default:
800 caller_data->call_state = FTDM_CALLER_STATE_FAIL;
801 break;
802 }
803
804 return 0;
805 }
806 #endif
807
808 if (gen->CRVFlag) {
809 ftdmchan = isdn_data->channels_local_crv[gen->CRV];
810 } else {
811 ftdmchan = isdn_data->channels_remote_crv[gen->CRV];
812 }
813
814 ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %x (%d:%d) source isdn_data->channels_%s_crv[%#hx]\n",
815 ftdmchan,
816 ((ftdmchan) ? ftdm_channel_get_span_id(ftdmchan) : -1),
817 ((ftdmchan) ? ftdm_channel_get_id(ftdmchan) : -1),
818 ((gen->CRVFlag) ? "local" : "remote"),
819 gen->CRV);
820
821 if (gen->ProtDisc == 3) {
822 switch(gen->MesType) {
823 case Q931mes_SERVICE:
824 {
825 Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf);
826 if (ftdmchan) {
827 switch (changestatus->NewStatus) {
828 case 0:
829 {
830 ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
831 ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d in service\n",
832 ftdm_channel_get_span_id(ftdmchan),
833 ftdm_channel_get_id(ftdmchan));
834 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
835 }
836 break;
837 case 1:
838 {
839 ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
840 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
841 }
842 break;
843 case 2:
844 {
845 ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
846 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
847 }
848 break;
849 default:
850 {
851 break;
852 }
853 }
854 }
855 }
856 break;
857 default:
858 break;
859 }
860 } else {
861 switch(gen->MesType) {
862 case Q931mes_RESTART:
863 {
864 if (chan_id) {
865 ftdmchan = ftdm_span_get_channel(span, chan_id);
866 }
867 if (ftdmchan) {
868 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
869 } else {
870 uint32_t i;
871
872 for (i = 1; i < ftdm_span_get_chan_count(span); i++) {
873
874 if (ftdm_channel_get_state(span->channels[i]) == FTDM_CHANNEL_STATE_DOWN ||
875 ftdm_channel_get_type(span->channels[i]) == FTDM_CHAN_TYPE_DQ921)
876 continue;
877
878 ftdm_set_state_locked(span->channels[i], FTDM_CHANNEL_STATE_RESTART);
879 }
880 }
881 }
882 break;
883 case Q931mes_RELEASE:
884 case Q931mes_RELEASE_COMPLETE:
885 {
886 const char *what = gen->MesType == Q931mes_RELEASE ? "Release" : "Release Complete";
887 if (ftdmchan) {
888 if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_TERMINATING ||
889 ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP)
890 {
891 if (gen->MesType == Q931mes_RELEASE) {
892 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
893 } else {
894 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
895 }
896 }
897 else if ((gen->MesType == Q931mes_RELEASE && ftdm_channel_get_state(ftdmchan) <= FTDM_CHANNEL_STATE_UP) ||
898 (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALING)) {
899
900
901
902
903 Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
904 ftdm_sigmsg_t sig;
905 ftdm_status_t status;
906
907 memset(&sig, 0, sizeof(sig));
908 sig.span_id = ftdm_channel_get_span_id(ftdmchan);
909 sig.chan_id = ftdm_channel_get_id(ftdmchan);
910 sig.channel = ftdmchan;
911 sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED;
912
913 sig.event_id = FTDM_SIGEVENT_STOP;
914 status = ftdm_span_send_signal(span, &sig);
915
916 ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what,
917 ftdm_channel_get_state_str(ftdmchan),
918 ftdm_channel_get_span_id(ftdmchan),
919 ftdm_channel_get_id(ftdmchan));
920 } else {
921 ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d\n", what, ftdm_channel_get_id(ftdmchan));
922 }
923 } else {
924 ftdm_log(FTDM_LOG_CRIT, "Received %s with no matching channel %d\n", what, chan_id);
925 }
926 }
927 break;
928 case Q931mes_DISCONNECT:
929 {
930 if (ftdmchan) {
931 Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
932 ftdmchan->caller_data.hangup_cause = cause->Value;
933 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
934 } else {
935 ftdm_log(FTDM_LOG_CRIT, "Received Disconnect with no matching channel %d\n", chan_id);
936 }
937 }
938 break;
939 case Q931mes_ALERTING:
940 {
941 if (ftdmchan) {
942 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
943 } else {
944 ftdm_log(FTDM_LOG_CRIT, "Received Alerting with no matching channel %d\n", chan_id);
945 }
946 }
947 break;
948 case Q931mes_PROGRESS:
949 {
950 if (ftdmchan) {
951 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
952 } else {
953 ftdm_log(FTDM_LOG_CRIT, "Received Progress with no matching channel %d\n", chan_id);
954 }
955 }
956 break;
957 case Q931mes_CONNECT:
958 #if 0
959 {
960 if (ftdmchan) {
961 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
962
963 #if 0
964 gen->MesType = Q931mes_CONNECT_ACKNOWLEDGE;
965 gen->CRVFlag = 0;
966 Q931Rx43(&isdn_data->q931, gen, gen->Size);
967 #endif
968 } else {
969 ftdm_log(FTDM_LOG_CRIT, "Received Connect with no matching channel %d\n", chan_id);
970 }
971 }
972 #endif
973 break;
974 case Q931mes_SETUP:
975 {
976 Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
977 Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
978 uint32_t cplen = mlen;
979 int overlap_dial = 0;
980 int fail_cause = 0;
981 int fail = 1;
982
983 if (ftdmchan && ftdmchan == isdn_data->channels_remote_crv[gen->CRV]) {
984 ftdm_log(FTDM_LOG_INFO, "Duplicate SETUP message(?) for Channel %d:%d ~ %d:%d in state %s [ignoring]\n",
985 ftdm_channel_get_span_id(ftdmchan),
986 ftdm_channel_get_id(ftdmchan),
987 ftdm_channel_get_ph_span_id(ftdmchan),
988 ftdm_channel_get_ph_id(ftdmchan),
989 ftdm_channel_get_state_str(ftdmchan));
990 break;
991 }
992
993 ftdmchan = NULL;
994
995
996
997 if (FTDM_SPAN_IS_NT(span) && chan_hunt) {
998 int x;
999
1000
1001
1002
1003
1004 for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1005 ftdm_channel_t *zc = ftdm_span_get_channel(span, x);
1006
1007 if (!ftdm_test_flag(zc, FTDM_CHANNEL_INUSE) && ftdm_channel_get_state(zc) == FTDM_CHANNEL_STATE_DOWN) {
1008 ftdmchan = zc;
1009 break;
1010 }
1011 }
1012 }
1013 else if (!FTDM_SPAN_IS_NT(span) && chan_hunt) {
1014
1015
1016
1017 fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
1018
1019 ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (network side didn't specify a channel)\n");
1020 }
1021 else {
1022
1023
1024
1025
1026
1027
1028 if (chan_id > 0 && chan_id < FTDM_MAX_CHANNELS_SPAN && chan_id <= ftdm_span_get_chan_count(span)) {
1029 ftdmchan = ftdm_span_get_channel(span, chan_id);
1030 }
1031 else {
1032
1033 fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
1034
1035 ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (none selected or out of bounds)\n");
1036 }
1037 }
1038
1039 if (!callednum || !strlen((char *)callednum->Digit)) {
1040 if (FTDM_SPAN_IS_NT(span)) {
1041 ftdm_log(FTDM_LOG_NOTICE, "No destination number found, assuming overlap dial\n");
1042 overlap_dial++;
1043 } else {
1044 ftdm_log(FTDM_LOG_ERROR, "No destination number found\n");
1045 ftdmchan = NULL;
1046 }
1047 }
1048
1049 if (ftdmchan) {
1050 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
1051 if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN || ftdm_channel_get_state(ftdmchan) >= FTDM_CHANNEL_STATE_TERMINATING)
1052 {
1053 int x = 0;
1054 ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n",
1055 ftdm_channel_get_span_id(ftdmchan),
1056 ftdm_channel_get_id(ftdmchan),
1057 ftdm_channel_get_ph_span_id(ftdmchan),
1058 ftdm_channel_get_ph_id(ftdmchan));
1059
1060 for (x = 0; x < 200; x++) {
1061 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
1062 break;
1063 }
1064 ftdm_sleep(5);
1065 }
1066 }
1067 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
1068 ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
1069 ftdm_channel_get_span_id(ftdmchan),
1070 ftdm_channel_get_id(ftdmchan),
1071 ftdm_channel_get_ph_span_id(ftdmchan),
1072 ftdm_channel_get_ph_id(ftdmchan));
1073 ftdmchan = NULL;
1074 }
1075 }
1076
1077 if (ftdmchan && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN) {
1078 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1079
1080 isdn_data->channels_remote_crv[gen->CRV] = ftdmchan;
1081 memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
1082
1083 if (ftdmchan->call_data) {
1084 memset(ftdmchan->call_data, 0, sizeof(ftdm_isdn_bchan_data_t));
1085 }
1086
1087
1088 isdn_get_number(callingnum, caller_data->cid_num.digits);
1089 isdn_get_number(callingnum, caller_data->cid_name);
1090 isdn_get_number(callingnum, caller_data->ani.digits);
1091
1092 if (!overlap_dial) {
1093 isdn_get_number(callednum, caller_data->dnis.digits);
1094 }
1095 #ifdef __TODO_OR_REMOVE__
1096 ftdmchan->caller_data.CRV = gen->CRV;
1097 #endif
1098 if (cplen > sizeof(caller_data->raw_data)) {
1099 cplen = sizeof(caller_data->raw_data);
1100 }
1101 gen->CRVFlag = !(gen->CRVFlag);
1102 memcpy(caller_data->raw_data, msg, cplen);
1103 caller_data->raw_data_len = cplen;
1104 fail = 0;
1105 }
1106 }
1107
1108 if (fail) {
1109 Q931ie_Cause cause;
1110
1111 gen->MesType = Q931mes_DISCONNECT;
1112 gen->CRVFlag = 1;
1113
1114 cause.IEId = Q931ie_CAUSE;
1115 cause.Size = sizeof(Q931ie_Cause);
1116 cause.CodStand = Q931_CODING_ITU;
1117 cause.Location = 1;
1118 cause.Recom = 1;
1119
1120 cause.Value = (unsigned char)((fail_cause) ? fail_cause : FTDM_CAUSE_WRONG_CALL_STATE);
1121 *cause.Diag = '\0';
1122 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1123 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1124
1125 if (gen->CRV) {
1126 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
1127 }
1128
1129 if (ftdmchan) {
1130 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
1131 } else {
1132 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
1133 }
1134
1135 } else {
1136 Q931ie_ChanID ChanID;
1137
1138
1139
1140
1141 Q931InitIEChanID(&ChanID);
1142 ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1;
1143 ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdmchan->span) ? 1 : 0;
1144 if (ChanID.IntType) {
1145 ChanID.InfoChanSel = 1;
1146 ChanID.ChanMapType = 3;
1147 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1148 } else {
1149 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;
1150 }
1151 gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1152
1153 if (overlap_dial) {
1154 Q931ie_ProgInd progress;
1155
1156
1157
1158
1159 progress.IEId = Q931ie_PROGRESS_INDICATOR;
1160 progress.Size = sizeof(Q931ie_ProgInd);
1161 progress.CodStand = Q931_CODING_ITU;
1162 progress.Location = 1;
1163 progress.ProgDesc = 8;
1164 gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *) &progress);
1165
1166
1167
1168
1169 gen->MesType = Q931mes_SETUP_ACKNOWLEDGE;
1170 gen->CRVFlag = 1;
1171 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1172
1173 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALTONE);
1174 } else {
1175
1176
1177
1178 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1179 }
1180 }
1181 }
1182 break;
1183
1184 case Q931mes_CALL_PROCEEDING:
1185 {
1186 if (ftdmchan) {
1187 ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1188 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
1189 } else {
1190 ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING with no matching channel %d\n", chan_id);
1191 }
1192 }
1193 break;
1194 case Q931mes_CONNECT_ACKNOWLEDGE:
1195 {
1196 if (ftdmchan) {
1197 ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1198 } else {
1199 ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK with no matching channel %d\n", chan_id);
1200 }
1201 }
1202 break;
1203
1204 case Q931mes_INFORMATION:
1205 {
1206 if (ftdmchan) {
1207 ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1208
1209 if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) {
1210 char digit = '\0';
1211
1212
1213
1214
1215 if (Q931IsIEPresent(gen->CalledNum)) {
1216 ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data;
1217 Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
1218 int pos;
1219
1220 digit = callednum->Digit[strlen((char *)callednum->Digit) - 1];
1221 if (digit == '#') {
1222 callednum->Digit[strlen((char *)callednum->Digit) - 1] = '\0';
1223 }
1224
1225
1226 pos = strlen(ftdmchan->caller_data.dnis.digits);
1227 strcat(&ftdmchan->caller_data.dnis.digits[pos], (char *)callednum->Digit);
1228
1229
1230 data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1231
1232 ftdm_log(FTDM_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, ftdmchan->caller_data.dnis.digits);
1233 }
1234
1235 if (Q931IsIEPresent(gen->SendComplete) || digit == '#') {
1236 ftdm_log(FTDM_LOG_DEBUG, "Leaving overlap dial mode\n");
1237
1238 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1239 }
1240 }
1241 } else {
1242 ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message with no matching channel\n");
1243 }
1244 }
1245 break;
1246
1247 default:
1248 ftdm_log(FTDM_LOG_CRIT, "Received unhandled message %d (%#x)\n", (int)gen->MesType, (int)gen->MesType);
1249 break;
1250 }
1251 }
1252
1253 return 0;
1254 }
1255
1256 static int ftdm_isdn_921_23(void *pvt, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *msg, L2INT mlen)
1257 {
1258 ftdm_span_t *span = pvt;
1259 ftdm_isdn_data_t *isdn_data = span->signal_data;
1260 int ret, offset = (ind == Q921_DL_DATA) ? 4 : 3;
1261 char bb[4096] = "";
1262
1263 switch(ind) {
1264 case Q921_DL_DATA:
1265 case Q921_DL_UNIT_DATA:
1266 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
1267 ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb);
1268 #ifdef HAVE_PCAP
1269 if (isdn_pcap_capture_l3only(isdn_data)) {
1270 isdn_pcap_write(isdn_data, msg, mlen, (ind == Q921_DL_UNIT_DATA) ? ISDN_PCAP_INCOMING_BCAST : ISDN_PCAP_INCOMING);
1271 }
1272 #endif
1273 default:
1274 ret = Q931Rx23(&isdn_data->q931, ind, tei, msg, mlen);
1275 if (ret != 0)
1276 ftdm_log(FTDM_LOG_DEBUG, "931 parse error [%d] [%s]\n", ret, q931_error_to_name(ret));
1277 break;
1278 }
1279
1280 return ((ret >= 0) ? 1 : 0);
1281 }
1282
1283 static int ftdm_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
1284 {
1285 ftdm_span_t *span = (ftdm_span_t *) pvt;
1286 ftdm_size_t len = (ftdm_size_t) mlen;
1287 ftdm_isdn_data_t *isdn_data = span->signal_data;
1288
1289 assert(span != NULL);
1290
1291 #ifdef HAVE_PCAP
1292 if (isdn_pcap_capture_both(isdn_data)) {
1293 isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING);
1294 }
1295 #endif
1296 return ftdm_channel_write(isdn_data->dchan, msg, len, &len) == FTDM_SUCCESS ? 0 : -1;
1297 }
1298
1299 static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
1300 {
1301 Q931mes_Generic *gen = (Q931mes_Generic *) ftdmchan->caller_data.raw_data;
1302 ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
1303 ftdm_span_t *span = ftdm_channel_get_span(ftdmchan);
1304 ftdm_sigmsg_t sig;
1305 ftdm_status_t status;
1306
1307 ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n",
1308 ftdm_channel_get_span_id(ftdmchan),
1309 ftdm_channel_get_id(ftdmchan),
1310 ftdm_channel_get_state_str(ftdmchan));
1311
1312 memset(&sig, 0, sizeof(sig));
1313 sig.span_id = ftdm_channel_get_span_id(ftdmchan);
1314 sig.chan_id = ftdm_channel_get_id(ftdmchan);
1315 sig.channel = ftdmchan;
1316
1317 switch (ftdm_channel_get_state(ftdmchan)) {
1318 case FTDM_CHANNEL_STATE_DOWN:
1319 {
1320 if (gen->CRV) {
1321 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1322 isdn_data->channels_local_crv[gen->CRV] = NULL;
1323 } else {
1324 isdn_data->channels_remote_crv[gen->CRV] = NULL;
1325 }
1326 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
1327 }
1328 ftdm_channel_close(&ftdmchan);
1329 }
1330 break;
1331 case FTDM_CHANNEL_STATE_PROGRESS:
1332 {
1333 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1334 sig.event_id = FTDM_SIGEVENT_PROGRESS;
1335 if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
1336 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1337 }
1338 } else {
1339 int crv = gen->CRV;
1340
1341 Q931InitMesGeneric(gen);
1342 gen->MesType = Q931mes_CALL_PROCEEDING;
1343 gen->CRV = crv;
1344 gen->CRVFlag = 1;
1345
1346 if (FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) {
1347 Q931ie_ChanID ChanID;
1348
1349
1350
1351
1352 Q931InitIEChanID(&ChanID);
1353 ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1;
1354 ChanID.PrefExcl = 1;
1355
1356 if (ChanID.IntType) {
1357 ChanID.InfoChanSel = 1;
1358 ChanID.ChanMapType = 3;
1359 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1360 } else {
1361 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;
1362 }
1363 gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1364 }
1365
1366 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1367 }
1368 }
1369 break;
1370 case FTDM_CHANNEL_STATE_DIALTONE:
1371 {
1372 ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data;
1373
1374 if (data) {
1375 data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1376 }
1377 }
1378 break;
1379 case FTDM_CHANNEL_STATE_RING:
1380 {
1381 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1382 sig.event_id = FTDM_SIGEVENT_START;
1383 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1384 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1385 }
1386 }
1387 }
1388 break;
1389 case FTDM_CHANNEL_STATE_RESTART:
1390 {
1391 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
1392 sig.event_id = FTDM_SIGEVENT_RESTART;
1393 status = ftdm_span_send_signal(span, &sig);
1394 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1395 }
1396 break;
1397 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
1398 {
1399 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1400 sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
1401 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1402 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1403 }
1404 } else {
1405 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1406 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1407 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1408 return;
1409 }
1410 }
1411 gen->MesType = Q931mes_ALERTING;
1412 gen->CRVFlag = 1;
1413 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1414 }
1415 }
1416 break;
1417 case FTDM_CHANNEL_STATE_UP:
1418 {
1419 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1420 sig.event_id = FTDM_SIGEVENT_UP;
1421 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1422 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1423 }
1424 } else {
1425 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1426 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1427 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1428 return;
1429 }
1430 }
1431 gen->MesType = Q931mes_CONNECT;
1432 gen->BearerCap = 0;
1433 gen->CRVFlag = 1;
1434 Q931Rx43(&isdn_data->q931, gen, ftdmchan->caller_data.raw_data_len);
1435 }
1436 }
1437 break;
1438 case FTDM_CHANNEL_STATE_DIALING:
1439 if (!(isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
1440 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1441 Q931ie_BearerCap BearerCap;
1442 Q931ie_ChanID ChanID;
1443 Q931ie_CallingNum CallingNum;
1444 Q931ie_CallingNum *ptrCallingNum;
1445 Q931ie_CalledNum CalledNum;
1446 Q931ie_CalledNum *ptrCalledNum;
1447 Q931ie_Display Display, *ptrDisplay;
1448 Q931ie_HLComp HLComp;
1449 Q931ie_ProgInd Progress;
1450 int codec = 0;
1451
1452
1453
1454
1455 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
1456
1457
1458
1459
1460 Q931InitMesGeneric(gen);
1461 gen->MesType = Q931mes_SETUP;
1462 gen->CRVFlag = 0;
1463
1464
1465
1466
1467 Q931InitIEBearerCap(&BearerCap);
1468 BearerCap.CodStand = Q931_CODING_ITU;
1469 BearerCap.ITC = Q931_ITC_SPEECH;
1470 BearerCap.TransMode = 0;
1471 BearerCap.ITR = Q931_ITR_64K;
1472 BearerCap.Layer1Ident = 1;
1473 BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? 3 : 2;
1474 gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap);
1475
1476
1477
1478
1479 Q931InitIEChanID(&ChanID);
1480 ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1;
1481 ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan)) ? 1 : 0;
1482 if (ChanID.IntType) {
1483 ChanID.InfoChanSel = 1;
1484 ChanID.ChanMapType = 3;
1485 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1486 } else {
1487 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;
1488 }
1489 gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1490
1491
1492
1493
1494 Q931InitIEProgInd(&Progress);
1495 Progress.CodStand = Q931_CODING_ITU;
1496 Progress.Location = 0;
1497 Progress.ProgDesc = 3;
1498 gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress);
1499
1500
1501
1502
1503 if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) {
1504 Q931InitIEDisplay(&Display);
1505 Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name);
1506 gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display);
1507 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
1508 ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name) + 1);
1509 }
1510
1511
1512
1513
1514 Q931InitIECallingNum(&CallingNum);
1515 CallingNum.TypNum = caller_data->ani.type;
1516 CallingNum.NumPlanID = Q931_NUMPLAN_E164;
1517 CallingNum.PresInd = Q931_PRES_ALLOWED;
1518 CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
1519 CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits);
1520 gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum);
1521 ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
1522 ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits) + 1);
1523
1524
1525
1526
1527 Q931InitIECalledNum(&CalledNum);
1528 CalledNum.TypNum = Q931_TON_UNKNOWN;
1529 CalledNum.NumPlanID = Q931_NUMPLAN_E164;
1530 CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits);
1531 gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum);
1532 ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
1533 ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits) + 1);
1534
1535
1536
1537
1538 Q931InitIEHLComp(&HLComp);
1539 HLComp.CodStand = Q931_CODING_ITU;
1540 HLComp.Interpret = 4;
1541 HLComp.PresMeth = 1;
1542 HLComp.HLCharID = Q931_HLCHAR_TELEPHONY;
1543 gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp);
1544
1545 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1546 isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
1547
1548
1549
1550
1551
1552 if (gen->CRV) {
1553 struct Q931_Call *call;
1554
1555 call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
1556 if (call) {
1557 ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
1558 Q931CallSetPrivate(call, ftdm_channel_get_span(ftdmchan));
1559 }
1560 }
1561 }
1562 break;
1563 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1564 {
1565
1566 if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP) {
1567 gen->MesType = Q931mes_RELEASE_COMPLETE;
1568
1569 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1570 }
1571 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1572 }
1573 break;
1574 case FTDM_CHANNEL_STATE_HANGUP:
1575 {
1576 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1577 Q931ie_Cause cause;
1578
1579 ftdm_log(FTDM_LOG_DEBUG, "Hangup: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1580
1581 gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1582
1583 cause.IEId = Q931ie_CAUSE;
1584 cause.Size = sizeof(Q931ie_Cause);
1585 cause.CodStand = Q931_CODING_ITU;
1586 cause.Location = 1;
1587 cause.Recom = 1;
1588
1589
1590
1591
1592
1593 if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_RING) {
1594
1595
1596
1597
1598 gen->MesType = Q931mes_RELEASE_COMPLETE;
1599
1600
1601 cause.Value = (unsigned char) caller_data->hangup_cause;
1602 *cause.Diag = '\0';
1603 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1604 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1605
1606
1607
1608 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1609 }
1610 else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) {
1611
1612
1613
1614 gen->MesType = Q931mes_RELEASE;
1615
1616 cause.Value = (unsigned char) caller_data->hangup_cause;
1617 *cause.Diag = '\0';
1618 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1619 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1620
1621
1622
1623 }
1624 else {
1625
1626
1627
1628 gen->MesType = Q931mes_DISCONNECT;
1629
1630 cause.Value = (unsigned char) caller_data->hangup_cause;
1631 *cause.Diag = '\0';
1632 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1633 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1634 }
1635 }
1636 break;
1637 case FTDM_CHANNEL_STATE_TERMINATING:
1638 {
1639 ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1640
1641 sig.event_id = FTDM_SIGEVENT_STOP;
1642 status = ftdm_span_send_signal(span, &sig);
1643
1644 gen->MesType = Q931mes_RELEASE;
1645 gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1646 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1647 }
1648 default:
1649 break;
1650 }
1651 }
1652
1653 static __inline__ void check_state(ftdm_span_t *span)
1654 {
1655 if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
1656 uint32_t j;
1657
1658 ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
1659
1660 for (j = 1; j <= ftdm_span_get_chan_count(span); j++) {
1661 ftdm_channel_t *chan = ftdm_span_get_channel(span, j);
1662
1663 if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
1664 ftdm_channel_lock(chan);
1665
1666 ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
1667 state_advance(chan);
1668 ftdm_channel_complete_state(chan);
1669
1670 ftdm_channel_unlock(chan);
1671 }
1672 }
1673 }
1674 }
1675
1676
1677 static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event)
1678 {
1679 ftdm_alarm_flag_t alarmbits;
1680 ftdm_sigmsg_t sig;
1681
1682 memset(&sig, 0, sizeof(sig));
1683 sig.span_id = ftdm_channel_get_span_id(event->channel);
1684 sig.chan_id = ftdm_channel_get_id(event->channel);
1685 sig.channel = event->channel;
1686
1687 ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
1688 ftdm_oob_event2str(event->enum_id),
1689 ftdm_channel_get_span_id(event->channel),
1690 ftdm_channel_get_id(event->channel),
1691 ftdm_channel_get_state_str(event->channel));
1692
1693 switch (event->enum_id) {
1694 case FTDM_OOB_ALARM_TRAP:
1695 {
1696 sig.event_id = FTDM_OOB_ALARM_TRAP;
1697 if (ftdm_channel_get_state(event->channel) != FTDM_CHANNEL_STATE_DOWN) {
1698 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART);
1699 }
1700 ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1701 ftdm_channel_get_alarms(event->channel, &alarmbits);
1702 ftdm_span_send_signal(span, &sig);
1703
1704 ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms [%s]\n",
1705 ftdm_channel_get_span_id(event->channel),
1706 ftdm_channel_get_id(event->channel),
1707 ftdm_channel_get_ph_span_id(event->channel),
1708 ftdm_channel_get_ph_id(event->channel),
1709 ftdm_channel_get_last_error(event->channel));
1710 }
1711 break;
1712 case FTDM_OOB_ALARM_CLEAR:
1713 {
1714 sig.event_id = FTDM_OOB_ALARM_CLEAR;
1715 ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1716 ftdm_channel_get_alarms(event->channel, &alarmbits);
1717 ftdm_span_send_signal(span, &sig);
1718 }
1719 break;
1720 #ifdef __BROKEN_BY_FREETDM_CONVERSION__
1721 case FTDM_OOB_DTMF:
1722 {
1723 const char * digit_str = (const char *)event->data;
1724
1725 if (digit_str) {
1726 fio_event_cb_t event_callback = NULL;
1727
1728 ftdm_channel_queue_dtmf(event->channel, digit_str);
1729 if (span->event_callback) {
1730 event_callback = span->event_callback;
1731 } else if (event->channel->event_callback) {
1732 event_callback = event->channel->event_callback;
1733 }
1734
1735 if (event_callback) {
1736 event->channel->event_header.channel = event->channel;
1737 event->channel->event_header.e_type = FTDM_EVENT_DTMF;
1738 event->channel->event_header.data = (void *)digit_str;
1739 event_callback(event->channel, &event->channel->event_header);
1740 event->channel->event_header.e_type = FTDM_EVENT_NONE;
1741 event->channel->event_header.data = NULL;
1742 }
1743 ftdm_safe_free(event->data);
1744 }
1745 }
1746 break;
1747 #endif
1748 }
1749
1750 return FTDM_SUCCESS;
1751 }
1752
1753
1754 static __inline__ void check_events(ftdm_span_t *span)
1755 {
1756 ftdm_status_t status = ftdm_span_poll_event(span, 5, NULL);
1757
1758 switch (status) {
1759 case FTDM_SUCCESS:
1760 {
1761 ftdm_event_t *event;
1762
1763 while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
1764 if (event->enum_id == FTDM_OOB_NOOP) {
1765 continue;
1766 }
1767 if (process_event(span, event) != FTDM_SUCCESS) {
1768 break;
1769 }
1770 }
1771 }
1772 break;
1773 case FTDM_FAIL:
1774 {
1775 ftdm_log(FTDM_LOG_DEBUG, "Event Failure! %d\n", ftdm_running());
1776 }
1777 break;
1778 default:
1779 break;
1780 }
1781 }
1782
1783
1784 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
1785 {
1786 ftdm_buffer_t *dt_buffer = ts->user_data;
1787 int wrote;
1788
1789 if (!dt_buffer) {
1790 return -1;
1791 }
1792
1793 wrote = teletone_mux_tones(ts, map);
1794 ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2);
1795 return 0;
1796 }
1797
1798 static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
1799 {
1800 ftdm_span_t *span = (ftdm_span_t *) obj;
1801 ftdm_isdn_data_t *isdn_data = span->signal_data;
1802 ftdm_buffer_t *dt_buffer = NULL;
1803 teletone_generation_session_t ts = {{{{0}}}};;
1804 unsigned char frame[1024];
1805 int x, interval;
1806 int offset = 0;
1807
1808 ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n");
1809 ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1810
1811 if (ftdm_buffer_create(&dt_buffer, 1024, 1024, 0) != FTDM_SUCCESS) {
1812 snprintf(isdn_data->dchan->last_error, sizeof(isdn_data->dchan->last_error), "memory error!");
1813 ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n");
1814 goto done;
1815 }
1816 ftdm_buffer_set_loops(dt_buffer, -1);
1817
1818
1819 for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1820 ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
1821
1822 if (ftdm_channel_get_type(chan) != FTDM_CHAN_TYPE_DQ921) {
1823 ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval);
1824 break;
1825 }
1826 }
1827 if (!interval) {
1828 interval = 20;
1829 }
1830 ftdm_log(FTDM_LOG_NOTICE, "Tone generating interval %d\n", interval);
1831
1832
1833 teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
1834 ts.rate = 8000;
1835 ts.duration = ts.rate;
1836
1837
1838 while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
1839 ftdm_wait_flag_t flags;
1840 ftdm_status_t status;
1841 int last_chan_state = 0;
1842 int gated = 0;
1843 L2ULONG now = ftdm_time_now();
1844
1845
1846
1847
1848 for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1849 ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
1850 ftdm_size_t len = sizeof(frame), rlen;
1851
1852 if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) {
1853 continue;
1854 }
1855
1856
1857
1858
1859
1860
1861 switch (ftdm_channel_get_state(chan)) {
1862 case FTDM_CHANNEL_STATE_DIALTONE:
1863 {
1864 ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)chan->call_data;
1865 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
1866
1867
1868 if (data && data->digit_timeout && data->digit_timeout <= now) {
1869 if (strlen(caller_data->dnis.digits) > 0) {
1870 ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, advancing to RING state\n");
1871 ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING);
1872 } else {
1873
1874 ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, no digits received, going to HANGUP state\n");
1875 caller_data->hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
1876 ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
1877 }
1878 data->digit_timeout = 0;
1879 continue;
1880 }
1881
1882 if (last_chan_state != ftdm_channel_get_state(chan)) {
1883 ftdm_buffer_zero(dt_buffer);
1884 teletone_run(&ts, span->tone_map[FTDM_TONEMAP_DIAL]);
1885 last_chan_state = ftdm_channel_get_state(chan);
1886 }
1887 }
1888 break;
1889
1890 case FTDM_CHANNEL_STATE_RING:
1891 {
1892 if (last_chan_state != ftdm_channel_get_state(chan)) {
1893 ftdm_buffer_zero(dt_buffer);
1894 teletone_run(&ts, span->tone_map[FTDM_TONEMAP_RING]);
1895 last_chan_state = ftdm_channel_get_state(chan);
1896 }
1897 }
1898 break;
1899
1900 default:
1901 continue;
1902 }
1903
1904 if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
1905 if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
1906 ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
1907 continue;
1908 }
1909 ftdm_log(FTDM_LOG_NOTICE, "Successfully opened channel %d:%d\n",
1910 ftdm_channel_get_span_id(chan),
1911 ftdm_channel_get_id(chan));
1912 }
1913
1914 flags = FTDM_READ;
1915
1916 status = ftdm_channel_wait(chan, &flags, (gated) ? 0 : interval);
1917 switch (status) {
1918 case FTDM_FAIL:
1919 continue;
1920
1921 case FTDM_TIMEOUT:
1922 gated = 1;
1923 continue;
1924
1925 default:
1926 if (!(flags & FTDM_READ)) {
1927 continue;
1928 }
1929 }
1930 gated = 1;
1931
1932 status = ftdm_channel_read(chan, frame, &len);
1933 if (status != FTDM_SUCCESS || len <= 0) {
1934 continue;
1935 }
1936
1937 if (chan->effective_codec != FTDM_CODEC_SLIN) {
1938 len *= 2;
1939 }
1940
1941
1942 ftdm_buffer_seek(dt_buffer, offset);
1943
1944 rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
1945
1946 if (chan->effective_codec != FTDM_CODEC_SLIN) {
1947 fio_codec_t codec_func = NULL;
1948
1949 if (chan->native_codec == FTDM_CODEC_ULAW) {
1950 codec_func = fio_slin2ulaw;
1951 } else if (chan->native_codec == FTDM_CODEC_ALAW) {
1952 codec_func = fio_slin2alaw;
1953 }
1954
1955 if (codec_func) {
1956 status = codec_func(frame, sizeof(frame), &rlen);
1957 } else {
1958 snprintf(chan->last_error, sizeof(chan->last_error), "codec error!");
1959 goto done;
1960 }
1961 }
1962 ftdm_channel_write(chan, frame, sizeof(frame), &rlen);
1963 }
1964
1965
1966
1967
1968 if (!gated) {
1969 ftdm_sleep(interval);
1970 }
1971
1972 offset += (ts.rate / (1000 / interval)) << 1;
1973 if (offset >= ts.rate) {
1974 offset = 0;
1975 }
1976 }
1977
1978 done:
1979 if (ts.buffer) {
1980 teletone_destroy_session(&ts);
1981 }
1982
1983 if (dt_buffer) {
1984 ftdm_buffer_destroy(&dt_buffer);
1985 }
1986
1987 ftdm_log(FTDM_LOG_DEBUG, "ISDN tone thread ended.\n");
1988 ftdm_clear_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1989
1990 return NULL;
1991 }
1992
1993 static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
1994 {
1995 ftdm_span_t *span = (ftdm_span_t *) obj;
1996 ftdm_isdn_data_t *isdn_data = span->signal_data;
1997 unsigned char frame[1024];
1998 ftdm_size_t len = sizeof(frame);
1999 int errs = 0;
2000
2001 #ifdef WIN32
2002 timeBeginPeriod(1);
2003 #endif
2004
2005 ftdm_log(FTDM_LOG_DEBUG, "ISDN thread starting.\n");
2006 ftdm_set_flag(isdn_data, FTDM_ISDN_RUNNING);
2007
2008 Q921Start(&isdn_data->q921);
2009 Q931Start(&isdn_data->q931);
2010
2011 while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2012 ftdm_wait_flag_t flags = FTDM_READ;
2013 ftdm_status_t status = ftdm_channel_wait(isdn_data->dchan, &flags, 100);
2014
2015 Q921TimerTick(&isdn_data->q921);
2016 Q931TimerTick(&isdn_data->q931);
2017 check_state(span);
2018 check_events(span);
2019
2020
2021
2022
2023 switch (status) {
2024 case FTDM_FAIL:
2025 {
2026 ftdm_log(FTDM_LOG_ERROR, "D-Chan Read Error!\n");
2027 snprintf(span->last_error, sizeof(span->last_error), "D-Chan Read Error!");
2028 if (++errs == 10) {
2029 isdn_data->dchan->state = FTDM_CHANNEL_STATE_UP;
2030 goto done;
2031 }
2032 }
2033 break;
2034 case FTDM_TIMEOUT:
2035 {
2036 errs = 0;
2037 }
2038 break;
2039 default:
2040 {
2041 errs = 0;
2042 if (flags & FTDM_READ) {
2043 len = sizeof(frame);
2044 if (ftdm_channel_read(isdn_data->dchan, frame, &len) == FTDM_SUCCESS) {
2045 #ifdef HAVE_PCAP
2046 if (isdn_pcap_capture_both(isdn_data)) {
2047 isdn_pcap_write(isdn_data, frame, len, ISDN_PCAP_INCOMING);
2048 }
2049 #endif
2050 Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len);
2051 Q921Rx12(&isdn_data->q921);
2052 }
2053 } else {
2054 ftdm_log(FTDM_LOG_DEBUG, "No Read FLAG!\n");
2055 }
2056 }
2057 break;
2058 }
2059 }
2060
2061 done:
2062 ftdm_channel_close(&isdn_data->dchan);
2063 ftdm_clear_flag(isdn_data, FTDM_ISDN_RUNNING);
2064
2065 #ifdef WIN32
2066 timeEndPeriod(1);
2067 #endif
2068 #ifdef HAVE_PCAP
2069 if (isdn_pcap_is_open(isdn_data)) {
2070 isdn_pcap_close(isdn_data);
2071 }
2072 #endif
2073 ftdm_log(FTDM_LOG_DEBUG, "ISDN thread ended.\n");
2074 return NULL;
2075 }
2076
2077 static int q931_rx_32(void *pvt, Q921DLMsg_t ind, L3UCHAR tei, L3UCHAR *msg, L3INT mlen)
2078 {
2079 ftdm_span_t *span = pvt;
2080 ftdm_isdn_data_t *isdn_data = span->signal_data;
2081 int offset = 4;
2082 char bb[4096] = "";
2083
2084 switch(ind) {
2085 case Q921_DL_UNIT_DATA:
2086 offset = 3;
2087
2088 case Q921_DL_DATA:
2089 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
2090 ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb);
2091 break;
2092
2093 default:
2094 break;
2095 }
2096
2097 #ifdef HAVE_PCAP
2098 if (isdn_pcap_capture_l3only(isdn_data)) {
2099 isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING);
2100 }
2101 #endif
2102 return Q921Rx32(&isdn_data->q921, ind, tei, msg, mlen);
2103 }
2104
2105 static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT size)
2106 {
2107 ftdm_span_t *span = (ftdm_span_t *) pvt;
2108
2109 ftdm_log("Span", "Q.921", span->span_id, (int)level, "%s", msg);
2110 return 0;
2111 }
2112
2113 static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, char *msg, L3INT size)
2114 {
2115 ftdm_span_t *span = (ftdm_span_t *) pvt;
2116
2117 ftdm_log("Span", "Q.931", span->span_id, (int)level, "%s", msg);
2118 return 0;
2119 }
2120
2121 static ftdm_state_map_t isdn_state_map = {
2122 {
2123 {
2124 ZSD_OUTBOUND,
2125 ZSM_UNACCEPTABLE,
2126 {FTDM_ANY_STATE},
2127 {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
2128 },
2129 {
2130 ZSD_OUTBOUND,
2131 ZSM_UNACCEPTABLE,
2132 {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
2133 {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2134 },
2135 {
2136 ZSD_OUTBOUND,
2137 ZSM_UNACCEPTABLE,
2138 {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2139 {FTDM_CHANNEL_STATE_DIALING, FTDM_END}
2140 },
2141 {
2142 ZSD_OUTBOUND,
2143 ZSM_UNACCEPTABLE,
2144 {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
2145 {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2146 },
2147 {
2148 ZSD_OUTBOUND,
2149 ZSM_UNACCEPTABLE,
2150 {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
2151 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
2152 },
2153 {
2154 ZSD_OUTBOUND,
2155 ZSM_UNACCEPTABLE,
2156 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2157 {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2158 },
2159 {
2160 ZSD_OUTBOUND,
2161 ZSM_UNACCEPTABLE,
2162 {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2163 {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2164 },
2165 {
2166 ZSD_OUTBOUND,
2167 ZSM_UNACCEPTABLE,
2168 {FTDM_CHANNEL_STATE_UP, FTDM_END},
2169 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2170 },
2171
2172
2173 {
2174 ZSD_INBOUND,
2175 ZSM_UNACCEPTABLE,
2176 {FTDM_ANY_STATE},
2177 {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
2178 },
2179 {
2180 ZSD_INBOUND,
2181 ZSM_UNACCEPTABLE,
2182 {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
2183 {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2184 },
2185 {
2186 ZSD_INBOUND,
2187 ZSM_UNACCEPTABLE,
2188 {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2189 {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_RING, FTDM_END}
2190 },
2191 {
2192 ZSD_INBOUND,
2193 ZSM_UNACCEPTABLE,
2194 {FTDM_CHANNEL_STATE_DIALTONE, FTDM_END},
2195 {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2196 },
2197 {
2198 ZSD_INBOUND,
2199 ZSM_UNACCEPTABLE,
2200 {FTDM_CHANNEL_STATE_RING, FTDM_END},
2201 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
2202 },
2203 {
2204 ZSD_INBOUND,
2205 ZSM_UNACCEPTABLE,
2206 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2207 {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2208 },
2209 {
2210 ZSD_INBOUND,
2211 ZSM_UNACCEPTABLE,
2212 {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2213 {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2214 },
2215 {
2216 ZSD_INBOUND,
2217 ZSM_UNACCEPTABLE,
2218 {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
2219 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
2220 FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
2221 },
2222 {
2223 ZSD_INBOUND,
2224 ZSM_UNACCEPTABLE,
2225 {FTDM_CHANNEL_STATE_UP, FTDM_END},
2226 {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2227 },
2228 }
2229 };
2230
2231
2232
2233
2234 static ftdm_status_t ftdm_isdn_stop(ftdm_span_t *span)
2235 {
2236 ftdm_isdn_data_t *isdn_data = span->signal_data;
2237
2238 if (!ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2239 return FTDM_FAIL;
2240 }
2241
2242 ftdm_set_flag(isdn_data, FTDM_ISDN_STOP);
2243
2244 while (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2245 ftdm_sleep(100);
2246 }
2247
2248 while (ftdm_test_flag(isdn_data, FTDM_ISDN_TONES_RUNNING)) {
2249 ftdm_sleep(100);
2250 }
2251
2252 return FTDM_SUCCESS;
2253 }
2254
2255
2256
2257
2258 static ftdm_status_t ftdm_isdn_start(ftdm_span_t *span)
2259 {
2260 ftdm_isdn_data_t *isdn_data = span->signal_data;
2261 ftdm_status_t ret;
2262
2263 if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2264 return FTDM_FAIL;
2265 }
2266
2267 ftdm_clear_flag(isdn_data, FTDM_ISDN_STOP);
2268 ret = ftdm_thread_create_detached(ftdm_isdn_run, span);
2269
2270 if (ret != FTDM_SUCCESS) {
2271 return ret;
2272 }
2273
2274 if (FTDM_SPAN_IS_NT(span) && !(isdn_data->opts & FTDM_ISDN_OPT_DISABLE_TONES)) {
2275 ret = ftdm_thread_create_detached(ftdm_isdn_tones_run, span);
2276 }
2277 return ret;
2278 }
2279
2280
2281
2282
2283
2284
2285 static int32_t parse_loglevel(const char *level)
2286 {
2287 if (!level)
2288 return -1;
2289
2290 if (!strcasecmp(level, "debug")) {
2291 return FTDM_LOG_LEVEL_DEBUG;
2292 } else if (!strcasecmp(level, "info")) {
2293 return FTDM_LOG_LEVEL_INFO;
2294 } else if (!strcasecmp(level, "notice")) {
2295 return FTDM_LOG_LEVEL_NOTICE;
2296 } else if (!strcasecmp(level, "warning")) {
2297 return FTDM_LOG_LEVEL_WARNING;
2298 } else if (!strcasecmp(level, "error")) {
2299 return FTDM_LOG_LEVEL_ERROR;
2300 } else if (!strcasecmp(level, "alert")) {
2301 return FTDM_LOG_LEVEL_ALERT;
2302 } else if (!strcasecmp(level, "crit")) {
2303 return FTDM_LOG_LEVEL_CRIT;
2304 } else if (!strcasecmp(level, "emerg")) {
2305 return FTDM_LOG_LEVEL_EMERG;
2306 } else {
2307 return -1;
2308 }
2309 }
2310
2311 static int parse_opts(const char *in, uint32_t *flags)
2312 {
2313 if (!in || !flags)
2314 return -1;
2315
2316 if (strstr(in, "suggest_channel")) {
2317 *flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL;
2318 }
2319 if (strstr(in, "omit_display")) {
2320 *flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE;
2321 }
2322 if (strstr(in, "disable_tones")) {
2323 *flags |= FTDM_ISDN_OPT_DISABLE_TONES;
2324 }
2325
2326 return 0;
2327 }
2328
2329 static int parse_dialect(const char *in, uint32_t *dialect)
2330 {
2331 if (!in || !dialect)
2332 return -1;
2333
2334 #if __UNSUPPORTED__
2335 if (!strcasecmp(in, "national")) {
2336 *dialect = Q931_Dialect_National;
2337 return 0;
2338 }
2339 if (!strcasecmp(in, "dms")) {
2340 *dialect = Q931_Dialect_DMS;
2341 return 0;
2342 }
2343 #endif
2344 if (!strcasecmp(in, "5ess")) {
2345 *dialect = Q931_Dialect_5ESS;
2346 return 0;
2347 }
2348 if (!strcasecmp(in, "dss1") || !strcasecmp(in, "euroisdn")) {
2349 *dialect = Q931_Dialect_DSS1;
2350 return 0;
2351 }
2352 if (!strcasecmp(in, "q931")) {
2353 *dialect = Q931_Dialect_Q931;
2354 return 0;
2355 }
2356
2357 return -1;
2358 }
2359
2360
2361
2362
2363
2364
2365 static const char isdn_api_usage[] =
2366 #ifdef HAVE_PCAP
2367 "isdn capture <span> <start> <filename> [q931only]\n"
2368 "isdn capture <span> <stop|suspend|resume>\n"
2369 #endif
2370 "isdn loglevel <span> <q921|q931|all> <loglevel>\n"
2371 "isdn dump <span> calls\n"
2372 "isdn help";
2373
2374
2375
2376
2377
2378 static FIO_API_FUNCTION(isdn_api)
2379 {
2380 char *mycmd = NULL, *argv[10] = { 0 };
2381 int argc = 0;
2382
2383 if (data) {
2384 mycmd = strdup(data);
2385 argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2386 }
2387
2388 if (!argc || !strcasecmp(argv[0], "help")) {
2389 stream->write_function(stream, "%s\n", isdn_api_usage);
2390 goto done;
2391 }
2392 else if (!strcasecmp(argv[0], "dump")) {
2393 ftdm_isdn_data_t *isdn_data = NULL;
2394 ftdm_span_t *span = NULL;
2395 int span_id = 0;
2396
2397
2398
2399 if (argc < 3) {
2400 stream->write_function(stream, "-ERR not enough arguments.\n");
2401 goto done;
2402 }
2403
2404 span_id = atoi(argv[1]);
2405
2406 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2407 isdn_data = span->signal_data;
2408 } else {
2409 stream->write_function(stream, "-ERR invalid span.\n");
2410 goto done;
2411 }
2412
2413 if (!strcasecmp(argv[2], "calls")) {
2414
2415 Q931DumpAllCalls(&isdn_data->q931);
2416 stream->write_function(stream, "+OK call information dumped to log\n");
2417 goto done;
2418 }
2419 }
2420 else if (!strcasecmp(argv[0], "loglevel")) {
2421 ftdm_isdn_data_t *isdn_data = NULL;
2422 ftdm_span_t *span = NULL;
2423 int span_id = 0;
2424 int layer = 0;
2425 int level = 0;
2426
2427
2428
2429 if (argc < 3) {
2430 stream->write_function(stream, "-ERR not enough arguments.\n");
2431 goto done;
2432 }
2433
2434 span_id = atoi(argv[1]);
2435
2436 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2437 isdn_data = span->signal_data;
2438 } else {
2439 stream->write_function(stream, "-ERR invalid span.\n");
2440 goto done;
2441 }
2442
2443 if (!strcasecmp(argv[2], "q921")) {
2444 layer = 0x01;
2445 } else if (!strcasecmp(argv[2], "q931")) {
2446 layer = 0x02;
2447 } else if (!strcasecmp(argv[2], "all")) {
2448 layer = 0x03;
2449 } else {
2450 stream->write_function(stream, "-ERR invalid layer\n");
2451 goto done;
2452 }
2453
2454 if (argc > 3) {
2455
2456 if ((level = parse_loglevel(argv[3])) < 0) {
2457 stream->write_function(stream, "-ERR invalid loglevel\n");
2458 goto done;
2459 }
2460
2461 if (layer & 0x01) {
2462 Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)level);
2463 }
2464 if (layer & 0x02) {
2465 Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)level);
2466 }
2467 stream->write_function(stream, "+OK loglevel set");
2468 } else {
2469
2470 if (layer & 0x01) {
2471 stream->write_function(stream, "Q.921 loglevel: %s\n",
2472 Q921GetLogLevelName(&isdn_data->q921));
2473 }
2474 if (layer & 0x02) {
2475 stream->write_function(stream, "Q.931 loglevel: %s\n",
2476 Q931GetLogLevelName(&isdn_data->q931));
2477 }
2478 stream->write_function(stream, "+OK");
2479 }
2480 goto done;
2481 }
2482 #ifdef HAVE_PCAP
2483 else if (!strcasecmp(argv[0], "capture")) {
2484 ftdm_isdn_data_t *isdn_data = NULL;
2485 ftdm_span_t *span = NULL;
2486 int span_id = 0;
2487
2488
2489
2490
2491 if (argc < 3) {
2492 stream->write_function(stream, "-ERR not enough arguments.\n");
2493 goto done;
2494 }
2495
2496 span_id = atoi(argv[1]);
2497
2498 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2499 isdn_data = span->signal_data;
2500 } else {
2501 stream->write_function(stream, "-ERR invalid span.\n");
2502 goto done;
2503 }
2504
2505 if (!strcasecmp(argv[2], "start")) {
2506 char *filename = NULL;
2507
2508 if (argc < 4) {
2509 stream->write_function(stream, "-ERR not enough parameters.\n");
2510 goto done;
2511 }
2512
2513 if (isdn_pcap_is_open(isdn_data)) {
2514 stream->write_function(stream, "-ERR capture is already running.\n");
2515 goto done;
2516 }
2517
2518 filename = argv[3];
2519
2520 if (isdn_pcap_open(isdn_data, filename) != FTDM_SUCCESS) {
2521 stream->write_function(stream, "-ERR failed to open capture file.\n");
2522 goto done;
2523 }
2524
2525 if (argc > 4 && !strcasecmp(argv[4], "q931only")) {
2526 isdn_data->flags |= FTDM_ISDN_CAPTURE_L3ONLY;
2527 }
2528 isdn_pcap_start(isdn_data);
2529
2530 stream->write_function(stream, "+OK capture started.\n");
2531 goto done;
2532 }
2533 else if (!strcasecmp(argv[2], "stop")) {
2534
2535 if (!isdn_pcap_is_open(isdn_data)) {
2536 stream->write_function(stream, "-ERR capture is not running.\n");
2537 goto done;
2538 }
2539
2540 isdn_pcap_stop(isdn_data);
2541 isdn_pcap_close(isdn_data);
2542
2543 stream->write_function(stream, "+OK capture stopped.\n");
2544 goto done;
2545 }
2546 else if (!strcasecmp(argv[2], "suspend")) {
2547
2548 if (!isdn_pcap_is_open(isdn_data)) {
2549 stream->write_function(stream, "-ERR capture is not running.\n");
2550 goto done;
2551 }
2552 isdn_pcap_stop(isdn_data);
2553
2554 stream->write_function(stream, "+OK capture suspended.\n");
2555 goto done;
2556 }
2557 else if (!strcasecmp(argv[2], "resume")) {
2558
2559 if (!isdn_pcap_is_open(isdn_data)) {
2560 stream->write_function(stream, "-ERR capture is not running.\n");
2561 goto done;
2562 }
2563 isdn_pcap_start(isdn_data);
2564
2565 stream->write_function(stream, "+OK capture resumed.\n");
2566 goto done;
2567 }
2568 else {
2569 stream->write_function(stream, "-ERR wrong action.\n");
2570 goto done;
2571 }
2572 }
2573 #endif
2574 else {
2575 stream->write_function(stream, "-ERR invalid command.\n");
2576 }
2577 done:
2578 ftdm_safe_free(mycmd);
2579
2580 return FTDM_SUCCESS;
2581 }
2582
2583 static int parse_mode(const char *mode)
2584 {
2585 if (!mode)
2586 return -1;
2587
2588 if (!strcasecmp(mode, "user") || !strcasecmp(mode, "cpe")) {
2589 return Q931_TE;
2590 }
2591 if (!strcasecmp(mode, "net") || !strcasecmp(mode, "network")) {
2592 return Q931_NT;
2593 }
2594
2595 return -1;
2596 }
2597
2598 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
2599 {
2600 Q931Dialect_t dialect = Q931_Dialect_National;
2601 ftdm_channel_t *dchan = NULL;
2602 ftdm_isdn_data_t *isdn_data;
2603 int32_t digit_timeout = 0;
2604 const char *tonemap = "us";
2605 int dchan_count = 0, bchan_count = 0;
2606 int q921loglevel = -1;
2607 int q931loglevel = -1;
2608 uint32_t i;
2609
2610 if (span->signal_type) {
2611 ftdm_log(FTDM_LOG_ERROR, "Span is already configured for signalling [%d]\n", span->signal_type);
2612 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d]", span->signal_type);
2613 return FTDM_FAIL;
2614 }
2615
2616 if (ftdm_span_get_trunk_type(span) >= FTDM_TRUNK_NONE) {
2617 ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1\n", ftdm_span_get_trunk_type_str(span));
2618 span->trunk_type = FTDM_TRUNK_T1;
2619 }
2620
2621 for (i = 1; i <= ftdm_span_get_chan_count(span); i++) {
2622 ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
2623
2624 switch (ftdm_channel_get_type(chan)) {
2625 case FTDM_CHAN_TYPE_DQ921:
2626 if (dchan_count > 1) {
2627 ftdm_log(FTDM_LOG_ERROR, "Span has more than 1 D-Channel!\n");
2628 snprintf(span->last_error, sizeof(span->last_error), "Span has more than 1 D-Channel!");
2629 return FTDM_FAIL;
2630 }
2631
2632 if (ftdm_channel_open(ftdm_span_get_id(span), i, &dchan) == FTDM_SUCCESS) {
2633 ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", dchan_count,
2634 ftdm_channel_get_span_id(dchan), ftdm_channel_get_id(dchan));
2635 dchan->state = FTDM_CHANNEL_STATE_UP;
2636 }
2637
2638 dchan_count++;
2639 break;
2640
2641 case FTDM_CHAN_TYPE_B:
2642 bchan_count++;
2643 break;
2644
2645 default:
2646 break;
2647 }
2648 }
2649 if (!dchan_count) {
2650 ftdm_log(FTDM_LOG_ERROR, "Span has no D-Channel!\n");
2651 snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channel!");
2652 return FTDM_FAIL;
2653 }
2654 if (!bchan_count) {
2655 ftdm_log(FTDM_LOG_ERROR, "Span has no B-Channels!\n");
2656 snprintf(span->last_error, sizeof(span->last_error), "Span has no B-Channels!");
2657 return FTDM_FAIL;
2658 }
2659
2660 isdn_data = malloc(sizeof(*isdn_data));
2661 assert(isdn_data != NULL);
2662 memset(isdn_data, 0, sizeof(*isdn_data));
2663
2664 isdn_data->mode = Q931_TE;
2665 dialect = Q931_Dialect_Q931;
2666
2667 for (i = 0; ftdm_parameters[i].var; i++) {
2668 const char *var = ftdm_parameters[i].var;
2669 const char *val = ftdm_parameters[i].val;
2670
2671 if (ftdm_strlen_zero(var)) {
2672 ftdm_log(FTDM_LOG_WARNING, "Skipping variable with no name\n");
2673 continue;
2674 }
2675
2676 if (ftdm_strlen_zero(val)) {
2677 ftdm_log(FTDM_LOG_ERROR, "Variable '%s' has no value\n", var);
2678 return FTDM_FAIL;
2679 }
2680
2681 if (!strcasecmp(var, "mode")) {
2682 if ((isdn_data->mode = parse_mode(val)) < 0) {
2683 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown mode '%s'\n", val);
2684 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown mode [%s]!", val);
2685 return FTDM_FAIL;
2686 }
2687 } else if (!strcasecmp(var, "dialect")) {
2688 if (parse_dialect(val, &dialect) < 0) {
2689 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown dialect '%s'\n", val);
2690 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown dialect [%s]!", val);
2691 return FTDM_FAIL;
2692 }
2693 } else if (!strcasecmp(var, "opts")) {
2694 if (parse_opts(val, &isdn_data->opts) < 0) {
2695 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown options '%s'\n", val);
2696 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown options [%s]!", val);
2697 return FTDM_FAIL;
2698 }
2699 } else if (!strcasecmp(var, "tonemap")) {
2700 tonemap = (const char *)val;
2701 } else if (!strcasecmp(var, "digit_timeout")) {
2702 digit_timeout = atoi(val);
2703 if (digit_timeout < 3000 || digit_timeout > 30000) {
2704 ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
2705 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2706 }
2707 } else if (!strcasecmp(var, "q921loglevel")) {
2708 if ((q921loglevel = parse_loglevel(val)) < 0) {
2709 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
2710 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
2711 return FTDM_FAIL;
2712 }
2713 } else if (!strcasecmp(var, "q931loglevel")) {
2714 if ((q931loglevel = parse_loglevel(val)) < 0) {
2715 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
2716 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
2717 return FTDM_FAIL;
2718 }
2719 } else {
2720 ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s'\n", var);
2721 snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
2722 return FTDM_FAIL;
2723 }
2724 }
2725
2726 if (!digit_timeout) {
2727 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2728 }
2729
2730
2731 if (isdn_data->mode == Q931_NT) {
2732 ftdm_isdn_bchan_data_t *data;
2733
2734 data = malloc(bchan_count * sizeof(ftdm_isdn_bchan_data_t));
2735 if (!data) {
2736 return FTDM_FAIL;
2737 }
2738
2739 for (i = 1; i <= ftdm_span_get_chan_count(span); i++, data++) {
2740 ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
2741
2742 if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) {
2743 chan->call_data = data;
2744 memset(data, 0, sizeof(ftdm_isdn_bchan_data_t));
2745 }
2746 }
2747 }
2748
2749 isdn_data->dchan = dchan;
2750 isdn_data->digit_timeout = digit_timeout;
2751
2752 Q921_InitTrunk(&isdn_data->q921,
2753 0,
2754 0,
2755 isdn_data->mode,
2756 (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) ? Q921_PTMP : Q921_PTP,
2757 0,
2758 ftdm_isdn_921_21,
2759 (Q921Tx23CB_t)ftdm_isdn_921_23,
2760 span,
2761 span);
2762
2763 Q921SetLogCB(&isdn_data->q921, &ftdm_isdn_q921_log, span);
2764 Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)q921loglevel);
2765
2766 Q931InitTrunk(&isdn_data->q931,
2767 dialect,
2768 isdn_data->mode,
2769 span->trunk_type,
2770 ftdm_isdn_931_34,
2771 (Q931Tx32CB_t)q931_rx_32,
2772 ftdm_isdn_931_err,
2773 span,
2774 span);
2775
2776 Q931SetLogCB(&isdn_data->q931, &ftdm_isdn_q931_log, span);
2777 Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)q931loglevel);
2778
2779
2780 Q931SetCallEventCB(&isdn_data->q931, ftdm_isdn_call_event, span);
2781
2782
2783 Q931TrunkSetAutoRestartAck(&isdn_data->q931, 1);
2784 Q931TrunkSetAutoConnectAck(&isdn_data->q931, 1);
2785 Q931TrunkSetAutoServiceAck(&isdn_data->q931, 1);
2786 Q931TrunkSetStatusEnquiry(&isdn_data->q931, 0);
2787
2788 span->state_map = &isdn_state_map;
2789 span->signal_data = isdn_data;
2790 span->signal_type = FTDM_SIGTYPE_ISDN;
2791 span->signal_cb = sig_cb;
2792 span->start = ftdm_isdn_start;
2793 span->stop = ftdm_isdn_stop;
2794 span->outgoing_call = isdn_outgoing_call;
2795
2796 span->get_channel_sig_status = isdn_get_channel_sig_status;
2797 span->get_span_sig_status = isdn_get_span_sig_status;
2798
2799 #ifdef __TODO__
2800 if ((isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
2801 span->channel_request = isdn_channel_request;
2802 span->flags |= FTDM_SPAN_SUGGEST_CHAN_ID;
2803 }
2804 #endif
2805 ftdm_span_load_tones(span, tonemap);
2806
2807 return FTDM_SUCCESS;
2808 }
2809
2810
2811
2812
2813
2814 static ftdm_io_interface_t isdn_interface = {
2815 .name = "isdn",
2816 .api = isdn_api
2817 };
2818
2819
2820
2821
2822 static FIO_IO_LOAD_FUNCTION(isdn_io_load)
2823 {
2824 assert(fio != NULL);
2825
2826 *fio = &isdn_interface;
2827
2828 return FTDM_SUCCESS;
2829 }
2830
2831
2832
2833
2834 static FIO_SIG_LOAD_FUNCTION(isdn_load)
2835 {
2836 Q931Initialize();
2837
2838 Q921SetGetTimeCB(ftdm_time_now);
2839 Q931SetGetTimeCB(ftdm_time_now);
2840
2841 return FTDM_SUCCESS;
2842 }
2843
2844
2845
2846
2847 static FIO_SIG_UNLOAD_FUNCTION(isdn_unload)
2848 {
2849 return FTDM_SUCCESS;
2850 };
2851
2852 ftdm_module_t ftdm_module = {
2853 .name = "isdn",
2854 .io_load = isdn_io_load,
2855 .io_unload = NULL,
2856 .sig_load = isdn_load,
2857 .sig_unload = isdn_unload,
2858 .configure_span_signaling = isdn_configure_span
2859 };
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870