diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 1ab90a8c4c..12473fa775 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -381,13 +381,19 @@ switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) return status; } -void tech_init(private_t *tech_pvt, switch_core_session_t *session) +void tech_init(private_t *tech_pvt, switch_core_session_t *session, listener_t *listener, uint32_t line) { + switch_assert(tech_pvt); + switch_assert(session); + switch_assert(listener); + tech_pvt->read_frame.data = tech_pvt->databuf; tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - tech_pvt->call_id = 12345; /* TODO */ + tech_pvt->call_id = listener->profile->next_call_id++; + tech_pvt->listener = listener; + tech_pvt->line = line; switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; } @@ -508,16 +514,25 @@ switch_status_t channel_on_hangup(switch_core_session_t *session) stop_tone(listener, tech_pvt->line, tech_pvt->call_id); set_lamp(listener, SKINNY_BUTTON_LINE, tech_pvt->line, SKINNY_LAMP_OFF); clear_prompt_status(listener, tech_pvt->line, tech_pvt->call_id); - close_receive_channel(listener, - tech_pvt->call_id, /* uint32_t conference_id, */ - tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ - tech_pvt->call_id /* uint32_t conference_id2, */ - ); - stop_media_transmission(listener, - tech_pvt->call_id, /* uint32_t conference_id, */ - tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ - tech_pvt->call_id /* uint32_t conference_id2, */ - ); + + if( skinny_line_get_state(tech_pvt->listener, tech_pvt->line) == SKINNY_KEY_SET_CONNECTED ) { + close_receive_channel(listener, + tech_pvt->call_id, /* uint32_t conference_id, */ + tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ + tech_pvt->call_id /* uint32_t conference_id2, */ + ); + stop_media_transmission(listener, + tech_pvt->call_id, /* uint32_t conference_id, */ + tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ + tech_pvt->call_id /* uint32_t conference_id2, */ + ); + switch_mutex_lock(globals.calls_mutex); + globals.calls--; + if (globals.calls < 0) { + globals.calls = 0; + } + switch_mutex_unlock(globals.calls_mutex); + } send_call_state(listener, SKINNY_ON_HOOK, tech_pvt->line, @@ -526,14 +541,6 @@ switch_status_t channel_on_hangup(switch_core_session_t *session) /* TODO: DefineTimeDate */ set_speaker_mode(listener, SKINNY_SPEAKER_OFF); set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0); - - - switch_mutex_lock(globals.calls_mutex); - globals.calls--; - if (globals.calls < 0) { - globals.calls = 0; - } - switch_mutex_unlock(globals.calls_mutex); return SWITCH_STATUS_SUCCESS; } @@ -551,12 +558,12 @@ switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) switch (sig) { case SWITCH_SIG_KILL: - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); break; case SWITCH_SIG_BREAK: - switch_set_flag_locked(tech_pvt, TFLAG_BREAK); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_break(tech_pvt->rtp_session); + } break; default: break; @@ -748,6 +755,8 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi char *profile_name, *dest; skinny_profile_t *profile = NULL; + listener_t *listener = NULL; + uint32_t line = 0; char name[128]; switch_channel_t *channel; switch_caller_profile_t *caller_profile; @@ -767,8 +776,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi goto error; } - tech_init(tech_pvt, nsession); - if(!(profile_name = switch_core_session_strdup(nsession, outbound_profile->destination_number))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error Creating Session Info\n"); goto error; @@ -794,6 +801,26 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi switch_channel_set_name(channel, name); + if ((skinny_profile_find_listener(profile, dest, &listener, &line) != SWITCH_STATUS_SUCCESS)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Problem while retrieving listener and line for destination %s in profile %s\n", dest, profile_name); + cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; + goto error; + } + + if (!listener) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid destination or phone not registred %s in profile %s\n", dest, profile_name); + cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; + goto error; + } + + if (line == 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid destination or phone not registred %s in profile %s\n", dest, profile_name); + cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; + goto error; + } + + tech_init(tech_pvt, nsession, listener, line); + caller_profile = switch_caller_profile_clone(nsession, outbound_profile); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; @@ -801,24 +828,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi switch_channel_set_flag(channel, CF_OUTBOUND); switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); - if ((skinny_profile_find_listener(profile, dest, &tech_pvt->listener, &tech_pvt->line) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Problem while retrieving listener and line for destination %s in profile %s\n", dest, profile_name); - cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; - goto error; - } - - if (!tech_pvt->listener) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid destination or phone not registred %s in profile %s\n", dest, profile_name); - cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; - goto error; - } - - if (tech_pvt->line == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid destination or phone not registred %s in profile %s\n", dest, profile_name); - cause = SWITCH_CAUSE_UNALLOCATED_NUMBER; - goto error; - } - if(tech_pvt->listener->session[tech_pvt->line]) { /* Line is busy */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Device line is busy %s in profile %s\n", dest, profile_name); cause = SWITCH_CAUSE_USER_BUSY; @@ -1424,8 +1433,6 @@ static switch_status_t load_skinny_config(void) skinny_execute_sql_callback(profile, profile->listener_mutex, "DELETE FROM skinny_devices", NULL, NULL); skinny_execute_sql_callback(profile, profile->listener_mutex, "DELETE FROM skinny_buttons", NULL, NULL); - switch_core_hash_init(&profile->session_hash, module_pool); - switch_core_hash_insert(globals.profile_hash, profile->name, profile); profile = NULL; } else { diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 9169cd2b07..62e75d2b9d 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -92,9 +92,8 @@ struct skinny_profile { switch_mutex_t *sock_mutex; struct listener *listeners; uint8_t listener_ready; - /* sessions */ - switch_hash_t *session_hash; - switch_mutex_t *sessions_mutex; + /* call id */ + uint32_t next_call_id; }; typedef struct skinny_profile skinny_profile_t; @@ -143,7 +142,6 @@ typedef enum { TFLAG_HANGUP = (1 << 5), TFLAG_LINEAR = (1 << 6), TFLAG_CODEC = (1 << 7), - TFLAG_BREAK = (1 << 8), TFLAG_READING = (1 << 9), TFLAG_WRITING = (1 << 10) @@ -209,7 +207,7 @@ uint32_t skinny_line_perform_set_state(listener_t *listener, const char *file, c uint32_t skinny_line_get_state(listener_t *listener, uint32_t instance); switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force); -void tech_init(private_t *tech_pvt, switch_core_session_t *session); +void tech_init(private_t *tech_pvt, switch_core_session_t *session, listener_t *listener, uint32_t line); switch_status_t channel_on_init(switch_core_session_t *session); switch_status_t channel_on_hangup(switch_core_session_t *session); switch_status_t channel_on_destroy(switch_core_session_t *session); diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 9874177775..2bb8b14484 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -272,6 +272,7 @@ char* skinny_codec2string(enum skinny_codecs skinnycodec) } } +/*****************************************************************************/ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) { skinny_message_t *request; @@ -355,6 +356,7 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) return SWITCH_STATUS_SUCCESS; } +/*****************************************************************************/ int skinny_device_event_callback(void *pArg, int argc, char **argv, char **columnNames) { switch_event_t *event = (switch_event_t *) pArg; @@ -399,6 +401,7 @@ switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, s return SWITCH_STATUS_SUCCESS; } +/*****************************************************************************/ switch_status_t skinny_send_call_info(switch_core_session_t *session) { private_t *tech_pvt; @@ -435,11 +438,15 @@ switch_status_t skinny_send_call_info(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_pick_up(listener_t *listener, uint32_t line) +/*****************************************************************************/ +switch_status_t skinny_create_session(listener_t *listener, uint32_t line, uint32_t to_state) { switch_core_session_t *session; switch_channel_t *channel; private_t *tech_pvt; + char *cid_name = "TODO-soft_key_event"; /* TODO set form the line*/ + char *cid_num = "00000"; /* TODO set form the line */ + char name[128]; if (!(session = switch_core_session_request(skinny_get_endpoint_interface(), SWITCH_CALL_DIRECTION_INBOUND, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); @@ -453,10 +460,25 @@ switch_status_t skinny_pick_up(listener_t *listener, uint32_t line) switch_core_session_add_stream(session, NULL); - tech_pvt->listener = listener; - tech_pvt->line = line; + tech_init(tech_pvt, session, listener, line); - tech_init(tech_pvt, session); + channel = switch_core_session_get_channel(session); + + snprintf(name, sizeof(name), "SKINNY/%s/%s/%d", listener->profile->name, listener->device_name, tech_pvt->line); + switch_channel_set_name(channel, name); + + if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error Creating Session thread\n"); + goto error; + } + + if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), + NULL, listener->profile->dialplan, cid_name, cid_num, listener->remote_ip, NULL, NULL, NULL, "skinny" /* modname */, listener->profile->context, tech_pvt->dest)) != 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error Creating Session caller profile\n"); + goto error; + } + + switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0); set_speaker_mode(listener, SKINNY_SPEAKER_ON); @@ -465,7 +487,7 @@ switch_status_t skinny_pick_up(listener_t *listener, uint32_t line) SKINNY_OFF_HOOK, tech_pvt->line, tech_pvt->call_id); - skinny_line_set_state(listener, tech_pvt->line, SKINNY_KEY_SET_OFF_HOOK, tech_pvt->call_id); + skinny_line_set_state(listener, tech_pvt->line, to_state, tech_pvt->call_id); display_prompt_status(listener, 0, "\200\000", @@ -474,7 +496,6 @@ switch_status_t skinny_pick_up(listener_t *listener, uint32_t line) activate_call_plane(listener, tech_pvt->line); start_tone(listener, SKINNY_TONE_DIALTONE, 0, tech_pvt->line, tech_pvt->call_id); - channel = switch_core_session_get_channel(session); goto done; error: if (session) { @@ -488,6 +509,29 @@ done: return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_process_dest(listener_t *listener, uint32_t line) +{ + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + channel = switch_core_session_get_channel(listener->session[line]); + assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(listener->session[line]); + assert(tech_pvt != NULL); + + tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, tech_pvt->dest); + if(strlen(tech_pvt->dest) >= 4) { /* TODO Number is complete -> check against dialplan */ + if (switch_channel_get_state(channel) == CS_NEW) { + switch_channel_set_state(channel, CS_INIT); + } + + send_dialed_number(listener, tech_pvt->dest, tech_pvt->line, tech_pvt->call_id); + skinny_answer(listener->session[line]); + } + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_answer(switch_core_session_t *session) { private_t *tech_pvt; @@ -525,21 +569,40 @@ switch_status_t skinny_answer(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_hangup(listener_t *listener, uint32_t line) +struct speed_dial_get_dest_helper { + uint32_t pos; + char dest[40]; +}; + +int skinny_speed_dial_get_dest_callback(void *pArg, int argc, char **argv, char **columnNames) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; + struct speed_dial_get_dest_helper *helper = pArg; - channel = switch_core_session_get_channel(listener->session[line]); - assert(channel != NULL); + helper->pos++; + if (helper->pos == atoi(argv[0])) { /* wanted_position */ + strncpy(helper->dest, argv[3], 40); /* value */ + } + return 0; +} - tech_pvt = switch_core_session_get_private(listener->session[line]); - assert(tech_pvt != NULL); +void skinny_speed_dial_get_dest(skinny_profile_t *profile, const char *device_name, uint32_t instance, char *dest) +{ + struct speed_dial_get_dest_helper helper = {0}; + char *sql; - switch_clear_flag_locked(tech_pvt, TFLAG_IO); - switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - return SWITCH_STATUS_SUCCESS; + switch_assert(device_name); + + if ((sql = switch_mprintf( + "SELECT '%d' AS wanted_position, position, label, value, settings " + "FROM skinny_buttons WHERE device_name='%s' AND type='speed-dial' " + "ORDER BY position", + instance, + device_name + ))) { + skinny_execute_sql_callback(profile, profile->listener_mutex, sql, skinny_speed_dial_get_dest_callback, &helper); + switch_safe_free(sql); + } + strncpy(dest, helper.dest, 40); } /*****************************************************************************/ @@ -1273,8 +1336,12 @@ switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_ message->data.soft_key_set.total_soft_key_set_count = 11; /* TODO fill the set */ + skinny_send_reply(listener, message); + /* Init the states */ + skinny_line_set_state(listener, 0, SKINNY_KEY_SET_ON_HOOK, 0); + return SWITCH_STATUS_SUCCESS; } @@ -1420,6 +1487,7 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn switch_status_t status = SWITCH_STATUS_SUCCESS; skinny_profile_t *profile; + switch_channel_t *channel = NULL; uint32_t line; switch_assert(listener->profile); @@ -1438,7 +1506,7 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn if(!listener->session[line]) { /*the line is not busy */ switch(request->data.soft_key_event.event) { case SOFTKEY_NEWCALL: - skinny_pick_up(listener, line); + skinny_create_session(listener, line, SKINNY_KEY_SET_OFF_HOOK); break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, @@ -1447,7 +1515,11 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn } else { /* the line is busy */ switch(request->data.soft_key_event.event) { case SOFTKEY_ENDCALL: - skinny_hangup(listener, line); + channel = switch_core_session_get_channel(listener->session[line]); + assert(channel != NULL); + + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, @@ -1477,7 +1549,48 @@ switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_mess if(listener->session[line]) { /*answering a call */ skinny_answer(listener->session[line]); } else { /* start a new call */ - skinny_pick_up(listener, line); + skinny_create_session(listener, line, SKINNY_KEY_SET_OFF_HOOK); + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) +{ + skinny_profile_t *profile; + uint32_t line = 1; + private_t *tech_pvt = NULL; + char dest[40] = ""; + + switch_assert(listener->profile); + switch_assert(listener->device_name); + + profile = listener->profile; + + skinny_check_data_length(request, sizeof(request->data.stimulus)); + + switch(request->data.stimulus.instance_type) { + case SKINNY_BUTTON_VOICEMAIL: + skinny_create_session(listener, line, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT); + + tech_pvt = switch_core_session_get_private(listener->session[line]); + assert(tech_pvt != NULL); + + strcpy(tech_pvt->dest, "vmain"); + skinny_process_dest(listener, line); + break; + case SKINNY_BUTTON_SPEED_DIAL: + skinny_speed_dial_get_dest(listener->profile, listener->device_name, request->data.stimulus.instance, dest); + if(strlen(dest) > 0) { + skinny_create_session(listener, line, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT); + + tech_pvt = switch_core_session_get_private(listener->session[line]); + assert(tech_pvt != NULL); + + strcpy(tech_pvt->dest, dest); + skinny_process_dest(listener, line); + } + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); } return SWITCH_STATUS_SUCCESS; } @@ -1581,7 +1694,7 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny skinny_check_data_length(request, sizeof(request->data.keypad_button)); - if(request->data.keypad_button.line_instance) { + if(request->data.keypad_button.line_instance != 0) { line = request->data.keypad_button.line_instance; } else { /* Find first active line */ @@ -1619,10 +1732,6 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny if((skinny_line_get_state(listener, tech_pvt->line) == SKINNY_KEY_SET_OFF_HOOK) || (skinny_line_get_state(listener, tech_pvt->line) == SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT)) { - char name[128]; - switch_channel_t *channel; - char *cid_name = "TODO-soft_key_event"; /* TODO */ - char *cid_num = "00000"; /* TODO */ if(strlen(tech_pvt->dest) == 0) {/* first digit */ stop_tone(listener, tech_pvt->line, tech_pvt->call_id); skinny_line_set_state(listener, tech_pvt->line, SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, tech_pvt->call_id); @@ -1630,38 +1739,7 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny tech_pvt->dest[strlen(tech_pvt->dest)] = digit; - if(strlen(tech_pvt->dest) >= 4) { /* TODO Number is complete */ - if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(listener->session[line]), - NULL, listener->profile->dialplan, cid_name, cid_num, listener->remote_ip, NULL, NULL, NULL, "skinny" /* modname */, listener->profile->context, tech_pvt->dest)) != 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session[line]), SWITCH_LOG_CRIT, "Error Creating Session caller profile\n"); - goto error; - } - - channel = switch_core_session_get_channel(listener->session[line]); - snprintf(name, sizeof(name), "SKINNY/%s/%s/%d", listener->profile->name, listener->device_name, line); - switch_channel_set_name(channel, name); - - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - - if (switch_channel_get_state(channel) == CS_NEW) { - switch_channel_set_state(channel, CS_INIT); - } - - if (switch_core_session_thread_launch(listener->session[line]) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session[line]), SWITCH_LOG_CRIT, "Error Creating Session thread\n"); - goto error; - } - - skinny_line_set_state(listener, tech_pvt->line, SKINNY_KEY_SET_CONNECTED, tech_pvt->call_id); - send_dialed_number(listener, tech_pvt->dest, tech_pvt->line, tech_pvt->call_id); - skinny_answer(listener->session[line]); - - goto done; -error: - return SWITCH_STATUS_FALSE; -done: - return SWITCH_STATUS_SUCCESS; - } + skinny_process_dest(listener, tech_pvt->line); } else { if(digit != '\0') { switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; @@ -1687,7 +1765,7 @@ switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_messa skinny_check_data_length(request, sizeof(request->data.on_hook)); - if(request->data.on_hook.line_instance) { + if(request->data.on_hook.line_instance != 0) { line = request->data.on_hook.line_instance; } else { /* Find first active line */ @@ -1700,7 +1778,12 @@ switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_messa } if(listener->session[line]) { - skinny_hangup(listener, line); + switch_channel_t *channel = NULL; + + channel = switch_core_session_get_channel(listener->session[line]); + assert(channel != NULL); + + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); } return status; } @@ -1758,6 +1841,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_soft_key_event_message(listener, request); case OFF_HOOK_MESSAGE: return skinny_handle_off_hook_message(listener, request); + case STIMULUS_MESSAGE: + return skinny_handle_stimulus_message(listener, request); case OPEN_RECEIVE_CHANNEL_ACK_MESSAGE: return skinny_handle_open_receive_channel_ack_message(listener, request); case KEYPAD_BUTTON_MESSAGE: diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index f3de02ed56..33153240fd 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -73,7 +73,7 @@ struct keypad_button_message { struct stimulus_message { uint32_t instance_type; /* See enum skinny_button_definition */ uint32_t instance; - uint32_t call_reference; + /* uint32_t call_reference; */ }; /* OffHookMessage */ @@ -665,6 +665,10 @@ switch_status_t skinny_device_event(listener_t *listener, switch_event_t **ev, s switch_status_t skinny_send_call_info(switch_core_session_t *session); +switch_status_t skinny_create_session(listener_t *listener, uint32_t line, uint32_t to_state); +switch_status_t skinny_process_dest(listener_t *listener, uint32_t line); +switch_status_t skinny_answer(switch_core_session_t *session); + switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply); #define skinny_send_reply(listener, reply) skinny_perform_send_reply(listener, __FILE__, __SWITCH_FUNC__, __LINE__, reply)