Revision
17318
Author
math.parent
Date
2010-04-16 04:59:58 -0500 (Fri, 16 Apr 2010)

Log Message

Skinny: initial transfer support

and some re-indentation

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c (17317 => 17318)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-04-16 04:29:38 UTC (rev 17317)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.c	2010-04-16 09:59:58 UTC (rev 17318)
@@ -542,9 +542,9 @@
 	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->profile = profile;
 	tech_pvt->call_id = ++profile->next_call_id;
 	tech_pvt->party_id = tech_pvt->call_id;
-	tech_pvt->profile = profile;
 	switch_core_session_set_private(session, tech_pvt);
 	tech_pvt->session = session;
 }

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h (17317 => 17318)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h	2010-04-16 04:29:38 UTC (rev 17317)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/mod_skinny.h	2010-04-16 09:59:58 UTC (rev 17318)
@@ -147,36 +147,40 @@
 } 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;
 
-    /* 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;
+	/* 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;
 };
 
 typedef struct private_object private_t;

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c (17317 => 17318)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c	2010-04-16 04:29:38 UTC (rev 17317)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.c	2010-04-16 09:59:58 UTC (rev 17318)
@@ -837,6 +837,47 @@
 	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;
@@ -1990,6 +2031,7 @@
 	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;
@@ -1998,6 +2040,9 @@
 	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);
 
@@ -2146,6 +2191,13 @@
 	            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);
 
@@ -2341,19 +2393,17 @@
 			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);
-	    }
+			);
+
+		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;
 }
 
@@ -2509,14 +2559,14 @@
 			return skinny_handle_unregister(listener, request);
 		case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
 			return skinny_handle_soft_key_template_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);
-		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);
 		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);

Modified: freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.h (17317 => 17318)


--- freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.h	2010-04-16 04:29:38 UTC (rev 17317)
+++ freeswitch/trunk/src/mod/endpoints/mod_skinny/skinny_protocol.h	2010-04-16 09:59:58 UTC (rev 17318)
@@ -162,6 +162,18 @@
 /* SoftKeyTemplateReqMessage */
 #define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028
 
+/* HeadsetStatusMessage */
+#define HEADSET_STATUS_MESSAGE 0x002B
+struct headset_status_message {
+    uint32_t mode;
+};
+
+/* RegisterAvailableLinesMessage */
+#define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D
+struct register_available_lines_message {
+    uint32_t count;
+};
+
 /* ServiceUrlStatReqMessage */
 #define SERVICE_URL_STAT_REQ_MESSAGE 0x0033
 struct service_url_stat_req_message {
@@ -174,18 +186,6 @@
     uint32_t feature_index;
 };
 
-/* HeadsetStatusMessage */
-#define HEADSET_STATUS_MESSAGE 0x002B
-struct headset_status_message {
-    uint32_t mode;
-};
-
-/* RegisterAvailableLinesMessage */
-#define REGISTER_AVAILABLE_LINES_MESSAGE 0x002D
-struct register_available_lines_message {
-    uint32_t count;
-};
-
 /* RegisterAckMessage */
 #define REGISTER_ACK_MESSAGE 0x0081
 struct register_ack_message {