Skinny: rewrite of the skinny state machine
- for incoming calls, go CS_ROUTING only when number is dialed. CS_HIBERNATE before - start media when both side have answered Also: - send tone for UNALLOCATED_NUMBER and USER_BUSY - if channel variables are not sufficent to set call info, ask the partner channel
This commit is contained in:
parent
f8f91362f0
commit
8cc89ab042
|
@ -561,24 +561,104 @@ void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_sessi
|
||||||
switch_status_t channel_on_init(switch_core_session_t *session)
|
switch_status_t channel_on_init(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
private_t *tech_pvt = switch_core_session_get_private(session);
|
|
||||||
|
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_IO);
|
|
||||||
|
|
||||||
/* Move channel's state machine to ROUTING. This means the call is trying
|
|
||||||
to get from the initial start where the call because, to the point
|
|
||||||
where a destination has been identified. If the channel is simply
|
|
||||||
left in the initial state, nothing will happen. */
|
|
||||||
switch_channel_set_state(channel, CS_ROUTING);
|
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL INIT\n", switch_channel_get_name(channel));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL INIT\n", switch_channel_get_name(channel));
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct channel_on_routing_helper {
|
||||||
|
private_t *tech_pvt;
|
||||||
|
listener_t *listener;
|
||||||
|
uint32_t line_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
int channel_on_routing_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||||
|
{
|
||||||
|
struct channel_on_routing_helper *helper = pArg;
|
||||||
|
listener_t *listener = NULL;
|
||||||
|
|
||||||
|
char *device_name = argv[0];
|
||||||
|
uint32_t device_instance = atoi(argv[1]);
|
||||||
|
/* uint32_t position = atoi(argv[2]); */
|
||||||
|
uint32_t line_instance = atoi(argv[3]);
|
||||||
|
/* char *label = argv[4]; */
|
||||||
|
/* char *value = argv[5]; */
|
||||||
|
/* char *caller_name = argv[6]; */
|
||||||
|
/* uint32_t ring_on_idle = atoi(argv[7]); */
|
||||||
|
/* uint32_t ring_on_active = atoi(argv[8]); */
|
||||||
|
/* uint32_t busy_trigger = atoi(argv[9]); */
|
||||||
|
/* char *forward_all = argv[10]; */
|
||||||
|
/* char *forward_busy = argv[11]; */
|
||||||
|
/* char *forward_noanswer = argv[12]; */
|
||||||
|
/* uint32_t noanswer_duration = atoi(argv[13]); */
|
||||||
|
/* char *channel_uuid = argv[14]; */
|
||||||
|
/* uint32_t call_id = atoi(argv[15]); */
|
||||||
|
/* uint32_t call_state = atoi(argv[16]); */
|
||||||
|
|
||||||
|
skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener);
|
||||||
|
if(listener) {
|
||||||
|
if(!strcmp(device_name, helper->listener->device_name)
|
||||||
|
&& (device_instance == helper->listener->device_instance)
|
||||||
|
&& (line_instance == helper->line_instance)) {/* the calling line */
|
||||||
|
helper->tech_pvt->caller_profile->dialplan = switch_core_strdup(helper->tech_pvt->caller_profile->pool, listener->profile->dialplan);
|
||||||
|
helper->tech_pvt->caller_profile->context = switch_core_strdup(helper->tech_pvt->caller_profile->pool, listener->profile->context);
|
||||||
|
send_dialed_number(listener, helper->tech_pvt->caller_profile->destination_number, line_instance, helper->tech_pvt->call_id);
|
||||||
|
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_PROCEED);
|
||||||
|
skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
|
||||||
|
} else {
|
||||||
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
||||||
|
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
|
||||||
|
send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0xffff);
|
||||||
|
send_display_prompt_status(listener, 0, SKINNY_DISP_IN_USE_REMOTE,
|
||||||
|
line_instance, helper->tech_pvt->call_id);
|
||||||
|
skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch_status_t channel_on_routing(switch_core_session_t *session)
|
switch_status_t channel_on_routing(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
||||||
|
skinny_action_t action;
|
||||||
|
private_t *tech_pvt = switch_core_session_get_private(session);
|
||||||
|
char *data = NULL;
|
||||||
|
listener_t *listener = NULL;
|
||||||
|
struct channel_on_routing_helper helper = {0};
|
||||||
|
|
||||||
|
if(switch_test_flag(tech_pvt, TFLAG_FORCE_ROUTE)) {
|
||||||
|
action = SKINNY_ACTION_ROUTE;
|
||||||
|
switch_clear_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE);
|
||||||
|
} else {
|
||||||
|
action = skinny_session_dest_match_pattern(session, &data);
|
||||||
|
}
|
||||||
|
switch(action) {
|
||||||
|
case SKINNY_ACTION_ROUTE:
|
||||||
|
skinny_profile_find_listener_by_device_name_and_instance(tech_pvt->profile,
|
||||||
|
switch_channel_get_variable(channel, "skinny_device_name"),
|
||||||
|
atoi(switch_channel_get_variable(channel, "skinny_device_instance")), &listener);
|
||||||
|
if (listener) {
|
||||||
|
helper.tech_pvt = tech_pvt;
|
||||||
|
helper.listener = listener;
|
||||||
|
helper.line_instance = atoi(switch_channel_get_variable(channel, "skinny_line_instance"));
|
||||||
|
skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), channel_on_routing_callback, &helper);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Could not find listener %s:%s for Channel %s\n",
|
||||||
|
switch_channel_get_variable(channel, "skinny_device_name"), switch_channel_get_variable(channel, "skinny_device_instance"),
|
||||||
|
switch_channel_get_name(channel));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SKINNY_ACTION_WAIT:
|
||||||
|
/* for now, wait forever */
|
||||||
|
switch_channel_set_state(channel, CS_HIBERNATE);
|
||||||
|
break;
|
||||||
|
case SKINNY_ACTION_DROP:
|
||||||
|
default:
|
||||||
|
switch_channel_hangup(channel, SWITCH_CAUSE_UNALLOCATED_NUMBER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
|
||||||
|
|
||||||
|
@ -591,7 +671,6 @@ switch_status_t channel_on_execute(switch_core_session_t *session)
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
|
||||||
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,11 +730,14 @@ int channel_on_hangup_callback(void *pArg, int argc, char **argv, char **columnN
|
||||||
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF);
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF);
|
||||||
switch (helper->cause) {
|
switch (helper->cause) {
|
||||||
case SWITCH_CAUSE_UNALLOCATED_NUMBER:
|
case SWITCH_CAUSE_UNALLOCATED_NUMBER:
|
||||||
|
send_start_tone(listener, SKINNY_TONE_REORDER, 0, line_instance, call_id);
|
||||||
|
skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
|
||||||
send_display_prompt_status(listener, 0, SKINNY_DISP_UNKNOWN_NUMBER, line_instance, call_id);
|
send_display_prompt_status(listener, 0, SKINNY_DISP_UNKNOWN_NUMBER, line_instance, call_id);
|
||||||
break;
|
break;
|
||||||
case SWITCH_CAUSE_USER_BUSY:
|
case SWITCH_CAUSE_USER_BUSY:
|
||||||
|
send_start_tone(listener, SKINNY_TONE_BUSYTONE, 0, line_instance, call_id);
|
||||||
send_display_prompt_status(listener, 0, SKINNY_DISP_BUSY, line_instance, call_id);
|
send_display_prompt_status(listener, 0, SKINNY_DISP_BUSY, line_instance, call_id);
|
||||||
break;
|
break;
|
||||||
case SWITCH_CAUSE_NORMAL_CLEARING:
|
case SWITCH_CAUSE_NORMAL_CLEARING:
|
||||||
send_clear_prompt_status(listener, line_instance, call_id);
|
send_clear_prompt_status(listener, line_instance, call_id);
|
||||||
break;
|
break;
|
||||||
|
@ -842,6 +924,20 @@ switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame
|
||||||
|
|
||||||
switch_status_t channel_answer_channel(switch_core_session_t *session)
|
switch_status_t channel_answer_channel(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
private_t *tech_pvt = switch_core_session_get_private(session);
|
||||||
|
listener_t *listener = NULL;
|
||||||
|
|
||||||
|
skinny_profile_find_listener_by_device_name_and_instance(tech_pvt->profile,
|
||||||
|
switch_channel_get_variable(channel, "skinny_device_name"),
|
||||||
|
atoi(switch_channel_get_variable(channel, "skinny_device_instance")), &listener);
|
||||||
|
if (listener) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Bli!\n");
|
||||||
|
skinny_session_start_media(session, listener, atoi(switch_channel_get_variable(channel, "skinny_line_instance")));
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Unable to find listener to answer %s:%s\n",
|
||||||
|
switch_channel_get_variable(channel, "skinny_device_name"), switch_channel_get_variable(channel, "skinny_device_instance"));
|
||||||
|
}
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,7 +1021,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi
|
||||||
tech_pvt->caller_profile = caller_profile;
|
tech_pvt->caller_profile = caller_profile;
|
||||||
|
|
||||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
|
|
||||||
|
|
||||||
if ((sql = switch_mprintf(
|
if ((sql = switch_mprintf(
|
||||||
"INSERT INTO skinny_active_lines "
|
"INSERT INTO skinny_active_lines "
|
||||||
|
|
|
@ -146,8 +146,6 @@ typedef switch_status_t (*skinny_listener_callback_func_t) (listener_t *listener
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TFLAG_IO = (1 << 0),
|
TFLAG_IO = (1 << 0),
|
||||||
TFLAG_INBOUND = (1 << 1),
|
|
||||||
TFLAG_OUTBOUND = (1 << 2),
|
|
||||||
TFLAG_DTMF = (1 << 3),
|
TFLAG_DTMF = (1 << 3),
|
||||||
TFLAG_VOICE = (1 << 4),
|
TFLAG_VOICE = (1 << 4),
|
||||||
TFLAG_HANGUP = (1 << 5),
|
TFLAG_HANGUP = (1 << 5),
|
||||||
|
@ -155,7 +153,8 @@ typedef enum {
|
||||||
TFLAG_CODEC = (1 << 7),
|
TFLAG_CODEC = (1 << 7),
|
||||||
|
|
||||||
TFLAG_READING = (1 << 9),
|
TFLAG_READING = (1 << 9),
|
||||||
TFLAG_WRITING = (1 << 10)
|
TFLAG_WRITING = (1 << 10),
|
||||||
|
TFLAG_FORCE_ROUTE = (1 << 11)
|
||||||
} TFLAGS;
|
} TFLAGS;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -242,6 +242,15 @@ switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, s
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_status_t skinny_set_channel_variables(switch_channel_t *channel, listener_t *listener, uint32_t line_instance)
|
||||||
|
{
|
||||||
|
switch_channel_set_variable(channel, "skinny_profile_name", listener->profile->name);
|
||||||
|
switch_channel_set_variable(channel, "skinny_device_name", listener->device_name);
|
||||||
|
switch_channel_set_variable_printf(channel, "skinny_device_instance", "%d", listener->device_instance);
|
||||||
|
switch_channel_set_variable_printf(channel, "skinny_line_instance", "%d", line_instance);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data)
|
switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data)
|
||||||
|
@ -916,8 +925,9 @@ switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file
|
||||||
ptr = (char *) reply;
|
ptr = (char *) reply;
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG,
|
||||||
"Sending %s (type=%x,length=%d).\n",
|
"Sending %s (type=%x,length=%d) to %s:%d.\n",
|
||||||
skinny_message_type2str(reply->type), reply->type, reply->length);
|
skinny_message_type2str(reply->type), reply->type, reply->length,
|
||||||
|
listener->device_name, listener->device_instance);
|
||||||
switch_socket_send(listener->sock, ptr, &len);
|
switch_socket_send(listener->sock, ptr, &len);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
|
@ -637,6 +637,7 @@ char* skinny_codec2string(enum skinny_codecs skinnycodec);
|
||||||
switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req);
|
switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req);
|
||||||
|
|
||||||
switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name);
|
switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, switch_event_types_t event_id, const char *subclass_name);
|
||||||
|
switch_status_t skinny_set_channel_variables(switch_channel_t *channel, listener_t *listener, uint32_t line_instance);
|
||||||
|
|
||||||
switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data);
|
switch_status_t skinny_session_walk_lines(skinny_profile_t *profile, char *channel_uuid, switch_core_db_callback_func_t callback, void *data);
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l
|
||||||
snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name,
|
snprintf(name, sizeof(name), "SKINNY/%s/%s:%d/%d", listener->profile->name,
|
||||||
listener->device_name, listener->device_instance, *line_instance_p);
|
listener->device_name, listener->device_instance, *line_instance_p);
|
||||||
switch_channel_set_name(channel, name);
|
switch_channel_set_name(channel, name);
|
||||||
|
skinny_set_channel_variables(channel, listener, *line_instance_p);
|
||||||
|
|
||||||
if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_thread_launch(nsession) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT,
|
||||||
|
@ -163,6 +164,12 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l
|
||||||
send_display_prompt_status(listener, 0, "\200\000",
|
send_display_prompt_status(listener, 0, "\200\000",
|
||||||
*line_instance_p, tech_pvt->call_id);
|
*line_instance_p, tech_pvt->call_id);
|
||||||
send_activate_call_plane(listener, *line_instance_p);
|
send_activate_call_plane(listener, *line_instance_p);
|
||||||
|
if (switch_channel_get_state(channel) == CS_NEW) {
|
||||||
|
switch_channel_set_state(channel, CS_HIBERNATE);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT,
|
||||||
|
"Wow! this channel should be in CS_NEW state, but it is not!\n");
|
||||||
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
error:
|
error:
|
||||||
|
@ -246,60 +253,10 @@ found:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct skinny_session_process_dest_helper {
|
|
||||||
private_t *tech_pvt;
|
|
||||||
listener_t *listener;
|
|
||||||
uint32_t line_instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
int skinny_session_process_dest_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
||||||
{
|
|
||||||
struct skinny_session_process_dest_helper *helper = pArg;
|
|
||||||
listener_t *listener = NULL;
|
|
||||||
|
|
||||||
char *device_name = argv[0];
|
|
||||||
uint32_t device_instance = atoi(argv[1]);
|
|
||||||
/* uint32_t position = atoi(argv[2]); */
|
|
||||||
uint32_t line_instance = atoi(argv[3]);
|
|
||||||
/* char *label = argv[4]; */
|
|
||||||
/* char *value = argv[5]; */
|
|
||||||
/* char *caller_name = argv[6]; */
|
|
||||||
/* uint32_t ring_on_idle = atoi(argv[7]); */
|
|
||||||
/* uint32_t ring_on_active = atoi(argv[8]); */
|
|
||||||
/* uint32_t busy_trigger = atoi(argv[9]); */
|
|
||||||
/* char *forward_all = argv[10]; */
|
|
||||||
/* char *forward_busy = argv[11]; */
|
|
||||||
/* char *forward_noanswer = argv[12]; */
|
|
||||||
/* uint32_t noanswer_duration = atoi(argv[13]); */
|
|
||||||
/* char *channel_uuid = argv[14]; */
|
|
||||||
/* uint32_t call_id = atoi(argv[15]); */
|
|
||||||
/* uint32_t call_state = atoi(argv[16]); */
|
|
||||||
|
|
||||||
skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener);
|
|
||||||
if(listener) {
|
|
||||||
if(!strcmp(device_name, helper->listener->device_name)
|
|
||||||
&& (device_instance == helper->listener->device_instance)
|
|
||||||
&& (line_instance == helper->line_instance)) {/* the calling line */
|
|
||||||
/* nothing */
|
|
||||||
} else {
|
|
||||||
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
|
||||||
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
|
|
||||||
send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0xffff);
|
|
||||||
send_display_prompt_status(listener, 0, SKINNY_DISP_IN_USE_REMOTE,
|
|
||||||
line_instance, helper->tech_pvt->call_id);
|
|
||||||
skinny_session_send_call_info(helper->tech_pvt->session, listener, line_instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace)
|
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace)
|
||||||
{
|
{
|
||||||
skinny_action_t action;
|
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
private_t *tech_pvt = NULL;
|
private_t *tech_pvt = NULL;
|
||||||
char *data = NULL;
|
|
||||||
struct skinny_session_process_dest_helper helper = {0};
|
|
||||||
|
|
||||||
switch_assert(session);
|
switch_assert(session);
|
||||||
switch_assert(listener);
|
switch_assert(listener);
|
||||||
|
@ -333,34 +290,10 @@ switch_status_t skinny_session_process_dest(switch_core_session_t *session, list
|
||||||
} else {
|
} else {
|
||||||
tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool,
|
tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool,
|
||||||
dest);
|
dest);
|
||||||
|
switch_set_flag_locked(tech_pvt, TFLAG_FORCE_ROUTE);
|
||||||
}
|
}
|
||||||
if(dest) {
|
|
||||||
action = SKINNY_ACTION_ROUTE;
|
|
||||||
} else {
|
|
||||||
action = skinny_session_dest_match_pattern(session, &data);
|
|
||||||
}
|
|
||||||
switch(action) {
|
|
||||||
case SKINNY_ACTION_ROUTE:
|
|
||||||
tech_pvt->caller_profile->dialplan = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->dialplan);
|
|
||||||
tech_pvt->caller_profile->context = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->context);
|
|
||||||
send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id);
|
|
||||||
skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED);
|
|
||||||
skinny_session_send_call_info(session, listener, line_instance);
|
|
||||||
|
|
||||||
skinny_session_start_media(session, listener, line_instance);
|
switch_channel_set_state(channel, CS_ROUTING);
|
||||||
|
|
||||||
helper.tech_pvt = tech_pvt;
|
|
||||||
helper.listener = listener;
|
|
||||||
helper.line_instance = line_instance;
|
|
||||||
skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_process_dest_callback, &helper);
|
|
||||||
break;
|
|
||||||
case SKINNY_ACTION_WAIT:
|
|
||||||
/* for now, wait forever */
|
|
||||||
break;
|
|
||||||
case SKINNY_ACTION_DROP:
|
|
||||||
default:
|
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_UNALLOCATED_NUMBER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -383,20 +316,28 @@ switch_status_t skinny_session_send_call_info(switch_core_session_t *session, li
|
||||||
|
|
||||||
/* Calling party */
|
/* Calling party */
|
||||||
if (zstr((caller_party_name = switch_channel_get_variable(channel, "effective_caller_id_name"))) &&
|
if (zstr((caller_party_name = switch_channel_get_variable(channel, "effective_caller_id_name"))) &&
|
||||||
zstr((caller_party_name = switch_channel_get_variable(channel, "caller_id_name")))) {
|
zstr((caller_party_name = switch_channel_get_variable(channel, "caller_id_name"))) &&
|
||||||
|
zstr((caller_party_name = switch_channel_get_variable_partner(channel, "effective_caller_id_name"))) &&
|
||||||
|
zstr((caller_party_name = switch_channel_get_variable_partner(channel, "caller_id_name")))) {
|
||||||
caller_party_name = SWITCH_DEFAULT_CLID_NAME;
|
caller_party_name = SWITCH_DEFAULT_CLID_NAME;
|
||||||
}
|
}
|
||||||
if (zstr((caller_party_number = switch_channel_get_variable(channel, "effective_caller_id_number"))) &&
|
if (zstr((caller_party_number = switch_channel_get_variable(channel, "effective_caller_id_number"))) &&
|
||||||
zstr((caller_party_number = switch_channel_get_variable(channel, "caller_id_number")))) {
|
zstr((caller_party_number = switch_channel_get_variable(channel, "caller_id_number"))) &&
|
||||||
|
zstr((caller_party_number = switch_channel_get_variable_partner(channel, "effective_caller_id_number"))) &&
|
||||||
|
zstr((caller_party_number = switch_channel_get_variable_partner(channel, "caller_id_number")))) {
|
||||||
caller_party_number = "0000000000";
|
caller_party_number = "0000000000";
|
||||||
}
|
}
|
||||||
/* Called party */
|
/* Called party */
|
||||||
if (zstr((called_party_name = switch_channel_get_variable(channel, "effective_callee_id_name"))) &&
|
if (zstr((called_party_name = switch_channel_get_variable(channel, "effective_callee_id_name"))) &&
|
||||||
zstr((called_party_name = switch_channel_get_variable(channel, "callee_id_name")))) {
|
zstr((called_party_name = switch_channel_get_variable(channel, "callee_id_name"))) &&
|
||||||
|
zstr((called_party_name = switch_channel_get_variable_partner(channel, "effective_callee_id_name"))) &&
|
||||||
|
zstr((called_party_name = switch_channel_get_variable_partner(channel, "callee_id_name")))) {
|
||||||
called_party_name = SWITCH_DEFAULT_CLID_NAME;
|
called_party_name = SWITCH_DEFAULT_CLID_NAME;
|
||||||
}
|
}
|
||||||
if (zstr((called_party_number = switch_channel_get_variable(channel, "effective_callee_id_number"))) &&
|
if (zstr((called_party_number = switch_channel_get_variable(channel, "effective_callee_id_number"))) &&
|
||||||
zstr((called_party_number = switch_channel_get_variable(channel, "callee_id_number"))) &&
|
zstr((called_party_number = switch_channel_get_variable(channel, "callee_id_number"))) &&
|
||||||
|
zstr((called_party_number = switch_channel_get_variable_partner(channel, "effective_callee_id_number"))) &&
|
||||||
|
zstr((called_party_number = switch_channel_get_variable_partner(channel, "callee_id_number"))) &&
|
||||||
zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) {
|
zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) {
|
||||||
called_party_number = "0000000000";
|
called_party_number = "0000000000";
|
||||||
}
|
}
|
||||||
|
@ -615,6 +556,9 @@ switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t
|
||||||
|
|
||||||
skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_answer_callback, &helper);
|
skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_answer_callback, &helper);
|
||||||
|
|
||||||
|
if (switch_channel_get_state(channel) == CS_INIT) {
|
||||||
|
switch_channel_set_state(channel, CS_ROUTING);
|
||||||
|
}
|
||||||
skinny_session_start_media(session, listener, line_instance);
|
skinny_session_start_media(session, listener, line_instance);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -763,6 +707,8 @@ switch_status_t skinny_session_stop_media(switch_core_session_t *session, listen
|
||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
|
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||||
|
|
||||||
send_close_receive_channel(listener,
|
send_close_receive_channel(listener,
|
||||||
tech_pvt->call_id, /* uint32_t conference_id, */
|
tech_pvt->call_id, /* uint32_t conference_id, */
|
||||||
tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
||||||
|
@ -1565,10 +1511,12 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
|
||||||
0 /* uint32_t g723_bitrate */
|
0 /* uint32_t g723_bitrate */
|
||||||
);
|
);
|
||||||
|
|
||||||
if (switch_channel_get_state(channel) == CS_NEW) {
|
switch_set_flag_locked(tech_pvt, TFLAG_IO);
|
||||||
switch_channel_set_state(channel, CS_INIT);
|
|
||||||
}
|
|
||||||
switch_channel_mark_answered(channel);
|
switch_channel_mark_answered(channel);
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||||
|
"Unable to find session for device %s:%d (call id=%d).\n",
|
||||||
|
listener->device_name, listener->device_instance, request->data.open_receive_channel_ack.pass_thru_party_id);
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
if(session) {
|
if(session) {
|
||||||
|
@ -1819,7 +1767,8 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_
|
||||||
switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
|
switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request)
|
||||||
{
|
{
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||||
"Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
|
"Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length,
|
||||||
|
listener->device_name, listener->device_instance);
|
||||||
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) {
|
if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
"Device should send a register message first.\n");
|
"Device should send a register message first.\n");
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
/* SESSION FUNCTIONS */
|
/* SESSION FUNCTIONS */
|
||||||
switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance, switch_core_session_t **session);
|
switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *line_instance, switch_core_session_t **session);
|
||||||
|
skinny_action_t skinny_session_dest_match_pattern(switch_core_session_t *session, char **data);
|
||||||
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace);
|
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace);
|
||||||
switch_status_t skinny_session_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
switch_status_t skinny_session_send_call_info(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
||||||
switch_call_cause_t skinny_ring_lines(private_t *tech_pvt);
|
switch_call_cause_t skinny_ring_lines(private_t *tech_pvt);
|
||||||
|
|
Loading…
Reference in New Issue