/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines that allocate memory or you will have 1 channel with memory allocated from another channel's pool! */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { if ((*new_session = switch_core_session_request(reference_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { private_t *tech_pvt; switch_channel_t *channel; switch_caller_profile_t *caller_profile; 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); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), 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), "REFERENCE/%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; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Doh! no caller profile\n"); switch_core_session_destroy(new_session); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } 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; }
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { char name[128]; if (session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_clear_flag(channel, CF_PROXY_MEDIA); switch_channel_clear_flag(channel, CF_PROXY_MODE); switch_channel_pre_answer(channel); } if ((*new_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) { private_t *tech_pvt; switch_channel_t *channel; switch_caller_profile_t *caller_profile; 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); switch_snprintf(name, sizeof(name), "loopback/%s-a", outbound_profile->destination_number); switch_channel_set_name(channel, name); if (tech_init(tech_pvt, *new_session, session ? switch_core_session_get_read_codec(session) : NULL) != SWITCH_STATUS_SUCCESS) { switch_core_session_destroy(new_session); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), 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 *dialplan = NULL, *context = NULL; caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); caller_profile->source = switch_core_strdup(caller_profile->pool, modname); if (!strncasecmp(caller_profile->destination_number, "app=", 4)) { char *dest = switch_core_session_strdup(*new_session, caller_profile->destination_number); char *app = dest + 4; char *arg = NULL; if ((arg = strchr(app, ':'))) { *arg++ = '\0'; } switch_channel_set_variable(channel, "loopback_app", app); if (arg) { switch_channel_set_variable(channel, "loopback_app_arg", arg); } caller_profile->destination_number = switch_core_strdup(caller_profile->pool, app); } if ((context = strchr(caller_profile->destination_number, '/'))) { *context++ = '\0'; if ((dialplan = strchr(context, '/'))) { *dialplan++ = '\0'; } if (!zstr(context)) { caller_profile->context = switch_core_strdup(caller_profile->pool, context); } if (!zstr(dialplan)) { caller_profile->dialplan = switch_core_strdup(caller_profile->pool, dialplan); } } if (zstr(caller_profile->context)) { caller_profile->context = switch_core_strdup(caller_profile->pool, "default"); } if (zstr(caller_profile->dialplan)) { caller_profile->dialplan = switch_core_strdup(caller_profile->pool, "xml"); } switch_snprintf(name, sizeof(name), "loopback/%s-a", caller_profile->destination_number); switch_channel_set_name(channel, name); switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Doh! no caller profile\n"); switch_core_session_destroy(new_session); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } switch_channel_set_state(channel, CS_INIT); return SWITCH_CAUSE_SUCCESS; } return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; }
/* State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel, *b_channel; private_t *tech_pvt = NULL, *b_tech_pvt = NULL; switch_core_session_t *b_session; char name[128]; switch_caller_profile_t *caller_profile; tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_BLEG)) { if (!(b_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n"); goto end; } if (switch_core_session_read_lock(b_session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n"); switch_core_session_destroy(&b_session); goto end; } switch_core_session_add_stream(b_session, NULL); b_channel = switch_core_session_get_channel(b_session); b_tech_pvt = (private_t *) switch_core_session_alloc(b_session, sizeof(*b_tech_pvt)); switch_snprintf(name, sizeof(name), "loopback/%s-b", tech_pvt->caller_profile->destination_number); switch_channel_set_name(b_channel, name); if (tech_init(b_tech_pvt, b_session, switch_core_session_get_read_codec(session)) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_core_session_destroy(&b_session); goto end; } caller_profile = switch_caller_profile_clone(b_session, tech_pvt->caller_profile); caller_profile->source = switch_core_strdup(caller_profile->pool, modname); switch_channel_set_caller_profile(b_channel, caller_profile); b_tech_pvt->caller_profile = caller_profile; switch_channel_set_state(b_channel, CS_INIT); tech_pvt->other_session = b_session; tech_pvt->other_tech_pvt = b_tech_pvt; tech_pvt->other_channel = b_channel; //b_tech_pvt->other_session = session; //b_tech_pvt->other_tech_pvt = tech_pvt; //b_tech_pvt->other_channel = channel; b_tech_pvt->other_uuid = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session)); switch_set_flag_locked(tech_pvt, TFLAG_LINKED); switch_set_flag_locked(b_tech_pvt, TFLAG_LINKED); switch_set_flag_locked(b_tech_pvt, TFLAG_BLEG); switch_channel_set_flag(channel, CF_ACCEPT_CNG); //switch_ivr_transfer_variable(session, tech_pvt->other_session, "process_cdr"); switch_ivr_transfer_variable(session, tech_pvt->other_session, NULL); switch_channel_set_variable(channel, "other_loopback_leg_uuid", switch_channel_get_uuid(b_channel)); switch_channel_set_variable(b_channel, "other_loopback_leg_uuid", switch_channel_get_uuid(channel)); if (switch_core_session_thread_launch(b_session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n"); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; } } else if ((tech_pvt->other_session = switch_core_session_locate(tech_pvt->other_uuid))) { tech_pvt->other_tech_pvt = switch_core_session_get_private(tech_pvt->other_session); tech_pvt->other_channel = switch_core_session_get_channel(tech_pvt->other_session); } if (!tech_pvt->other_session) { switch_clear_flag_locked(tech_pvt, TFLAG_LINKED); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; } switch_channel_set_variable(channel, "loopback_leg", switch_test_flag(tech_pvt, TFLAG_BLEG) ? "B" : "A"); switch_channel_set_state(channel, CS_ROUTING); end: return SWITCH_STATUS_SUCCESS; }
WSChannel* WSClientParser::CreateCall( switch_core_session_t *session, const char *profileName, const char *profileContext, const char *profileDialplan, const char* ip ) { WSChannel *wsChannel = NULL; switch_memory_pool_t *pool = NULL; switch_channel_t* channel = NULL; switch_caller_profile_t *caller_profile = NULL; char *user = mpUser; char *domain = mpDomain; const char *destNumber = mpDestNumber; const char *context = NULL; const char *dialplan = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_log_printf( SWITCH_CHANNEL_UUID_LOG(this->GetUUID()), SWITCH_LOG_INFO, "WSClientParser::CreateCall( " "this : %p, " "profileName : '%s', " "profileContext : '%s', " "profileDialplan : '%s', " "ip : '%s' " ") \n", this, profileName, profileContext, profileDialplan, ip ); // 参数不能为空 if ( !user || !domain || !destNumber ) { status = SWITCH_STATUS_FALSE; } // 不允许一个连接创建多个会话 if( status == SWITCH_STATUS_SUCCESS && mpChannel ) { status = SWITCH_STATUS_FALSE; } if( status == SWITCH_STATUS_SUCCESS ) { pool = switch_core_session_get_pool(session); channel = switch_core_session_get_channel(session); switch_channel_set_name( channel, switch_core_session_sprintf(session, "ws/%s/%s/%s", profileName, user, destNumber) ); } // if ( status == SWITCH_STATUS_SUCCESS && !zstr(user) && !zstr(domain)) { // // 拨号不做验证 // const char *ivrUser = switch_core_session_sprintf(session, "%s@%s", user, domain); // status = switch_ivr_set_user(session, ivrUser); // } if( status == SWITCH_STATUS_SUCCESS ) { if (!(context = switch_channel_get_variable(channel, "user_context"))) { if (!(context = profileContext)) { context = "public"; } } if (!(dialplan = switch_channel_get_variable(channel, "inbound_dialplan"))) { if (!(dialplan = profileDialplan)) { dialplan = "LUA"; } } // switch_log_printf( // SWITCH_CHANNEL_SESSION_LOG(session), // SWITCH_LOG_NOTICE, // "WSClientParser::CreateCall( " // "context : %s, " // "dialplan : %s " // ") \n", // context, // dialplan // ); // 设置主叫 caller_profile = switch_caller_profile_new( pool, switch_str_nil(user), dialplan, SWITCH_DEFAULT_CLID_NAME, !zstr(user) ? user : SWITCH_DEFAULT_CLID_NUMBER, ip /* net addr */, NULL /* ani */, NULL /* anii */, NULL /* rdnis */, "mod_ws", context, destNumber ); switch_channel_set_caller_profile(channel, caller_profile); switch_core_session_add_stream(session, NULL); switch_channel_set_variable(channel, "caller", user); switch_channel_set_state(channel, CS_INIT); wsChannel = CreateChannel(session); } if( wsChannel ) { switch_log_printf( SWITCH_CHANNEL_UUID_LOG(this->GetUUID()), SWITCH_LOG_INFO, "WSClientParser::CreateCall( " "[Success], " "this : %p, " "wsChannel : %p, " "profileName : '%s', " "profileContext : '%s', " "profileDialplan : '%s', " "ip : '%s' " ") \n", this, wsChannel, profileName, profileContext, profileDialplan, ip ); } else { switch_log_printf( SWITCH_CHANNEL_UUID_LOG(this->GetUUID()), SWITCH_LOG_ERROR, "WSClientParser::CreateCall( " "[Fail], " "this : %p " ") \n", this, profileName, profileContext, profileDialplan, ip ); } return wsChannel; }
/* State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel, *b_channel; private_t *tech_pvt = NULL, *b_tech_pvt = NULL; switch_core_session_t *b_session; char name[128]; switch_caller_profile_t *caller_profile; switch_event_t *vars = NULL; const char *var; tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_BLEG)) { if (!(b_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n"); goto end; } if (switch_core_session_read_lock(b_session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n"); switch_core_session_destroy(&b_session); goto end; } switch_core_session_add_stream(b_session, NULL); b_channel = switch_core_session_get_channel(b_session); b_tech_pvt = (private_t *) switch_core_session_alloc(b_session, sizeof(*b_tech_pvt)); switch_snprintf(name, sizeof(name), "loopback/%s-b", tech_pvt->caller_profile->destination_number); switch_channel_set_name(b_channel, name); if (tech_init(b_tech_pvt, b_session, switch_core_session_get_read_codec(session)) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_core_session_destroy(&b_session); goto end; } caller_profile = switch_caller_profile_clone(b_session, tech_pvt->caller_profile); caller_profile->source = switch_core_strdup(caller_profile->pool, modname); switch_channel_set_caller_profile(b_channel, caller_profile); b_tech_pvt->caller_profile = caller_profile; switch_channel_set_state(b_channel, CS_INIT); tech_pvt->other_session = b_session; tech_pvt->other_tech_pvt = b_tech_pvt; tech_pvt->other_channel = b_channel; //b_tech_pvt->other_session = session; //b_tech_pvt->other_tech_pvt = tech_pvt; //b_tech_pvt->other_channel = channel; b_tech_pvt->other_uuid = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session)); switch_set_flag_locked(tech_pvt, TFLAG_LINKED); switch_set_flag_locked(b_tech_pvt, TFLAG_LINKED); switch_set_flag_locked(b_tech_pvt, TFLAG_BLEG); switch_channel_set_flag(channel, CF_ACCEPT_CNG); if ((vars = (switch_event_t *) switch_channel_get_private(channel, "__loopback_vars__"))) { switch_event_header_t *h; switch_channel_set_private(channel, "__loopback_vars__", NULL); for (h = vars->headers; h; h = h->next) { switch_channel_set_variable(tech_pvt->other_channel, h->name, h->value); } switch_event_destroy(&vars); } if ((var = switch_channel_get_variable(channel, "loopback_export"))) { int argc = 0; char *argv[128] = { 0 }; char *dup = switch_core_session_strdup(session, var); if ((argc = switch_split(dup, ',', argv))) { int i; for (i = 0; i < argc; i++) { if (!zstr(argv[i])) { const char *val = switch_channel_get_variable(channel, argv[i]); if(!zstr(val)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer variable [%s]=[%s] %s -> %s\n", argv[i], val, switch_channel_get_name(channel), switch_channel_get_name(tech_pvt->other_channel)); switch_channel_set_variable(tech_pvt->other_channel, argv[i], val); } } } } } if (switch_test_flag(tech_pvt, TFLAG_APP)) { switch_set_flag(b_tech_pvt, TFLAG_APP); switch_clear_flag(tech_pvt, TFLAG_APP); } switch_channel_set_variable(channel, "other_loopback_leg_uuid", switch_channel_get_uuid(b_channel)); switch_channel_set_variable(b_channel, "other_loopback_leg_uuid", switch_channel_get_uuid(channel)); if (switch_core_session_thread_launch(b_session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n"); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; } } else if ((tech_pvt->other_session = switch_core_session_locate(tech_pvt->other_uuid))) { tech_pvt->other_tech_pvt = switch_core_session_get_private(tech_pvt->other_session); tech_pvt->other_channel = switch_core_session_get_channel(tech_pvt->other_session); } if (!tech_pvt->other_session) { switch_clear_flag_locked(tech_pvt, TFLAG_LINKED); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; } switch_channel_set_variable(channel, "loopback_leg", switch_test_flag(tech_pvt, TFLAG_BLEG) ? "B" : "A"); switch_channel_set_state(channel, CS_ROUTING); end: return SWITCH_STATUS_SUCCESS; }
static switch_status_t create_session(switch_core_session_t **new_session, modem_t *modem) { switch_status_t status = SWITCH_STATUS_FALSE; switch_core_session_t *session; switch_channel_t *channel; private_t *tech_pvt = NULL; char name[1024]; switch_caller_profile_t *caller_profile; char *ani = NULL, *p, *digits = NULL; if (!(session = switch_core_session_request(modem_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n"); goto end; } switch_core_session_add_stream(session, NULL); channel = switch_core_session_get_channel(session); tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(*tech_pvt)); p = switch_core_session_strdup(session, modem->digits); if (*p == '*') { ani = p + 1; if ((digits = strchr(ani, '*'))) { *digits++ = '\0'; } else { ani = NULL; } } if (zstr(digits)) { digits = p; } if (zstr(ani)) { ani = modem->devlink + 5; } switch_snprintf(name, sizeof(name), "modem/%d/%s", modem->slot, digits); switch_channel_set_name(channel, name); if (tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_core_session_destroy(&session); goto end; } caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), modem->devlink, spandsp_globals.modem_dialplan, "FSModem", ani, NULL, ani, NULL, NULL, "mod_spandsp", spandsp_globals.modem_context, digits); caller_profile->source = switch_core_strdup(caller_profile->pool, "mod_spandsp"); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n"); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; } status = SWITCH_STATUS_SUCCESS; tech_attach(tech_pvt, modem); *new_session = session; end: return status; }
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { char name[128]; switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; if ((*new_session = switch_core_session_request(modem_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { private_t *tech_pvt; switch_channel_t *channel; switch_caller_profile_t *caller_profile; char *dest = switch_core_session_strdup(*new_session, outbound_profile->destination_number); char *modem_id_string = NULL; char *number = NULL; int modem_id = 0; modem_t *modem = NULL; if ((modem_id_string = dest)) { if ((number = strchr(modem_id_string, '/'))) { *number++ = '\0'; } } if (zstr(modem_id_string) || zstr(number)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Invalid dial string.\n"); cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT; goto fail; } if (!strcasecmp(modem_id_string, "a")) { modem_id = -1; } else { modem_id = atoi(modem_id_string); } if (!(modem = acquire_modem(modem_id))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Cannot find a modem.\n"); cause = SWITCH_CAUSE_USER_BUSY; goto fail; } 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); switch_snprintf(name, sizeof(name), "modem/%d/%s", modem->slot, number); switch_channel_set_name(channel, name); if (tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } switch_set_string(modem->digits, number); tech_attach(tech_pvt, modem); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } if (outbound_profile) { caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); caller_profile->source = switch_core_strdup(caller_profile->pool, "mod_spandsp"); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Doh! no caller profile\n"); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } switch_channel_set_state(channel, CS_INIT); return SWITCH_CAUSE_SUCCESS; fail: if (new_session) { switch_core_session_destroy(new_session); } if (modem) { modem_set_state(modem, MODEM_STATE_ONHOOK); } } return cause; }