This source file includes following definitions.
- ft_r2_clean_call
- ft_r2_accept_call
- ft_r2_answer_call
- FIO_CHANNEL_OUTGOING_CALL_FUNCTION
- ftdm_r2_start
- ftdm_r2_on_call_init
- ftdm_r2_on_call_offered
- ftdm_r2_on_call_accepted
- ftdm_r2_on_call_answered
- ftdm_r2_on_call_disconnect
- ftdm_r2_on_call_end
- ftdm_r2_on_call_read
- ftdm_r2_on_hardware_alarm
- ftdm_r2_on_os_error
- ftdm_r2_on_protocol_error
- ftdm_r2_on_line_blocked
- ftdm_r2_on_line_idle
- ftdm_r2_write_log
- ftdm_r2_on_context_log
- ftdm_r2_on_chan_log
- ftdm_r2_on_dnis_digit_received
- ftdm_r2_on_ani_digit_received
- ftdm_r2_io_set_cas
- ftdm_r2_io_get_cas
- ftdm_r2_io_flush_write_buffers
- ftdm_r2_io_write
- ftdm_r2_io_read
- ftdm_r2_io_wait
- ftdm_r2_io_open
- ftdm_r2_io_close
- ftdm_r2_io_setup
- ftdm_r2_io_get_oob_event
- FIO_SIG_CONFIGURE_FUNCTION
- ftdm_r2_channel_run
- ftdm_r2_run
- FIO_API_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
34 #include <stdio.h>
35 #include <openr2.h>
36 #include "private/ftdm_core.h"
37
38
39 static ftdm_mutex_t* g_thread_count_mutex;
40 static int32_t g_thread_count = 0;
41
42
43
44 typedef enum {
45 FTDM_R2_RUNNING = (1 << 0),
46 } ftdm_r2_flag_t;
47
48
49 #define R2CALL(ftdmchan) ((ftdm_r2_call_t*)((ftdmchan)->call_data))
50 typedef struct ftdm_r2_call_t {
51 openr2_chan_t *r2chan;
52 int accepted:1;
53 int answer_pending:1;
54 int state_ack_pending:1;
55 int disconnect_rcvd:1;
56 int ftdm_started:1;
57 ftdm_channel_state_t chanstate;
58 ftdm_size_t dnis_index;
59 ftdm_size_t ani_index;
60 char name[10];
61 } ftdm_r2_call_t;
62
63
64 typedef struct ft_r2_conf_s {
65
66 openr2_variant_t variant;
67 openr2_calling_party_category_t category;
68 openr2_log_level_t loglevel;
69
70
71 char *logdir;
72 char *advanced_protocol_file;
73
74
75 int32_t max_ani;
76 int32_t max_dnis;
77 int32_t mfback_timeout;
78 int32_t metering_pulse_timeout;
79
80
81 int immediate_accept;
82 int skip_category;
83 int get_ani_first;
84 int call_files;
85 int double_answer;
86 int charge_calls;
87 int forced_release;
88 int allow_collect_calls;
89 } ft_r2_conf_t;
90
91
92 typedef struct ftdm_r2_data_s {
93
94 ftdm_r2_flag_t flags;
95
96 openr2_context_t *r2context;
97
98 openr2_calling_party_category_t category;
99
100 int charge_calls:1;
101
102 int allow_collect_calls:1;
103
104 int forced_release:1;
105
106 int accept_on_offer:1;
107 } ftdm_r2_data_t;
108
109
110
111 typedef struct ftdm_r2_span_pvt_s {
112 openr2_context_t *r2context;
113 ftdm_hash_t *r2calls;
114 } ftdm_r2_span_pvt_t;
115
116
117 static void *ftdm_r2_run(ftdm_thread_t *me, void *obj);
118
119
120 static void *ftdm_r2_channel_run(ftdm_thread_t *me, void *obj);
121
122
123
124
125
126 static ftdm_hash_t *g_mod_data_hash;
127
128
129 static ftdm_io_interface_t g_ftdm_r2_interface;
130
131 static void ft_r2_clean_call(ftdm_r2_call_t *call)
132 {
133 openr2_chan_t *r2chan = call->r2chan;
134 memset(call, 0, sizeof(*call));
135 call->r2chan = r2chan;
136 }
137
138 static void ft_r2_accept_call(ftdm_channel_t *ftdmchan)
139 {
140 openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
141
142
143
144
145 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
146 R2CALL(ftdmchan)->accepted = 1;
147 }
148
149 static void ft_r2_answer_call(ftdm_channel_t *ftdmchan)
150 {
151 openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
152
153
154
155
156 openr2_chan_answer_call(r2chan);
157 R2CALL(ftdmchan)->answer_pending = 0;
158 }
159
160 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
161 {
162 ftdm_status_t status;
163 ftdm_mutex_lock(ftdmchan->mutex);
164
165
166 ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_INTHREAD, 200);
167
168 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
169 ftdm_log(FTDM_LOG_ERROR, "%d:%d Yay! R2 outgoing call in channel that is already in thread.\n",
170 ftdmchan->span_id, ftdmchan->chan_id);
171 ftdm_mutex_unlock(ftdmchan->mutex);
172 return FTDM_FAIL;
173 }
174
175 ft_r2_clean_call(ftdmchan->call_data);
176 R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
177 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
178 ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
179 R2CALL(ftdmchan)->ftdm_started = 1;
180 ftdm_mutex_unlock(ftdmchan->mutex);
181
182 status = ftdm_thread_create_detached(ftdm_r2_channel_run, ftdmchan);
183 if (status == FTDM_FAIL) {
184 ftdm_log(FTDM_LOG_ERROR, "%d:%d Cannot handle request to start call in channel, failed to create thread!\n",
185 ftdmchan->span_id, ftdmchan->chan_id);
186 ftdm_channel_done(ftdmchan);
187 return FTDM_FAIL;
188 }
189
190 return FTDM_SUCCESS;
191 }
192
193 static ftdm_status_t ftdm_r2_start(ftdm_span_t *span)
194 {
195 ftdm_r2_data_t *r2_data = span->signal_data;
196 ftdm_set_flag(r2_data, FTDM_R2_RUNNING);
197 return ftdm_thread_create_detached(ftdm_r2_run, span);
198 }
199
200
201 static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
202 {
203 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
204 ftdm_status_t status;
205 ftdm_log(FTDM_LOG_NOTICE, "Received request to start call on chan %d\n", openr2_chan_get_number(r2chan));
206
207 ftdm_mutex_lock(ftdmchan->mutex);
208
209 if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
210 ftdm_log(FTDM_LOG_ERROR, "Cannot handle request to start call in channel %d, invalid state (%d)\n",
211 openr2_chan_get_number(r2chan), ftdmchan->state);
212 ftdm_mutex_unlock(ftdmchan->mutex);
213 return;
214 }
215
216
217 ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_INTHREAD, 200);
218
219 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
220 ftdm_log(FTDM_LOG_ERROR, "Cannot handle request to start call in channel %d, already in thread!\n",
221 openr2_chan_get_number(r2chan));
222 ftdm_mutex_unlock(ftdmchan->mutex);
223 return;
224 }
225 ft_r2_clean_call(ftdmchan->call_data);
226 R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
227 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
228 ftdm_mutex_unlock(ftdmchan->mutex);
229
230 status = ftdm_thread_create_detached(ftdm_r2_channel_run, ftdmchan);
231 if (status == FTDM_FAIL) {
232 ftdm_log(FTDM_LOG_ERROR, "Cannot handle request to start call in channel %d, failed to create thread!\n",
233 openr2_chan_get_number(r2chan));
234 }
235 }
236
237
238 static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
239 {
240 ftdm_sigmsg_t sigev;
241 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
242
243 ftdm_log(FTDM_LOG_NOTICE, "Call offered on chan %d, ANI = %s, DNIS = %s, Category = %s\n", openr2_chan_get_number(r2chan),
244 ani, dnis, openr2_proto_get_category_string(category));
245
246
247 memset(&sigev, 0, sizeof(sigev));
248 sigev.chan_id = ftdmchan->chan_id;
249 sigev.span_id = ftdmchan->span_id;
250 sigev.channel = ftdmchan;
251 sigev.event_id = FTDM_SIGEVENT_START;
252
253 if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) {
254 ftdm_log(FTDM_LOG_NOTICE, "Failed to handle call offered on chan %d\n", openr2_chan_get_number(r2chan));
255 openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
256 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
257 return;
258 }
259 ftdm_channel_use(ftdmchan);
260 R2CALL(ftdmchan)->ftdm_started = 1;
261 }
262
263 static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
264 {
265 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
266 ftdm_log(FTDM_LOG_NOTICE, "Call accepted on chan %d\n", openr2_chan_get_number(r2chan));
267
268 openr2_chan_disable_read(r2chan);
269 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
270 R2CALL(ftdmchan)->state_ack_pending = 1;
271 if (R2CALL(ftdmchan)->answer_pending) {
272 ftdm_log(FTDM_LOG_DEBUG, "Answer was pending on chan %d, answering now.\n", openr2_chan_get_number(r2chan));
273 ft_r2_answer_call(ftdmchan);
274 return;
275 }
276 } else {
277 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
278 }
279 }
280
281 static void ftdm_r2_on_call_answered(openr2_chan_t *r2chan)
282 {
283 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
284 ftdm_log(FTDM_LOG_NOTICE, "Call answered on chan %d\n", openr2_chan_get_number(r2chan));
285
286 if (OR2_DIR_FORWARD == openr2_chan_get_direction(r2chan)) {
287 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
288 }
289 }
290
291
292 static void ftdm_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
293 {
294 ftdm_sigmsg_t sigev;
295 ftdm_r2_data_t *r2data;
296 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
297 ftdm_log(FTDM_LOG_NOTICE, "Call disconnected on chan %d\n", openr2_chan_get_number(r2chan));
298
299 ftdm_log(FTDM_LOG_DEBUG, "Got openr2 disconnection, clearing call on channel %d\n", ftdmchan->physical_chan_id);
300
301 R2CALL(ftdmchan)->disconnect_rcvd = 1;
302
303
304 openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
305
306
307 if (!R2CALL(ftdmchan)->ftdm_started) {
308 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
309 return;
310 }
311
312
313 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
314
315
316 memset(&sigev, 0, sizeof(sigev));
317 sigev.chan_id = ftdmchan->chan_id;
318 sigev.span_id = ftdmchan->span_id;
319 sigev.channel = ftdmchan;
320 sigev.event_id = FTDM_SIGEVENT_STOP;
321 r2data = ftdmchan->span->signal_data;
322
323 ftdm_span_send_signal(ftdmchan->span, &sigev);
324 }
325
326 static void ftdm_r2_on_call_end(openr2_chan_t *r2chan)
327 {
328 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
329 ftdm_log(FTDM_LOG_NOTICE, "Call finished on chan %d\n", openr2_chan_get_number(r2chan));
330
331 if (!R2CALL(ftdmchan)->disconnect_rcvd) {
332 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
333 return;
334 }
335 }
336
337 static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
338 {
339 ftdm_log(FTDM_LOG_NOTICE, "Call read data on chan %d\n", openr2_chan_get_number(r2chan));
340 }
341
342 static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
343 {
344 ftdm_log(FTDM_LOG_NOTICE, "Alarm on chan %d (%d)\n", openr2_chan_get_number(r2chan), alarm);
345 }
346
347 static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
348 {
349 ftdm_log(FTDM_LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
350 }
351
352 static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
353 {
354 ftdm_sigmsg_t sigev;
355 ftdm_r2_data_t *r2data;
356 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
357
358 ftdm_log(FTDM_LOG_ERROR, "Protocol error on chan %d\n", openr2_chan_get_number(r2chan));
359
360 R2CALL(ftdmchan)->disconnect_rcvd = 1;
361
362 if (!R2CALL(ftdmchan)->ftdm_started) {
363 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
364 return;
365 }
366
367 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_PROTOCOL_ERROR;
368
369
370 memset(&sigev, 0, sizeof(sigev));
371 sigev.chan_id = ftdmchan->chan_id;
372 sigev.span_id = ftdmchan->span_id;
373 sigev.channel = ftdmchan;
374 sigev.event_id = FTDM_SIGEVENT_STOP;
375 r2data = ftdmchan->span->signal_data;
376
377 ftdm_span_send_signal(ftdmchan->span, &sigev);
378 }
379
380 static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
381 {
382 ftdm_log(FTDM_LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
383 }
384
385 static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan)
386 {
387 ftdm_log(FTDM_LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
388 }
389
390 static void ftdm_r2_write_log(openr2_log_level_t level, const char *message)
391 {
392 switch (level) {
393 case OR2_LOG_NOTICE:
394 ftdm_log(FTDM_LOG_NOTICE, "%s", message);
395 break;
396 case OR2_LOG_WARNING:
397 ftdm_log(FTDM_LOG_WARNING, "%s", message);
398 break;
399 case OR2_LOG_ERROR:
400 ftdm_log(FTDM_LOG_ERROR, "%s", message);
401 break;
402 case OR2_LOG_STACK_TRACE:
403 case OR2_LOG_MF_TRACE:
404 case OR2_LOG_CAS_TRACE:
405 case OR2_LOG_DEBUG:
406 case OR2_LOG_EX_DEBUG:
407 ftdm_log(FTDM_LOG_DEBUG, "%s", message);
408 break;
409 default:
410 ftdm_log(FTDM_LOG_WARNING, "We should handle logging level %d here.\n", level);
411 ftdm_log(FTDM_LOG_DEBUG, "%s", message);
412 break;
413 }
414 }
415
416 static void ftdm_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
417 {
418 #define CONTEXT_TAG "Context -"
419 char logmsg[256];
420 char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1];
421 vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
422 snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg);
423 ftdm_r2_write_log(level, completemsg);
424 #undef CONTEXT_TAG
425 }
426
427 static void ftdm_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
428 {
429 #define CHAN_TAG "Chan "
430 char logmsg[256];
431 char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1];
432 vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
433 snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d: %s", openr2_chan_get_number(r2chan), logmsg);
434 ftdm_r2_write_log(level, completemsg);
435 #undef CHAN_TAG
436 }
437
438 static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
439 {
440 ftdm_sigmsg_t sigev;
441 ftdm_r2_data_t *r2data;
442 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
443 ftdm_size_t collected_len = R2CALL(ftdmchan)->dnis_index;
444
445 ftdm_log(FTDM_LOG_DEBUG, "DNIS digit %d received chan %d\n", digit, openr2_chan_get_number(r2chan));
446
447
448 ftdmchan->caller_data.dnis.digits[collected_len] = digit;
449 collected_len++;
450 ftdmchan->caller_data.dnis.digits[collected_len] = '\0';
451 R2CALL(ftdmchan)->dnis_index = collected_len;
452
453
454 memset(&sigev, 0, sizeof(sigev));
455 sigev.chan_id = ftdmchan->chan_id;
456 sigev.span_id = ftdmchan->span_id;
457 sigev.channel = ftdmchan;
458 sigev.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
459 r2data = ftdmchan->span->signal_data;
460 if (ftdm_span_send_signal(ftdmchan->span, &sigev) == FTDM_BREAK) {
461 ftdm_log(FTDM_LOG_NOTICE, "Requested to stop getting DNIS. Current DNIS = %s on chan %d\n", ftdmchan->caller_data.dnis.digits, openr2_chan_get_number(r2chan));
462 return OR2_STOP_DNIS_REQUEST;
463 }
464
465
466 if (collected_len == (sizeof(ftdmchan->caller_data.dnis.digits) - 1)) {
467 ftdm_log(FTDM_LOG_NOTICE, "No more room for DNIS. Current DNIS = %s on chan %d\n", ftdmchan->caller_data.dnis.digits, openr2_chan_get_number(r2chan));
468 return OR2_STOP_DNIS_REQUEST;
469 }
470
471 return OR2_CONTINUE_DNIS_REQUEST;
472 }
473
474 static void ftdm_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
475 {
476 ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
477 ftdm_size_t collected_len = R2CALL(ftdmchan)->ani_index;
478
479
480 if (collected_len == (sizeof(ftdmchan->caller_data.ani.digits) - 1)) {
481 ftdm_log(FTDM_LOG_NOTICE, "No more room for ANI %c on chan %d, digit dropped.\n", digit, openr2_chan_get_number(r2chan));
482 return;
483 }
484 ftdm_log(FTDM_LOG_DEBUG, "ANI digit %c received chan %d\n", digit, openr2_chan_get_number(r2chan));
485
486
487 ftdmchan->caller_data.ani.digits[collected_len++] = digit;
488 ftdmchan->caller_data.ani.digits[collected_len] = '\0';
489 }
490
491 static openr2_event_interface_t ftdm_r2_event_iface = {
492 .on_call_init = ftdm_r2_on_call_init,
493 .on_call_offered = ftdm_r2_on_call_offered,
494 .on_call_accepted = ftdm_r2_on_call_accepted,
495 .on_call_answered = ftdm_r2_on_call_answered,
496 .on_call_disconnect = ftdm_r2_on_call_disconnect,
497 .on_call_end = ftdm_r2_on_call_end,
498 .on_call_read = ftdm_r2_on_call_read,
499 .on_hardware_alarm = ftdm_r2_on_hardware_alarm,
500 .on_os_error = ftdm_r2_on_os_error,
501 .on_protocol_error = ftdm_r2_on_protocol_error,
502 .on_line_blocked = ftdm_r2_on_line_blocked,
503 .on_line_idle = ftdm_r2_on_line_idle,
504
505 .on_context_log = (openr2_handle_context_logging_func)ftdm_r2_on_context_log,
506 .on_dnis_digit_received = ftdm_r2_on_dnis_digit_received,
507 .on_ani_digit_received = ftdm_r2_on_ani_digit_received,
508
509 .on_billing_pulse_received = NULL
510 };
511
512 static int ftdm_r2_io_set_cas(openr2_chan_t *r2chan, int cas)
513 {
514 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
515 ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_SET_CAS_BITS, &cas);
516 if (FTDM_FAIL == status) {
517 return -1;
518 }
519 return 0;
520 }
521
522 static int ftdm_r2_io_get_cas(openr2_chan_t *r2chan, int *cas)
523 {
524 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
525 ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_GET_CAS_BITS, cas);
526 if (FTDM_FAIL == status) {
527 return -1;
528 }
529 return 0;
530 }
531
532 static int ftdm_r2_io_flush_write_buffers(openr2_chan_t *r2chan)
533 {
534 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
535 ftdm_status_t status = ftdm_channel_command(ftdm_chan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL);
536 if (FTDM_FAIL == status) {
537 return -1;
538 }
539 return 0;
540 }
541
542 static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size)
543 {
544 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
545 ftdm_size_t outsize = size;
546 ftdm_status_t status = ftdm_channel_write(ftdm_chan, (void *)buf, size, &outsize);
547 if (FTDM_FAIL == status) {
548 return -1;
549 }
550 return outsize;
551 }
552
553 static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size)
554 {
555 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
556 ftdm_size_t outsize = size;
557 ftdm_status_t status = ftdm_channel_read(ftdm_chan, (void *)buf, &outsize);
558 if (FTDM_FAIL == status) {
559 return -1;
560 }
561 return outsize;
562 }
563
564 static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block)
565 {
566 ftdm_status_t status;
567 ftdm_wait_flag_t ftdmflags = 0;
568
569 ftdm_channel_t *ftdm_chan = openr2_chan_get_fd(r2chan);
570 int32_t timeout = block ? -1 : 0;
571
572 if (*flags & OR2_IO_READ) {
573 ftdmflags |= FTDM_READ;
574 }
575 if (*flags & OR2_IO_WRITE) {
576 ftdmflags |= FTDM_WRITE;
577 }
578 if (*flags & OR2_IO_OOB_EVENT) {
579 ftdmflags |= FTDM_EVENTS;
580 }
581
582 status = ftdm_channel_wait(ftdm_chan, &ftdmflags, timeout);
583
584 if (FTDM_SUCCESS != status) {
585 return -1;
586 }
587
588 *flags = 0;
589 if (ftdmflags & FTDM_READ) {
590 *flags |= OR2_IO_READ;
591 }
592 if (ftdmflags & FTDM_WRITE) {
593 *flags |= OR2_IO_WRITE;
594 }
595 if (ftdmflags & FTDM_EVENTS) {
596 *flags |= OR2_IO_OOB_EVENT;
597 }
598
599 return 0;
600 }
601
602
603
604 static openr2_io_fd_t ftdm_r2_io_open(openr2_context_t *r2context, int channo)
605 {
606 ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O open)!!\n");
607 return NULL;
608 }
609
610
611 static int ftdm_r2_io_close(openr2_chan_t *r2chan)
612 {
613 ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O close)!!\n");
614 return 0;
615 }
616
617
618 static int ftdm_r2_io_setup(openr2_chan_t *r2chan)
619 {
620 ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O Setup)!!\n");
621 return 0;
622 }
623
624
625 static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *event)
626 {
627 *event = 0;
628 ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O get oob event)!!\n");
629 return 0;
630 }
631
632 static openr2_io_interface_t ftdm_r2_io_iface = {
633 .open = ftdm_r2_io_open,
634 .close = ftdm_r2_io_close,
635 .set_cas = ftdm_r2_io_set_cas,
636 .get_cas = ftdm_r2_io_get_cas,
637 .flush_write_buffers = ftdm_r2_io_flush_write_buffers,
638 .write = ftdm_r2_io_write,
639 .read = ftdm_r2_io_read,
640 .setup = ftdm_r2_io_setup,
641 .wait = ftdm_r2_io_wait,
642 .get_oob_event = ftdm_r2_io_get_oob_event
643 };
644
645 static FIO_SIG_CONFIGURE_FUNCTION(ftdm_r2_configure_span)
646
647 {
648 int i = 0;
649 int conf_failure = 0;
650 char *var = NULL;
651 char *val = NULL;
652 ftdm_r2_data_t *r2data = NULL;
653 ftdm_r2_span_pvt_t *spanpvt = NULL;
654 ftdm_r2_call_t *r2call = NULL;
655 openr2_chan_t *r2chan = NULL;
656
657 assert(sig_cb != NULL);
658
659 ft_r2_conf_t r2conf =
660 {
661 .variant = OR2_VAR_ITU,
662 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER,
663 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
664 .max_ani = 10,
665 .max_dnis = 4,
666 .mfback_timeout = -1,
667 .metering_pulse_timeout = -1,
668 .allow_collect_calls = -1,
669 .immediate_accept = -1,
670 .skip_category = -1,
671 .forced_release = -1,
672 .charge_calls = -1,
673 .get_ani_first = -1,
674 .call_files = -1,
675 .logdir = NULL,
676 .advanced_protocol_file = NULL
677 };
678
679
680 if (span->signal_type) {
681 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling.");
682 return FTDM_FAIL;
683 }
684
685 while ((var = va_arg(ap, char *))) {
686 ftdm_log(FTDM_LOG_DEBUG, "Reading R2 parameter %s for span %d\n", var, span->span_id);
687 if (!strcasecmp(var, "variant")) {
688 if (!(val = va_arg(ap, char *))) {
689 break;
690 }
691 if (ftdm_strlen_zero_buf(val)) {
692 ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 variant parameter\n");
693 continue;
694 }
695 r2conf.variant = openr2_proto_get_variant(val);
696 if (r2conf.variant == OR2_VAR_UNKNOWN) {
697 ftdm_log(FTDM_LOG_ERROR, "Unknown R2 variant %s\n", val);
698 conf_failure = 1;
699 break;
700 }
701 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d for variant %s\n", span->span_id, val);
702 } else if (!strcasecmp(var, "category")) {
703 if (!(val = va_arg(ap, char *))) {
704 break;
705 }
706 if (ftdm_strlen_zero_buf(val)) {
707 ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 category parameter\n");
708 continue;
709 }
710 r2conf.category = openr2_proto_get_category(val);
711 if (r2conf.category == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
712 ftdm_log(FTDM_LOG_ERROR, "Unknown R2 caller category %s\n", val);
713 conf_failure = 1;
714 break;
715 }
716 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with default category %s\n", span->span_id, val);
717 } else if (!strcasecmp(var, "logdir")) {
718 if (!(val = va_arg(ap, char *))) {
719 break;
720 }
721 if (ftdm_strlen_zero_buf(val)) {
722 ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 logdir parameter\n");
723 continue;
724 }
725 r2conf.logdir = val;
726 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with logdir %s\n", span->span_id, val);
727 } else if (!strcasecmp(var, "logging")) {
728 if (!(val = va_arg(ap, char *))) {
729 break;
730 }
731 if (ftdm_strlen_zero_buf(val)) {
732 ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 logging parameter\n");
733 continue;
734 }
735 openr2_log_level_t tmplevel;
736 char *clevel;
737 char *logval = ftdm_malloc(strlen(val)+1);
738 if (!logval) {
739 ftdm_log(FTDM_LOG_WARNING, "Ignoring R2 logging parameter: '%s', failed to alloc memory\n", val);
740 continue;
741 }
742 strcpy(logval, val);
743 while (logval) {
744 clevel = strsep(&logval, ",");
745 if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
746 ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid R2 logging level: '%s'\n", clevel);
747 continue;
748 }
749 r2conf.loglevel |= tmplevel;
750 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with loglevel %s\n", span->span_id, clevel);
751 }
752 ftdm_safe_free(logval);
753 } else if (!strcasecmp(var, "advanced_protocol_file")) {
754 if (!(val = va_arg(ap, char *))) {
755 break;
756 }
757 if (ftdm_strlen_zero_buf(val)) {
758 ftdm_log(FTDM_LOG_NOTICE, "Ignoring empty R2 advanced_protocol_file parameter\n");
759 continue;
760 }
761 r2conf.advanced_protocol_file = val;
762 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with advanced protocol file %s\n", span->span_id, val);
763 } else if (!strcasecmp(var, "allow_collect_calls")) {
764 r2conf.allow_collect_calls = va_arg(ap, int);
765 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with allow collect calls max ani = %d\n", span->span_id, r2conf.allow_collect_calls);
766 } else if (!strcasecmp(var, "double_answer")) {
767 r2conf.double_answer = va_arg(ap, int);
768 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with double answer = %d\n", span->span_id, r2conf.double_answer);
769 } else if (!strcasecmp(var, "immediate_accept")) {
770 r2conf.immediate_accept = va_arg(ap, int);
771 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with immediate accept = %d\n", span->span_id, r2conf.immediate_accept);
772 } else if (!strcasecmp(var, "skip_category")) {
773 r2conf.skip_category = va_arg(ap, int);
774 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with skip category = %d\n", span->span_id, r2conf.skip_category);
775 } else if (!strcasecmp(var, "forced_release")) {
776 r2conf.forced_release = va_arg(ap, int);
777 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with forced release = %d\n", span->span_id, r2conf.forced_release);
778 } else if (!strcasecmp(var, "charge_calls")) {
779 r2conf.charge_calls = va_arg(ap, int);
780 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with charge calls = %d\n", span->span_id, r2conf.charge_calls);
781 } else if (!strcasecmp(var, "get_ani_first")) {
782 r2conf.get_ani_first = va_arg(ap, int);
783 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with get ani first = %d\n", span->span_id, r2conf.get_ani_first);
784 } else if (!strcasecmp(var, "call_files")) {
785 r2conf.call_files = va_arg(ap, int);
786 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with call files = %d\n", span->span_id, r2conf.call_files);
787 } else if (!strcasecmp(var, "mfback_timeout")) {
788 r2conf.mfback_timeout = va_arg(ap, int);
789 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with MF backward timeout = %dms\n", span->span_id, r2conf.mfback_timeout);
790 } else if (!strcasecmp(var, "metering_pulse_timeout")) {
791 r2conf.metering_pulse_timeout = va_arg(ap, int);
792 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with metering pulse timeout = %dms\n", span->span_id, r2conf.metering_pulse_timeout);
793 } else if (!strcasecmp(var, "max_ani")) {
794 r2conf.max_ani = va_arg(ap, int);
795 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with max ani = %d\n", span->span_id, r2conf.max_ani);
796 } else if (!strcasecmp(var, "max_dnis")) {
797 r2conf.max_dnis = va_arg(ap, int);
798 ftdm_log(FTDM_LOG_DEBUG, "Configuring R2 span %d with max dnis = %d\n", span->span_id, r2conf.max_dnis);
799 } else {
800 snprintf(span->last_error, sizeof(span->last_error), "Unknown R2 parameter [%s]", var);
801 return FTDM_FAIL;
802 }
803 }
804
805 if (conf_failure) {
806 snprintf(span->last_error, sizeof(span->last_error), "R2 configuration error");
807 return FTDM_FAIL;
808 }
809
810 r2data = ftdm_malloc(sizeof(*r2data));
811 if (!r2data) {
812 snprintf(span->last_error, sizeof(span->last_error), "Failed to allocate R2 data.");
813 return FTDM_FAIL;
814 }
815 memset(r2data, 0, sizeof(*r2data));
816
817 spanpvt = ftdm_malloc(sizeof(*spanpvt));
818 if (!spanpvt) {
819 snprintf(span->last_error, sizeof(span->last_error), "Failed to allocate private span data container.");
820 goto fail;
821 }
822 memset(spanpvt, 0, sizeof(*spanpvt));
823
824 r2data->r2context = openr2_context_new(r2conf.variant, &ftdm_r2_event_iface, r2conf.max_ani, r2conf.max_dnis);
825 if (!r2data->r2context) {
826 snprintf(span->last_error, sizeof(span->last_error), "Cannot create openr2 context for span.");
827 goto fail;
828 }
829 openr2_context_set_io_type(r2data->r2context, OR2_IO_CUSTOM, &ftdm_r2_io_iface);
830 openr2_context_set_log_level(r2data->r2context, r2conf.loglevel);
831 openr2_context_set_ani_first(r2data->r2context, r2conf.get_ani_first);
832 openr2_context_set_skip_category_request(r2data->r2context, r2conf.skip_category);
833 openr2_context_set_mf_back_timeout(r2data->r2context, r2conf.mfback_timeout);
834 openr2_context_set_metering_pulse_timeout(r2data->r2context, r2conf.metering_pulse_timeout);
835 openr2_context_set_double_answer(r2data->r2context, r2conf.double_answer);
836 openr2_context_set_immediate_accept(r2data->r2context, r2conf.immediate_accept);
837 if (r2conf.logdir) {
838 openr2_context_set_log_directory(r2data->r2context, r2conf.logdir);
839 }
840 if (r2conf.advanced_protocol_file) {
841 openr2_context_configure_from_advanced_file(r2data->r2context, r2conf.advanced_protocol_file);
842 }
843
844 spanpvt->r2calls = create_hashtable(FTDM_MAX_CHANNELS_SPAN, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
845 if (!spanpvt->r2calls) {
846 snprintf(span->last_error, sizeof(span->last_error), "Cannot create channel calls hash for span.");
847 goto fail;
848 }
849
850 for (i = 1; (i <= span->chan_count) && (i <= FTDM_MAX_CHANNELS_SPAN); i++) {
851 r2chan = openr2_chan_new_from_fd(r2data->r2context, span->channels[i], span->channels[i]->physical_chan_id);
852 if (!r2chan) {
853 snprintf(span->last_error, sizeof(span->last_error), "Cannot create all openr2 channels for span.");
854 goto fail;
855 }
856 if (r2conf.call_files) {
857 openr2_chan_enable_call_files(r2chan);
858 openr2_chan_set_log_level(r2chan, r2conf.loglevel);
859 }
860
861 r2call = ftdm_malloc(sizeof(*r2call));
862 if (!r2call) {
863 snprintf(span->last_error, sizeof(span->last_error), "Cannot create all R2 call data structures for the span.");
864 ftdm_safe_free(r2chan);
865 goto fail;
866 }
867 memset(r2call, 0, sizeof(*r2call));
868 openr2_chan_set_logging_func(r2chan, ftdm_r2_on_chan_log);
869 openr2_chan_set_client_data(r2chan, span->channels[i]);
870 r2call->r2chan = r2chan;
871 span->channels[i]->call_data = r2call;
872
873 snprintf(r2call->name, sizeof(r2call->name), "chancall%d", i);
874 hashtable_insert(spanpvt->r2calls, (void *)r2call->name, r2call, HASHTABLE_FLAG_FREE_VALUE);
875
876 }
877 spanpvt->r2context = r2data->r2context;
878
879
880 hashtable_insert(g_mod_data_hash, (void *)span->name, spanpvt, HASHTABLE_FLAG_FREE_VALUE);
881
882 span->start = ftdm_r2_start;
883 r2data->flags = 0;
884 span->signal_cb = sig_cb;
885 span->signal_type = FTDM_SIGTYPE_R2;
886 span->signal_data = r2data;
887 span->outgoing_call = r2_outgoing_call;
888
889 return FTDM_SUCCESS;
890
891 fail:
892
893 if (r2data && r2data->r2context) {
894 openr2_context_delete(r2data->r2context);
895 }
896 if (spanpvt && spanpvt->r2calls) {
897 hashtable_destroy(spanpvt->r2calls);
898 }
899 ftdm_safe_free(r2data);
900 ftdm_safe_free(spanpvt);
901 return FTDM_FAIL;
902
903 }
904
905 static void *ftdm_r2_channel_run(ftdm_thread_t *me, void *obj)
906 {
907 ftdm_channel_t *closed_chan;
908 uint32_t interval = 0;
909 ftdm_sigmsg_t sigev;
910 ftdm_channel_t *ftdmchan = (ftdm_channel_t *)obj;
911 openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
912
913 ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD);
914
915 ftdm_mutex_lock(g_thread_count_mutex);
916 g_thread_count++;
917 ftdm_mutex_unlock(g_thread_count_mutex);
918
919 ftdm_log(FTDM_LOG_DEBUG, "R2 CHANNEL thread starting on %d in state %s.\n",
920 ftdmchan->physical_chan_id,
921 ftdm_channel_state2str(ftdmchan->state));
922
923 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
924 ftdm_log(FTDM_LOG_ERROR, "OPEN ERROR [%s]\n", ftdmchan->last_error);
925 goto endthread;
926 }
927
928 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
929
930 assert(interval != 0);
931 ftdm_log(FTDM_LOG_DEBUG, "Got %d interval for chan %d\n", interval, ftdmchan->physical_chan_id);
932
933 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
934
935 memset(ftdmchan->caller_data.dnis.digits, 0, sizeof(ftdmchan->caller_data.collected));
936 memset(ftdmchan->caller_data.ani.digits, 0, sizeof(ftdmchan->caller_data.collected));
937 }
938
939 memset(&sigev, 0, sizeof(sigev));
940 sigev.chan_id = ftdmchan->chan_id;
941 sigev.span_id = ftdmchan->span_id;
942 sigev.channel = ftdmchan;
943
944 while (ftdm_running()) {
945 int32_t read_enabled = openr2_chan_get_read_enabled(r2chan);
946 ftdm_wait_flag_t flags = read_enabled ? ( FTDM_READ | FTDM_WRITE ) : 0;
947
948 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) && (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) {
949
950 ftdm_log(FTDM_LOG_DEBUG, "Executing state handler on %d:%d for %s\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
951 R2CALL(ftdmchan)->chanstate = ftdmchan->state;
952
953 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && !R2CALL(ftdmchan)->accepted &&
954 (ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS ||
955 ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA ||
956 ftdmchan->state == FTDM_CHANNEL_STATE_UP) ) {
957
958
959
960
961 ftdm_log(FTDM_LOG_DEBUG, "State ack in chan %d:%d for state %s will have to wait a bit\n", ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
962 } else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){
963
964 ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
965 ftdm_channel_complete_state(ftdmchan);
966 }
967
968 switch (ftdmchan->state) {
969
970
971 case FTDM_CHANNEL_STATE_COLLECT:
972 {
973 ftdm_log(FTDM_LOG_DEBUG, "COLLECT: Starting processing of incoming call in channel %d with interval %d\n", ftdmchan->physical_chan_id, interval);
974 }
975 break;
976
977
978 case FTDM_CHANNEL_STATE_DIALING:
979 {
980
981 ftdm_channel_use(ftdmchan);
982 ftdm_log(FTDM_LOG_DEBUG, "DIALING: Starting processing of outgoing call in channel %d with interval %d\n", ftdmchan->physical_chan_id, interval);
983 if (openr2_chan_make_call(r2chan, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits, OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER)) {
984 ftdm_log(FTDM_LOG_ERROR, "%d:%d Failed to make call in R2 channel, openr2_chan_make_call failed\n", ftdmchan->span_id, ftdmchan->chan_id);
985 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
986 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
987 }
988 }
989 break;
990
991
992 case FTDM_CHANNEL_STATE_PROGRESS:
993 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
994 {
995 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
996 if (!R2CALL(ftdmchan)->accepted) {
997 ftdm_log(FTDM_LOG_DEBUG, "PROGRESS: Accepting call on channel %d\n", ftdmchan->physical_chan_id);
998 ft_r2_accept_call(ftdmchan);
999 }
1000 } else {
1001 ftdm_log(FTDM_LOG_DEBUG, "PROGRESS: Notifying progress in channel %d\n", ftdmchan->physical_chan_id);
1002 sigev.event_id = FTDM_SIGEVENT_PROGRESS;
1003 if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) {
1004 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1005 }
1006 }
1007 }
1008 break;
1009
1010
1011 case FTDM_CHANNEL_STATE_UP:
1012 {
1013 ftdm_log(FTDM_LOG_DEBUG, "UP: Call was answered on channel %d\n", ftdmchan->physical_chan_id);
1014 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1015 if (!R2CALL(ftdmchan)->accepted) {
1016 ftdm_log(FTDM_LOG_DEBUG, "UP: Call has not been accepted, need to accept first\n");
1017
1018 ft_r2_accept_call(ftdmchan);
1019 R2CALL(ftdmchan)->answer_pending = 1;
1020 } else {
1021 ft_r2_answer_call(ftdmchan);
1022 }
1023 } else {
1024 ftdm_log(FTDM_LOG_DEBUG, "UP: Notifying of call answered in channel %d\n", ftdmchan->physical_chan_id);
1025 sigev.event_id = FTDM_SIGEVENT_UP;
1026 if (ftdm_span_send_signal(ftdmchan->span, &sigev) != FTDM_SUCCESS) {
1027 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1028 }
1029 }
1030 }
1031 break;
1032
1033
1034 case FTDM_CHANNEL_STATE_HANGUP:
1035 {
1036
1037 ftdm_log(FTDM_LOG_DEBUG, "HANGUP: Clearing call on channel %d\n", ftdmchan->physical_chan_id);
1038 if (!R2CALL(ftdmchan)->disconnect_rcvd) {
1039
1040 openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING);
1041 } else {
1042
1043
1044 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1045 }
1046 }
1047 break;
1048
1049
1050 case FTDM_CHANNEL_STATE_CANCEL:
1051 {
1052 ftdm_log(FTDM_LOG_DEBUG, "CANCEL: Unable to receive call on channel %d\n", ftdmchan->physical_chan_id);
1053 openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
1054 }
1055 break;
1056
1057
1058 case FTDM_CHANNEL_STATE_DOWN:
1059 {
1060 ftdm_log(FTDM_LOG_DEBUG, "DOWN: Placing channel %d back to the pool of available channels\n", ftdmchan->physical_chan_id);
1061 ftdm_channel_done(ftdmchan);
1062 goto endthread;
1063 }
1064 break;
1065
1066 default:
1067 {
1068 ftdm_log(FTDM_LOG_ERROR, "%s: Unhandled channel state change in channel %d\n", ftdm_channel_state2str(ftdmchan->state), ftdmchan->physical_chan_id);
1069 }
1070 break;
1071
1072 }
1073 }
1074
1075 if (flags) {
1076 if (ftdm_channel_wait(ftdmchan, &flags, interval * 2) != FTDM_SUCCESS) {
1077 ftdm_log(FTDM_LOG_DEBUG, "ftdm_channel_wait did not return FTDM_SUCCESS\n");
1078 continue;
1079 }
1080
1081
1082 openr2_chan_run_schedule(r2chan);
1083
1084
1085
1086
1087
1088
1089 openr2_chan_process_mf_signaling(r2chan);
1090 if (R2CALL(ftdmchan)->state_ack_pending) {
1091 ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
1092 ftdm_channel_complete_state(ftdmchan);
1093 R2CALL(ftdmchan)->state_ack_pending = 0;
1094 }
1095 } else {
1096
1097 ftdm_sleep(interval);
1098 }
1099
1100 }
1101
1102 endthread:
1103
1104 closed_chan = ftdmchan;
1105 ftdm_channel_close(&closed_chan);
1106 ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INTHREAD);
1107 ftdm_log(FTDM_LOG_DEBUG, "R2 channel %d thread ended.\n", ftdmchan->physical_chan_id);
1108
1109 ftdm_mutex_lock(g_thread_count_mutex);
1110 g_thread_count--;
1111 ftdm_mutex_unlock(g_thread_count_mutex);
1112
1113 return NULL;
1114 }
1115
1116 static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
1117 {
1118 openr2_chan_t *r2chan;
1119 ftdm_status_t status;
1120 ftdm_span_t *span = (ftdm_span_t *) obj;
1121 ftdm_r2_data_t *r2data = span->signal_data;
1122 int waitms = 1000;
1123 int i;
1124
1125 ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread started.\n");
1126 r2chan = NULL;
1127 for (i = 1; i <= span->chan_count; i++) {
1128 r2chan = R2CALL(span->channels[i])->r2chan;
1129 openr2_chan_set_idle(r2chan);
1130 openr2_chan_process_cas_signaling(r2chan);
1131 }
1132
1133 while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) {
1134 status = ftdm_span_poll_event(span, waitms);
1135 if (FTDM_FAIL == status) {
1136 ftdm_log(FTDM_LOG_ERROR, "Failure Polling event! [%s]\n", span->last_error);
1137 continue;
1138 }
1139 if (FTDM_SUCCESS == status) {
1140 ftdm_event_t *event;
1141 while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
1142 if (event->enum_id == FTDM_OOB_CAS_BITS_CHANGE) {
1143 r2chan = R2CALL(event->channel)->r2chan;
1144 ftdm_log(FTDM_LOG_DEBUG, "Handling CAS on channel %d.\n", openr2_chan_get_number(r2chan));
1145
1146
1147 openr2_chan_process_cas_signaling(r2chan);
1148 } else {
1149 ftdm_log(FTDM_LOG_DEBUG, "Ignoring event %d on channel %d.\n", event->enum_id, openr2_chan_get_number(r2chan));
1150
1151 }
1152 }
1153 } else if (status != FTDM_TIMEOUT) {
1154 ftdm_log(FTDM_LOG_ERROR, "ftdm_span_poll_event returned %d.\n", status);
1155 } else {
1156
1157 }
1158 }
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 ftdm_clear_flag(r2data, FTDM_R2_RUNNING);
1169 ftdm_log(FTDM_LOG_DEBUG, "R2 thread ending.\n");
1170
1171 return NULL;
1172
1173 }
1174
1175 static FIO_API_FUNCTION(ftdm_r2_api)
1176 {
1177 char *mycmd = NULL, *argv[10] = { 0 };
1178 int argc = 0;
1179
1180 if (data) {
1181 mycmd = ftdm_strdup(data);
1182 argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
1183 }
1184
1185 if (argc == 2) {
1186 if (!strcasecmp(argv[0], "kill")) {
1187 int span_id = atoi(argv[1]);
1188 ftdm_span_t *span = NULL;
1189
1190 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
1191 ftdm_r2_data_t *r2data = span->signal_data;
1192
1193 if (span->start != ftdm_r2_start) {
1194 stream->write_function(stream, "-ERR invalid span.\n");
1195 goto done;
1196 }
1197
1198 ftdm_clear_flag(r2data, FTDM_R2_RUNNING);
1199 stream->write_function(stream, "+OK killed.\n");
1200 goto done;
1201 } else {
1202 stream->write_function(stream, "-ERR invalid span.\n");
1203 goto done;
1204 }
1205 }
1206
1207 if (!strcasecmp(argv[0], "status")) {
1208 int span_id = atoi(argv[1]);
1209 ftdm_r2_data_t *r2data = NULL;
1210 ftdm_span_t *span = NULL;
1211 openr2_chan_t *r2chan = NULL;
1212 openr2_context_t *r2context = NULL;
1213 int i = 0;
1214
1215 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
1216 if (span->start != ftdm_r2_start) {
1217 stream->write_function(stream, "-ERR not an R2 span.\n");
1218 goto done;
1219 }
1220 if (!(r2data = span->signal_data)) {
1221 stream->write_function(stream, "-ERR invalid span. No R2 singal data in span.\n");
1222 goto done;
1223 }
1224 r2context = r2data->r2context;
1225 openr2_variant_t r2variant = openr2_context_get_variant(r2context);
1226 stream->write_function(stream,
1227 "Variant: %s\n"
1228 "Max ANI: %d\n"
1229 "Max DNIS: %d\n"
1230 "ANI First: %s\n"
1231 "Immediate Accept: %s\n",
1232 openr2_proto_get_variant_string(r2variant),
1233 openr2_context_get_max_ani(r2context),
1234 openr2_context_get_max_dnis(r2context),
1235 openr2_context_get_ani_first(r2context) ? "Yes" : "No",
1236 openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
1237 stream->write_function(stream, "\n");
1238 stream->write_function(stream, "%4s %-12.12s %-12.12s\n", "Channel", "Tx CAS", "Rx CAS");
1239 for (i = 1; i <= span->chan_count; i++) {
1240 if (i == 16) continue;
1241 r2chan = R2CALL(span->channels[i])->r2chan;
1242 stream->write_function(stream, "%4d %-12.12s %-12.12s\n",
1243 span->channels[i]->physical_chan_id,
1244 openr2_chan_get_tx_cas_string(r2chan),
1245 openr2_chan_get_rx_cas_string(r2chan));
1246 }
1247 stream->write_function(stream, "\n");
1248 stream->write_function(stream, "+OK.\n");
1249 goto done;
1250 } else {
1251 stream->write_function(stream, "-ERR invalid span.\n");
1252 goto done;
1253 }
1254 }
1255
1256 }
1257
1258 if (argc == 1) {
1259 if (!strcasecmp(argv[0], "threads")) {
1260 ftdm_mutex_lock(g_thread_count_mutex);
1261 stream->write_function(stream, "%d R2 channel threads up\n", g_thread_count);
1262 ftdm_mutex_unlock(g_thread_count_mutex);
1263 stream->write_function(stream, "+OK.\n");
1264 goto done;
1265 }
1266
1267 if (!strcasecmp(argv[0], "version")) {
1268 stream->write_function(stream, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
1269 stream->write_function(stream, "+OK.\n");
1270 goto done;
1271 }
1272
1273 if (!strcasecmp(argv[0], "variants")) {
1274 int32_t numvariants = 0;
1275 const openr2_variant_entry_t *variants = openr2_proto_get_variant_list(&numvariants);
1276 if (!variants) {
1277 stream->write_function(stream, "-ERR failed to retrieve openr2 variant list.\n");
1278 goto done;
1279 }
1280 #define VARIANT_FORMAT "%4s %40s\n"
1281 stream->write_function(stream, VARIANT_FORMAT, "Variant Code", "Country");
1282 numvariants--;
1283 for (; numvariants; numvariants--) {
1284 stream->write_function(stream, VARIANT_FORMAT, variants[numvariants].name, variants[numvariants].country);
1285 }
1286 stream->write_function(stream, "+OK.\n");
1287 #undef VARIANT_FORMAT
1288 goto done;
1289 }
1290 }
1291
1292 stream->write_function(stream, "-ERR invalid command.\n");
1293
1294 done:
1295
1296 ftdm_safe_free(mycmd);
1297
1298 return FTDM_SUCCESS;
1299
1300 }
1301
1302 static FIO_IO_LOAD_FUNCTION(ftdm_r2_io_init)
1303 {
1304 assert(fio != NULL);
1305 memset(&g_ftdm_r2_interface, 0, sizeof(g_ftdm_r2_interface));
1306
1307 g_ftdm_r2_interface.name = "r2";
1308 g_ftdm_r2_interface.api = ftdm_r2_api;
1309
1310 *fio = &g_ftdm_r2_interface;
1311
1312 return FTDM_SUCCESS;
1313 }
1314
1315 static FIO_SIG_LOAD_FUNCTION(ftdm_r2_init)
1316 {
1317 g_mod_data_hash = create_hashtable(10, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
1318 if (!g_mod_data_hash) {
1319 return FTDM_FAIL;
1320 }
1321 ftdm_mutex_create(&g_thread_count_mutex);
1322 return FTDM_SUCCESS;
1323 }
1324
1325 static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy)
1326 {
1327 ftdm_hash_iterator_t *i = NULL;
1328 ftdm_r2_span_pvt_t *spanpvt = NULL;
1329 const void *key = NULL;
1330 void *val = NULL;
1331 for (i = hashtable_first(g_mod_data_hash); i; i = hashtable_next(i)) {
1332 hashtable_this(i, &key, NULL, &val);
1333 if (key && val) {
1334 spanpvt = val;
1335 openr2_context_delete(spanpvt->r2context);
1336 hashtable_destroy(spanpvt->r2calls);
1337 }
1338 }
1339 hashtable_destroy(g_mod_data_hash);
1340 ftdm_mutex_destroy(&g_thread_count_mutex);
1341 return FTDM_SUCCESS;
1342 }
1343
1344 ftdm_module_t ftdm_module = {
1345 "r2",
1346 ftdm_r2_io_init,
1347 NULL,
1348 ftdm_r2_init,
1349 ftdm_r2_configure_span,
1350 ftdm_r2_destroy
1351 };
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363