typedef enum {
TFLAG_IO = (1 << 0),
- TFLAG_OUTBOUND = (1 << 1),
- TFLAG_DTMF = (1 << 2),
- TFLAG_CODEC = (1 << 3),
- TFLAG_BREAK = (1 << 4),
- TFLAG_HOLD = (1 << 5)
+ TFLAG_DTMF = (1 << 1),
+ TFLAG_CODEC = (1 << 2),
+ TFLAG_BREAK = (1 << 3),
+ TFLAG_HOLD = (1 << 4)
} TFLAGS;
static struct {
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool)
{
+
+ char *dest;
+ int span_id = 0;
+ zap_channel_t *zchan = NULL;
+ switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ char name[128];
+
+ if (!outbound_profile) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n");
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
+
+ if ((dest = strchr('/', outbound_profile->destination_number))) {
+ dest++;
+ span_id = atoi(outbound_profile->destination_number);
+ }
+
+ if (!span_id) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing span\n");
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
+
+ if (zap_channel_open_any(span_id, ZAP_TOP_DOWN, &zchan) != ZAP_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels available\n");
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
+
if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) {
private_t *tech_pvt;
switch_channel_t *channel;
switch_core_session_add_stream(*new_session, NULL);
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
channel = switch_core_session_get_channel(*new_session);
- tech_init(tech_pvt, *new_session, NULL);
+ tech_init(tech_pvt, *new_session, zchan);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
switch_core_session_destroy(new_session);
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- }
-
- if (outbound_profile) {
- char name[128];
-
- snprintf(name, sizeof(name), "OPENZAP/%s-%04x", outbound_profile->destination_number, rand() & 0xffff);
- switch_channel_set_name(channel, name);
-
- caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
- switch_channel_set_caller_profile(channel, caller_profile);
- tech_pvt->caller_profile = caller_profile;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
- switch_core_session_destroy(new_session);
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ goto fail;
}
+ snprintf(name, sizeof(name), "OPENZAP/%s", outbound_profile->destination_number);
+ switch_channel_set_name(channel, name);
+
+ caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
+ switch_channel_set_caller_profile(channel, caller_profile);
+ tech_pvt->caller_profile = caller_profile;
+
switch_channel_set_flag(channel, CF_OUTBOUND);
- switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT);
return SWITCH_CAUSE_SUCCESS;
}
- return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+
+ fail:
+ if (zchan) {
+ zap_channel_done(zchan);
+ }
+ return cause;
}
break;
case ZAP_CHANNEL_STATE_DOWN:
{
+ zap_channel_done(chan);
goto done;
}
break;
switch(chan->state) {
case ZAP_CHANNEL_STATE_UP:
{
+ zap_channel_use(chan);
if (zap_test_flag(chan, ZAP_CHANNEL_HOLD)) {
zap_clear_flag(chan, ZAP_CHANNEL_HOLD);
sig.event_id = ZAP_SIGEVENT_FLASH;
break;
case ZAP_CHANNEL_STATE_IDLE:
{
+ zap_channel_use(chan);
sig.event_id = ZAP_SIGEVENT_START;
zap_copy_string(sig.dnis, dtmf, sizeof(sig.dnis));
data->sig_cb(&sig);
break;
case ZAP_CHANNEL_STATE_DOWN:
{
+ zap_channel_done(chan);
sig.event_id = ZAP_SIGEVENT_STOP;
data->sig_cb(&sig);
goto done;
break;
case ZAP_CHANNEL_STATE_DIALTONE:
{
+ zap_channel_done(chan);
*dtmf = '\0';
dtmf_offset = 0;
zap_buffer_zero(dt_buffer);
break;
case ZAP_CHANNEL_STATE_RING:
{
+ zap_channel_done(chan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, chan->span->tone_map[ZAP_TONEMAP_RING]);
indicate = 1;
break;
case ZAP_CHANNEL_STATE_BUSY:
{
+ zap_channel_done(chan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, chan->span->tone_map[ZAP_TONEMAP_BUSY]);
indicate = 1;
break;
case ZAP_CHANNEL_STATE_ATTN:
{
+ zap_channel_done(chan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, chan->span->tone_map[ZAP_TONEMAP_ATTN]);
indicate = 1;
}
break;
default:
+ zap_channel_done(chan);
break;
}
}