} GFLAGS;
struct private_object {
- unsigned int flags;
- switch_frame_t read_frame;
- unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
- switch_core_session_t *session;
- switch_caller_profile_t *caller_profile;
- switch_mutex_t *mutex;
- switch_mutex_t *flag_mutex;
- /* identification */
- uint32_t call_id;
- uint32_t party_id;
+ unsigned int flags;
+ switch_frame_t read_frame;
+ unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+ switch_core_session_t *session;
+ switch_caller_profile_t *caller_profile;
+ switch_mutex_t *mutex;
+ switch_mutex_t *flag_mutex;
- skinny_profile_t *profile;
+ /* identification */
+ skinny_profile_t *profile;
+ uint32_t call_id;
+ uint32_t party_id;
+
+ /* related calls */
+ uint32_t transfer_to_call_id;
+ uint32_t transfer_from_call_id;
- /* codec */
- char *iananame;
- switch_codec_t read_codec;
- switch_codec_t write_codec;
- switch_codec_implementation_t read_impl;
- switch_codec_implementation_t write_impl;
- unsigned long rm_rate;
- uint32_t codec_ms;
- char *rm_encoding;
- char *rm_fmtp;
- switch_payload_t agreed_pt;
- /* RTP */
- switch_rtp_t *rtp_session;
- char *local_sdp_audio_ip;
- switch_port_t local_sdp_audio_port;
- char *remote_sdp_audio_ip;
- switch_port_t remote_sdp_audio_port;
+ /* codec */
+ char *iananame;
+ switch_codec_t read_codec;
+ switch_codec_t write_codec;
+ switch_codec_implementation_t read_impl;
+ switch_codec_implementation_t write_impl;
+ unsigned long rm_rate;
+ uint32_t codec_ms;
+ char *rm_encoding;
+ char *rm_fmtp;
+ switch_payload_t agreed_pt;
+ /* RTP */
+ switch_rtp_t *rtp_session;
+ char *local_sdp_audio_ip;
+ switch_port_t local_sdp_audio_port;
+ char *remote_sdp_audio_ip;
+ switch_port_t remote_sdp_audio_port;
};
typedef struct private_object private_t;
return SWITCH_STATUS_SUCCESS;
}
+switch_status_t skinny_session_transfer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance)
+{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ const char *uuid = NULL;
+ switch_core_session_t *session2 = NULL;
+ private_t *tech_pvt2 = NULL;
+
+ switch_assert(session);
+ switch_assert(listener);
+ switch_assert(listener->profile);
+
+ tech_pvt = switch_core_session_get_private(session);
+ channel = switch_core_session_get_channel(session);
+ uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE);
+
+ if (tech_pvt->transfer_from_call_id) {
+ if((session2 = skinny_profile_find_session(listener->profile, listener, &line_instance, 0))) {
+ switch_channel_t *channel2 = switch_core_session_get_channel(session2);
+ const char *uuid2 = switch_channel_get_variable(channel2, SWITCH_BRIDGE_VARIABLE);
+ switch_ivr_uuid_bridge(uuid, uuid2);
+ switch_core_session_rwunlock(session2);
+ /* TODO: How to inform the user that the bridge is not possible? */
+ }
+ } else {
+ if(uuid) {
+ /* TODO CallSelectStat */
+ status = skinny_create_ingoing_session(listener, &line_instance, &session2);
+ tech_pvt2 = switch_core_session_get_private(session2);
+ tech_pvt2->transfer_from_call_id = tech_pvt->call_id;
+ tech_pvt->transfer_to_call_id = tech_pvt2->call_id;
+ skinny_session_process_dest(session2, listener, line_instance, NULL, '\0', 0);
+ switch_core_session_rwunlock(session2);
+ } else {
+ /* TODO: How to inform the user that the bridge is not possible? */
+ }
+ }
+ return status;
+}
+
switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance)
{
switch_channel_t *channel = NULL;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL;
+ message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[3] = SOFTKEY_TRANSFER;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME;
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL;
+
+ message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[1] = SOFTKEY_REDIAL;
+ message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[2] = SOFTKEY_ENDCALL;
skinny_send_reply(listener, message);
status = skinny_session_hold_line(session, listener, line_instance);
}
break;
+ case SOFTKEY_TRANSFER:
+ session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id);
+
+ if(session) {
+ status = skinny_session_transfer(session, listener, line_instance);
+ }
+ break;
case SOFTKEY_BACKSPACE:
session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id);
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);
+ );
+ 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;
}
return skinny_handle_unregister(listener, request);
case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
return skinny_handle_soft_key_template_request(listener, request);
- case SERVICE_URL_STAT_REQ_MESSAGE:
- return skinny_handle_service_url_stat_request(listener, request);
- case FEATURE_STAT_REQ_MESSAGE:
- return skinny_handle_feature_stat_request(listener, request);
case HEADSET_STATUS_MESSAGE:
return skinny_headset_status_message(listener, request);
case REGISTER_AVAILABLE_LINES_MESSAGE:
return skinny_handle_register_available_lines_message(listener, request);
+ case SERVICE_URL_STAT_REQ_MESSAGE:
+ return skinny_handle_service_url_stat_request(listener, request);
+ case FEATURE_STAT_REQ_MESSAGE:
+ return skinny_handle_feature_stat_request(listener, request);
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length);
/* SoftKeyTemplateReqMessage */
#define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028
-/* ServiceUrlStatReqMessage */
-#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
-struct service_url_stat_req_message {
- uint32_t service_url_index;
-};
-
-/* FeatureStatReqMessage */
-#define FEATURE_STAT_REQ_MESSAGE 0x0034
-struct feature_stat_req_message {
- uint32_t feature_index;
-};
-
/* HeadsetStatusMessage */
#define HEADSET_STATUS_MESSAGE 0x002B
struct headset_status_message {
uint32_t count;
};
+/* ServiceUrlStatReqMessage */
+#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
+struct service_url_stat_req_message {
+ uint32_t service_url_index;
+};
+
+/* FeatureStatReqMessage */
+#define FEATURE_STAT_REQ_MESSAGE 0x0034
+struct feature_stat_req_message {
+ uint32_t feature_index;
+};
+
/* RegisterAckMessage */
#define REGISTER_ACK_MESSAGE 0x0081
struct register_ack_message {