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;
}
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,
/* 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;
}
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;
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;
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;
switch_channel_set_name(channel, name);
- caller_profile = switch_caller_profile_clone(nsession, 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);
-
- if ((skinny_profile_find_listener(profile, dest, &tech_pvt->listener, &tech_pvt->line) != SWITCH_STATUS_SUCCESS)) {
+ 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 (!tech_pvt->listener) {
+ 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 (tech_pvt->line == 0) {
+ 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;
+
+ switch_channel_set_flag(channel, CF_OUTBOUND);
+ switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
+
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;
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 {
}
}
+/*****************************************************************************/
switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req)
{
skinny_message_t *request;
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;
return SWITCH_STATUS_SUCCESS;
}
+/*****************************************************************************/
switch_status_t skinny_send_call_info(switch_core_session_t *session)
{
private_t *tech_pvt;
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");
switch_core_session_add_stream(session, NULL);
- tech_pvt->listener = listener;
- tech_pvt->line = line;
+ tech_init(tech_pvt, session, listener, line);
+
+ 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;
+ }
- tech_init(tech_pvt, session);
+ 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);
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",
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) {
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;
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);
}
/*****************************************************************************/
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;
}
switch_status_t status = SWITCH_STATUS_SUCCESS;
skinny_profile_t *profile;
+ switch_channel_t *channel = NULL;
uint32_t line;
switch_assert(listener->profile);
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,
} 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,
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;
}
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 */
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);
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)};
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 */
}
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;
}
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: