return skinny_send_reply(listener, message);
}
+switch_status_t send_version(listener_t *listener,
+ char *version)
+{
+ skinny_message_t *message;
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.version));
+ strncpy(message->data.version.version, version, 16);
+ return skinny_send_reply(listener, message);
+}
+
switch_status_t send_register_reject(listener_t *listener,
char *error)
{
return skinny_send_reply(listener, message);
}
-/* Message handling */
-switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request)
+/*****************************************************************************/
+/* SKINNY MESSAGE HANDLERS */
+/*****************************************************************************/
+switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request)
{
- switch_event_t *event = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.alarm));
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
- "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n",
- request->data.alarm.alarm_severity, request->data.alarm.display_message,
- request->data.alarm.alarm_param1, request->data.alarm.alarm_param2);
- /* skinny::alarm event */
- skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2);
- switch_event_fire(&event);
+ skinny_message_t *message;
+ message = switch_core_alloc(listener->pool, 12);
+ message->type = KEEP_ALIVE_ACK_MESSAGE;
+ message->length = 4;
+ keepalive_listener(listener, NULL);
+ skinny_send_reply(listener, message);
return SWITCH_STATUS_SUCCESS;
}
return status;
}
-switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request)
{
- skinny_check_data_length(request, sizeof(request->data.headset_status));
+ char *sql;
+ skinny_profile_t *profile;
+
+ switch_assert(listener->profile);
+ switch_assert(listener->device_name);
+
+ profile = listener->profile;
+
+ skinny_check_data_length(request, sizeof(request->data.as_uint16));
+
+ if ((sql = switch_mprintf(
+ "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d",
+ request->data.port.port,
+ listener->device_name,
+ listener->device_instance
+ ))) {
+ skinny_execute_sql(profile, sql, profile->sql_mutex);
+ switch_safe_free(sql);
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request)
+{
+ uint32_t line_instance = 0;
+ switch_core_session_t *session;
+
+ skinny_check_data_length(request, sizeof(request->data.keypad_button));
+
+ if(request->data.keypad_button.line_instance) {
+ line_instance = request->data.keypad_button.line_instance;
+ } else {
+ line_instance = 1;
+ }
+
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.keypad_button.call_id);
+
+ if(session) {
+ switch_channel_t *channel = NULL;
+ private_t *tech_pvt = NULL;
+ char digit = '\0';
+
+ channel = switch_core_session_get_channel(session);
+ tech_pvt = switch_core_session_get_private(session);
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button);
+
+ if (request->data.keypad_button.button == 14) {
+ digit = '*';
+ } else if (request->data.keypad_button.button == 15) {
+ digit = '#';
+ } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) {
+ digit = '0' + request->data.keypad_button.button;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button);
+ }
+
+ /* TODO check call_id and line */
+
+ if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) {
+
+ skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0);
+ } else {
+ if(digit != '\0') {
+ switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)};
+ dtmf.digit = digit;
+ switch_channel_queue_dtmf(channel, &dtmf);
+ }
+ }
+ }
+
+ if(session) {
+ switch_core_session_rwunlock(session);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request)
+{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ struct speed_dial_stat_res_message *button = NULL;
+ uint32_t line_instance = 0;
+ uint32_t call_id = 0;
+ switch_core_session_t *session = NULL;
+
+ skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id));
+
+ if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) {
+ call_id = request->data.stimulus.call_id;
+ }
+
+ switch(request->data.stimulus.instance_type) {
+ case SKINNY_BUTTON_LAST_NUMBER_REDIAL:
+ skinny_create_ingoing_session(listener, &line_instance, &session);
+ skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0);
+ break;
+ case SKINNY_BUTTON_SPEED_DIAL:
+ skinny_speed_dial_get(listener, request->data.stimulus.instance, &button);
+ if(strlen(button->line) > 0) {
+ skinny_create_ingoing_session(listener, &line_instance, &session);
+ skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0);
+ }
+ break;
+ case SKINNY_BUTTON_HOLD:
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id);
+
+ if(session) {
+ status = skinny_session_hold_line(session, listener, line_instance);
+ }
+ break;
+ case SKINNY_BUTTON_VOICEMAIL:
+ skinny_create_ingoing_session(listener, &line_instance, &session);
+ skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0);
+ break;
+ default:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type);
+ }
+
+ if(session) {
+ switch_core_session_rwunlock(session);
+ }
+
+ return status;
+}
+
+switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request)
+{
+ uint32_t line_instance;
+ switch_core_session_t *session = NULL;
+ private_t *tech_pvt = NULL;
+
+ skinny_check_data_length(request, sizeof(request->data.off_hook));
+
+ if(request->data.off_hook.line_instance > 0) {
+ line_instance = request->data.off_hook.line_instance;
+ } else {
+ line_instance = 1;
+ }
+
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.off_hook.call_id);
+
+ if(session) { /*answering a call */
+ skinny_session_answer(session, listener, line_instance);
+ } else { /* start a new call */
+ skinny_create_ingoing_session(listener, &line_instance, &session);
+ tech_pvt = switch_core_session_get_private(session);
+ assert(tech_pvt != NULL);
+
+ skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
+ }
+
+ if(session) {
+ switch_core_session_rwunlock(session);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request)
+{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_core_session_t *session = NULL;
+ uint32_t line_instance = 0;
+
+ skinny_check_data_length(request, sizeof(request->data.on_hook));
+
+ line_instance = request->data.on_hook.line_instance;
+
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.on_hook.call_id);
+
+ if(session) {
+ switch_channel_t *channel = NULL;
+
+ channel = switch_core_session_get_channel(session);
+
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ }
+
+ if(session) {
+ switch_core_session_rwunlock(session);
+ }
+
+ return status;
+}
+
+switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request)
+{
+ skinny_message_t *message;
+ struct speed_dial_stat_res_message *button = NULL;
+
+ skinny_check_data_length(request, sizeof(request->data.speed_dial_req));
+
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res));
+ message->type = SPEED_DIAL_STAT_RES_MESSAGE;
+ message->length = 4 + sizeof(message->data.speed_dial_res);
+
+ skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button);
+
+ memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message));
+
+ skinny_send_reply(listener, message);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request)
+{
+ skinny_message_t *message;
+ struct line_stat_res_message *button = NULL;
+
+ skinny_check_data_length(request, sizeof(request->data.line_req));
+
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res));
+ message->type = LINE_STAT_RES_MESSAGE;
+ message->length = 4 + sizeof(message->data.line_res);
+
+ skinny_line_get(listener, request->data.line_req.number, &button);
+
+ memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message));
+
+ skinny_send_reply(listener, message);
- /* Nothing to do */
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request)
-{
- char *sql;
- skinny_profile_t *profile;
-
- uint32_t i = 0;
- uint32_t n = 0;
- char *codec_order[SWITCH_MAX_CODECS];
- char *codec_string;
-
- size_t string_len, string_pos, pos;
-
- switch_assert(listener->profile);
- switch_assert(listener->device_name);
-
- profile = listener->profile;
-
- skinny_check_data_length(request, sizeof(request->data.cap_res.count));
-
- n = request->data.cap_res.count;
- if (n > SWITCH_MAX_CODECS) {
- n = SWITCH_MAX_CODECS;
- }
- string_len = -1;
-
- skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0]));
-
- for (i = 0; i < n; i++) {
- char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec);
- codec_order[i] = codec;
- string_len += strlen(codec)+1;
- }
- i = 0;
- pos = 0;
- codec_string = switch_core_alloc(listener->pool, string_len+1);
- for (string_pos = 0; string_pos < string_len; string_pos++) {
- char *codec = codec_order[i];
- switch_assert(i < n);
- if(pos == strlen(codec)) {
- codec_string[string_pos] = ',';
- i++;
- pos = 0;
- } else {
- codec_string[string_pos] = codec[pos++];
- }
- }
- codec_string[string_len] = '\0';
- if ((sql = switch_mprintf(
- "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'",
- codec_string,
- listener->device_name
- ))) {
- skinny_execute_sql(profile, sql, profile->sql_mutex);
- switch_safe_free(sql);
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
- "Codecs %s supported.\n", codec_string);
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request)
{
- char *sql;
- skinny_profile_t *profile;
-
- switch_assert(listener->profile);
- switch_assert(listener->device_name);
-
- profile = listener->profile;
-
- skinny_check_data_length(request, sizeof(request->data.as_uint16));
-
- if ((sql = switch_mprintf(
- "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d",
- request->data.port.port,
- listener->device_name,
- listener->device_instance
- ))) {
- skinny_execute_sql(profile, sql, profile->sql_mutex);
- switch_safe_free(sql);
- }
- return SWITCH_STATUS_SUCCESS;
+ return send_define_current_time_date(listener);
}
struct button_template_helper {
}
}
- skinny_send_reply(listener, message);
+
+
+ return skinny_send_reply(listener, message);;
+}
+switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request)
+{
+ /* TODO */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "VersionReqMessage not implemented yet.\n");
return SWITCH_STATUS_SUCCESS;
+ /* return send_version(listener, ""); */
}
-switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request)
{
- skinny_message_t *message;
+ char *sql;
skinny_profile_t *profile;
+ uint32_t i = 0;
+ uint32_t n = 0;
+ char *codec_order[SWITCH_MAX_CODECS];
+ char *codec_string;
+
+ size_t string_len, string_pos, pos;
+
switch_assert(listener->profile);
switch_assert(listener->device_name);
profile = listener->profile;
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template));
- message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE;
- message->length = 4 + sizeof(message->data.soft_key_template);
+ skinny_check_data_length(request, sizeof(request->data.cap_res.count));
- message->data.soft_key_template.soft_key_offset = 0;
- message->data.soft_key_template.soft_key_count = 21;
- message->data.soft_key_template.total_soft_key_count = 21;
+ n = request->data.cap_res.count;
+ if (n > SWITCH_MAX_CODECS) {
+ n = SWITCH_MAX_CODECS;
+ }
+ string_len = -1;
- memcpy(message->data.soft_key_template.soft_key,
- soft_key_template_default,
- sizeof(soft_key_template_default));
+ skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0]));
- skinny_send_reply(listener, message);
+ for (i = 0; i < n; i++) {
+ char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec);
+ codec_order[i] = codec;
+ string_len += strlen(codec)+1;
+ }
+ i = 0;
+ pos = 0;
+ codec_string = switch_core_alloc(listener->pool, string_len+1);
+ for (string_pos = 0; string_pos < string_len; string_pos++) {
+ char *codec = codec_order[i];
+ switch_assert(i < n);
+ if(pos == strlen(codec)) {
+ codec_string[string_pos] = ',';
+ i++;
+ pos = 0;
+ } else {
+ codec_string[string_pos] = codec[pos++];
+ }
+ }
+ codec_string[string_len] = '\0';
+ if ((sql = switch_mprintf(
+ "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'",
+ codec_string,
+ listener->device_name
+ ))) {
+ skinny_execute_sql(profile, sql, profile->sql_mutex);
+ switch_safe_free(sql);
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+ "Codecs %s supported.\n", codec_string);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request)
+{
+ switch_event_t *event = NULL;
+
+ skinny_check_data_length(request, sizeof(request->data.alarm));
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+ "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n",
+ request->data.alarm.alarm_severity, request->data.alarm.display_message,
+ request->data.alarm.alarm_param1, request->data.alarm.alarm_param2);
+ /* skinny::alarm event */
+ skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2);
+ switch_event_fire(&event);
return SWITCH_STATUS_SUCCESS;
}
+switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *listener, skinny_message_t *request)
+{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ uint32_t line_instance = 0;
+ switch_core_session_t *session;
+
+ skinny_check_data_length(request, sizeof(request->data.open_receive_channel_ack));
+
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.open_receive_channel_ack.pass_thru_party_id);
+
+ if(session) {
+ const char *err = NULL;
+ private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ struct in_addr addr;
+
+ tech_pvt = switch_core_session_get_private(session);
+ channel = switch_core_session_get_channel(session);
+
+ /* Codec */
+ tech_pvt->iananame = "PCMU"; /* TODO */
+ tech_pvt->codec_ms = 10; /* TODO */
+ tech_pvt->rm_rate = 8000; /* TODO */
+ tech_pvt->rm_fmtp = NULL; /* TODO */
+ tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */
+ tech_pvt->rm_encoding = switch_core_strdup(switch_core_session_get_pool(session), "");
+ skinny_tech_set_codec(tech_pvt, 0);
+ if ((status = skinny_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
+ goto end;
+ }
+
+ /* Request a local port from the core's allocator */
+ if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(listener->profile->ip))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ tech_pvt->local_sdp_audio_ip = switch_core_strdup(switch_core_session_get_pool(session), listener->profile->ip);
+
+ tech_pvt->remote_sdp_audio_ip = inet_ntoa(request->data.open_receive_channel_ack.ip);
+ tech_pvt->remote_sdp_audio_port = request->data.open_receive_channel_ack.port;
+
+ tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
+ tech_pvt->local_sdp_audio_port,
+ tech_pvt->remote_sdp_audio_ip,
+ tech_pvt->remote_sdp_audio_port,
+ tech_pvt->agreed_pt,
+ tech_pvt->read_impl.samples_per_packet,
+ tech_pvt->codec_ms * 1000,
+ (switch_rtp_flag_t) 0, "soft", &err,
+ switch_core_session_get_pool(session));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
+ "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
+ switch_channel_get_name(channel),
+ tech_pvt->local_sdp_audio_ip,
+ tech_pvt->local_sdp_audio_port,
+ tech_pvt->remote_sdp_audio_ip,
+ tech_pvt->remote_sdp_audio_port,
+ tech_pvt->agreed_pt,
+ tech_pvt->read_impl.microseconds_per_packet / 1000,
+ switch_rtp_ready(tech_pvt->rtp_session) ? "SUCCESS" : err);
+ inet_aton(tech_pvt->local_sdp_audio_ip, &addr);
+ send_start_media_transmission(listener,
+ tech_pvt->call_id, /* uint32_t conference_id, */
+ tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
+ addr.s_addr, /* uint32_t remote_ip, */
+ tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */
+ 20, /* uint32_t ms_per_packet, */
+ SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */
+ 184, /* uint32_t precedence, */
+ 0, /* uint32_t silence_suppression, */
+ 0, /* uint16_t max_frames_per_packet, */
+ 0 /* uint32_t g723_bitrate */
+ );
+
+ if (switch_channel_get_state(channel) == CS_NEW) {
+ switch_channel_set_state(channel, CS_INIT);
+ }
+ switch_channel_mark_answered(channel);
+ }
+end:
+ if(session) {
+ switch_core_session_rwunlock(session);
+ }
+ return status;
+}
+
switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request)
{
skinny_message_t *message;
return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request)
-{
- skinny_message_t *message;
- struct line_stat_res_message *button = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.line_req));
-
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res));
- message->type = LINE_STAT_RES_MESSAGE;
- message->length = 4 + sizeof(message->data.line_res);
-
- skinny_line_get(listener, request->data.line_req.number, &button);
-
- memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message));
-
- skinny_send_reply(listener, message);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request)
-{
- skinny_message_t *message;
- struct speed_dial_stat_res_message *button = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.speed_dial_req));
-
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res));
- message->type = SPEED_DIAL_STAT_RES_MESSAGE;
- message->length = 4 + sizeof(message->data.speed_dial_res);
-
- skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button);
-
- memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message));
-
- skinny_send_reply(listener, message);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request)
-{
- skinny_message_t *message;
- struct service_url_stat_res_message *button = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.service_url_req));
-
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res));
- message->type = SERVICE_URL_STAT_RES_MESSAGE;
- message->length = 4 + sizeof(message->data.service_url_res);
-
- skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button);
-
- memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message));
-
- skinny_send_reply(listener, message);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request)
-{
- skinny_message_t *message;
- struct feature_stat_res_message *button = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.feature_req));
-
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res));
- message->type = FEATURE_STAT_RES_MESSAGE;
- message->length = 4 + sizeof(message->data.feature_res);
-
- skinny_feature_get(listener, request->data.feature_req.feature_index, &button);
-
- memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message));
-
- skinny_send_reply(listener, message);
-
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request)
-{
- skinny_check_data_length(request, sizeof(request->data.reg_lines));
-
- /* Do nothing */
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request)
-{
- return send_define_current_time_date(listener);
-}
-
-switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request)
-{
- skinny_message_t *message;
-
- message = switch_core_alloc(listener->pool, 12);
- message->type = KEEP_ALIVE_ACK_MESSAGE;
- message->length = 4;
- keepalive_listener(listener, NULL);
- skinny_send_reply(listener, message);
- return SWITCH_STATUS_SUCCESS;
-}
-
-switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
uint32_t line_instance = 0;
return status;
}
-switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t *request)
{
- uint32_t line_instance;
- switch_core_session_t *session = NULL;
- private_t *tech_pvt = NULL;
-
- skinny_check_data_length(request, sizeof(request->data.off_hook));
-
- if(request->data.off_hook.line_instance > 0) {
- line_instance = request->data.off_hook.line_instance;
- } else {
- line_instance = 1;
- }
-
- session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.off_hook.call_id);
+ switch_event_t *event = NULL;
+ skinny_message_t *message;
- if(session) { /*answering a call */
- skinny_session_answer(session, listener, line_instance);
- } else { /* start a new call */
- skinny_create_ingoing_session(listener, &line_instance, &session);
- tech_pvt = switch_core_session_get_private(session);
- assert(tech_pvt != NULL);
+ /* skinny::unregister event */
+ skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_UNREGISTER);
+ switch_event_fire(&event);
- skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
- }
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.unregister_ack));
+ message->type = UNREGISTER_ACK_MESSAGE;
+ message->length = 4 + sizeof(message->data.unregister_ack);
+ message->data.unregister_ack.unregister_status = 0; /* OK */
+ skinny_send_reply(listener, message);
- if(session) {
- switch_core_session_rwunlock(session);
- }
+ /* Close socket */
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request)
{
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- struct speed_dial_stat_res_message *button = NULL;
- uint32_t line_instance = 0;
- uint32_t call_id = 0;
- switch_core_session_t *session = NULL;
+ skinny_message_t *message;
+ skinny_profile_t *profile;
- skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id));
+ switch_assert(listener->profile);
+ switch_assert(listener->device_name);
- if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) {
- call_id = request->data.stimulus.call_id;
- }
+ profile = listener->profile;
- switch(request->data.stimulus.instance_type) {
- case SKINNY_BUTTON_LAST_NUMBER_REDIAL:
- skinny_create_ingoing_session(listener, &line_instance, &session);
- skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0);
- break;
- case SKINNY_BUTTON_SPEED_DIAL:
- skinny_speed_dial_get(listener, request->data.stimulus.instance, &button);
- if(strlen(button->line) > 0) {
- skinny_create_ingoing_session(listener, &line_instance, &session);
- skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0);
- }
- break;
- case SKINNY_BUTTON_HOLD:
- session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id);
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template));
+ message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE;
+ message->length = 4 + sizeof(message->data.soft_key_template);
- if(session) {
- status = skinny_session_hold_line(session, listener, line_instance);
- }
- break;
- case SKINNY_BUTTON_VOICEMAIL:
- skinny_create_ingoing_session(listener, &line_instance, &session);
- skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0);
- break;
- default:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type);
- }
+ message->data.soft_key_template.soft_key_offset = 0;
+ message->data.soft_key_template.soft_key_count = 21;
+ message->data.soft_key_template.total_soft_key_count = 21;
- if(session) {
- switch_core_session_rwunlock(session);
- }
+ memcpy(message->data.soft_key_template.soft_key,
+ soft_key_template_default,
+ sizeof(soft_key_template_default));
- return status;
+ skinny_send_reply(listener, message);
+
+ return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request)
{
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- uint32_t line_instance = 0;
- switch_core_session_t *session;
-
- skinny_check_data_length(request, sizeof(request->data.open_receive_channel_ack));
-
- session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.open_receive_channel_ack.pass_thru_party_id);
-
- if(session) {
- const char *err = NULL;
- private_t *tech_pvt = NULL;
- switch_channel_t *channel = NULL;
- struct in_addr addr;
-
- tech_pvt = switch_core_session_get_private(session);
- channel = switch_core_session_get_channel(session);
-
- /* Codec */
- tech_pvt->iananame = "PCMU"; /* TODO */
- tech_pvt->codec_ms = 10; /* TODO */
- tech_pvt->rm_rate = 8000; /* TODO */
- tech_pvt->rm_fmtp = NULL; /* TODO */
- tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */
- tech_pvt->rm_encoding = switch_core_strdup(switch_core_session_get_pool(session), "");
- skinny_tech_set_codec(tech_pvt, 0);
- if ((status = skinny_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
- goto end;
- }
-
- /* Request a local port from the core's allocator */
- if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(listener->profile->ip))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
- return SWITCH_STATUS_FALSE;
- }
- tech_pvt->local_sdp_audio_ip = switch_core_strdup(switch_core_session_get_pool(session), listener->profile->ip);
-
- tech_pvt->remote_sdp_audio_ip = inet_ntoa(request->data.open_receive_channel_ack.ip);
- tech_pvt->remote_sdp_audio_port = request->data.open_receive_channel_ack.port;
-
- tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->agreed_pt,
- tech_pvt->read_impl.samples_per_packet,
- tech_pvt->codec_ms * 1000,
- (switch_rtp_flag_t) 0, "soft", &err,
- switch_core_session_get_pool(session));
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
- "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
- switch_channel_get_name(channel),
- tech_pvt->local_sdp_audio_ip,
- tech_pvt->local_sdp_audio_port,
- tech_pvt->remote_sdp_audio_ip,
- tech_pvt->remote_sdp_audio_port,
- tech_pvt->agreed_pt,
- tech_pvt->read_impl.microseconds_per_packet / 1000,
- switch_rtp_ready(tech_pvt->rtp_session) ? "SUCCESS" : err);
- inet_aton(tech_pvt->local_sdp_audio_ip, &addr);
- send_start_media_transmission(listener,
- tech_pvt->call_id, /* uint32_t conference_id, */
- tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
- addr.s_addr, /* uint32_t remote_ip, */
- tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */
- 20, /* uint32_t ms_per_packet, */
- SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */
- 184, /* uint32_t precedence, */
- 0, /* uint32_t silence_suppression, */
- 0, /* uint16_t max_frames_per_packet, */
- 0 /* uint32_t g723_bitrate */
- );
+ skinny_check_data_length(request, sizeof(request->data.headset_status));
- if (switch_channel_get_state(channel) == CS_NEW) {
- switch_channel_set_state(channel, CS_INIT);
- }
- switch_channel_mark_answered(channel);
- }
-end:
- if(session) {
- switch_core_session_rwunlock(session);
- }
- return status;
+ /* Nothing to do */
+ return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request)
{
- uint32_t line_instance = 0;
- switch_core_session_t *session;
-
- skinny_check_data_length(request, sizeof(request->data.keypad_button));
-
- if(request->data.keypad_button.line_instance) {
- line_instance = request->data.keypad_button.line_instance;
- } else {
- line_instance = 1;
- }
-
- session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.keypad_button.call_id);
-
- if(session) {
- switch_channel_t *channel = NULL;
- private_t *tech_pvt = NULL;
- char digit = '\0';
-
- channel = switch_core_session_get_channel(session);
- tech_pvt = switch_core_session_get_private(session);
-
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button);
-
- if (request->data.keypad_button.button == 14) {
- digit = '*';
- } else if (request->data.keypad_button.button == 15) {
- digit = '#';
- } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) {
- digit = '0' + request->data.keypad_button.button;
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button);
- }
-
- /* TODO check call_id and line */
-
- if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) {
-
- skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0);
- } else {
- if(digit != '\0') {
- switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)};
- dtmf.digit = digit;
- switch_channel_queue_dtmf(channel, &dtmf);
- }
- }
- }
-
- if(session) {
- switch_core_session_rwunlock(session);
- }
+ skinny_check_data_length(request, sizeof(request->data.reg_lines));
+ /* Do nothing */
return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request)
{
- switch_status_t status = SWITCH_STATUS_SUCCESS;
- switch_core_session_t *session = NULL;
- uint32_t line_instance = 0;
-
- skinny_check_data_length(request, sizeof(request->data.on_hook));
+ skinny_message_t *message;
+ struct service_url_stat_res_message *button = NULL;
- line_instance = request->data.on_hook.line_instance;
-
- session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.on_hook.call_id);
+ skinny_check_data_length(request, sizeof(request->data.service_url_req));
- if(session) {
- switch_channel_t *channel = NULL;
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res));
+ message->type = SERVICE_URL_STAT_RES_MESSAGE;
+ message->length = 4 + sizeof(message->data.service_url_res);
- channel = switch_core_session_get_channel(session);
+ skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- }
+ memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message));
- if(session) {
- switch_core_session_rwunlock(session);
- }
+ skinny_send_reply(listener, message);
- return status;
+ return SWITCH_STATUS_SUCCESS;
}
-switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t *request)
+switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request)
{
- switch_event_t *event = NULL;
skinny_message_t *message;
+ struct feature_stat_res_message *button = NULL;
- /* skinny::unregister event */
- skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_UNREGISTER);
- switch_event_fire(&event);
+ skinny_check_data_length(request, sizeof(request->data.feature_req));
- message = switch_core_alloc(listener->pool, 12+sizeof(message->data.unregister_ack));
- message->type = UNREGISTER_ACK_MESSAGE;
- message->length = 4 + sizeof(message->data.unregister_ack);
- message->data.unregister_ack.unregister_status = 0; /* OK */
- skinny_send_reply(listener, message);
+ message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res));
+ message->type = FEATURE_STAT_RES_MESSAGE;
+ message->length = 4 + sizeof(message->data.feature_res);
- /* Close socket */
- switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ skinny_feature_get(listener, request->data.feature_req.feature_index, &button);
+
+ memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message));
+
+ skinny_send_reply(listener, message);
return SWITCH_STATUS_SUCCESS;
}
return skinny_handle_time_date_request(listener, request);
case BUTTON_TEMPLATE_REQ_MESSAGE:
return skinny_handle_button_template_request(listener, request);
+ case VERSION_REQ_MESSAGE:
+ return skinny_handle_version_request(listener, request);
case CAPABILITIES_RES_MESSAGE:
return skinny_handle_capabilities_response(listener, request);
case ALARM_MESSAGE: