[svn-commits] file: trunk r395102 - in /trunk: channels/ include/asterisk/ res/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 23 07:27:14 CDT 2013


Author: file
Date: Tue Jul 23 07:27:03 2013
New Revision: 395102

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395102
Log:
Expose the chan_pjsip implementation pvt and session in a defined manner.

This allows modules outside of chan_pjsip itself to get the session given
only an Asterisk channel.

Review: https://reviewboard.asterisk.org/r/2674/

Modified:
    trunk/channels/chan_gulp.c
    trunk/include/asterisk/res_sip_session.h
    trunk/res/res_sip_session.c
    trunk/res/res_sip_session.exports.in

Modified: trunk/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_gulp.c?view=diff&rev=395102&r1=395101&r2=395102
==============================================================================
--- trunk/channels/chan_gulp.c (original)
+++ trunk/channels/chan_gulp.c Tue Jul 23 07:27:03 2013
@@ -114,7 +114,6 @@
 };
 
 struct gulp_pvt {
-	struct ast_sip_session *session;
 	struct ast_sip_session_media *media[SIP_MEDIA_SIZE];
 };
 
@@ -122,9 +121,6 @@
 {
 	struct gulp_pvt *pvt = obj;
 	int i;
-
-	ao2_cleanup(pvt->session);
-	pvt->session = NULL;
 
 	for (i = 0; i < SIP_MEDIA_SIZE; ++i) {
 		ao2_cleanup(pvt->media[i]);
@@ -336,12 +332,12 @@
 
 static int media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
 
 	if (!strcmp(data, "audio")) {
-		return media_offer_read_av(pvt->session, buf, len, AST_FORMAT_TYPE_AUDIO);
+		return media_offer_read_av(channel->session, buf, len, AST_FORMAT_TYPE_AUDIO);
 	} else if (!strcmp(data, "video")) {
-		return media_offer_read_av(pvt->session, buf, len, AST_FORMAT_TYPE_VIDEO);
+		return media_offer_read_av(channel->session, buf, len, AST_FORMAT_TYPE_VIDEO);
 	}
 
 	return 0;
@@ -349,10 +345,10 @@
 
 static int media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
 
 	struct media_offer_data mdata = {
-		.session = pvt->session,
+		.session = channel->session,
 		.value = value
 	};
 
@@ -362,7 +358,7 @@
 		mdata.media_type = AST_FORMAT_TYPE_VIDEO;
 	}
 
-	return ast_sip_push_task_synchronous(pvt->session->serializer, media_offer_write_av, &mdata);
+	return ast_sip_push_task_synchronous(channel->session->serializer, media_offer_write_av, &mdata);
 }
 
 static struct ast_custom_function media_offer_function = {
@@ -374,14 +370,15 @@
 /*! \brief Function called by RTP engine to get local audio RTP peer */
 static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_sip_endpoint *endpoint;
 
-	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
+	if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
-	endpoint = pvt->session->endpoint;
+	endpoint = channel->session->endpoint;
 
 	*instance = pvt->media[SIP_MEDIA_AUDIO]->rtp;
 	ao2_ref(*instance, +1);
@@ -397,9 +394,10 @@
 /*! \brief Function called by RTP engine to get local video RTP peer */
 static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
-
-	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+	struct gulp_pvt *pvt = channel->pvt;
+
+	if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
@@ -412,9 +410,9 @@
 /*! \brief Function called by RTP engine to get peer capabilities */
 static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
-
-	ast_format_cap_copy(result, pvt->session->endpoint->codecs);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+
+	ast_format_cap_copy(result, channel->session->endpoint->codecs);
 }
 
 static int send_direct_media_request(void *data)
@@ -486,8 +484,9 @@
 		const struct ast_format_cap *cap,
 		int nat_active)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+	struct gulp_pvt *pvt = channel->pvt;
+	struct ast_sip_session *session = channel->session;
 	int changed = 0;
 	struct ast_channel *bridge_peer;
 
@@ -544,7 +543,8 @@
 {
 	struct ast_channel *chan;
 	struct ast_format fmt;
-	struct gulp_pvt *pvt;
+	RAII_VAR(struct gulp_pvt *, pvt, NULL, ao2_cleanup);
+	struct ast_sip_channel_pvt *channel;
 
 	if (!(pvt = ao2_alloc(sizeof(*pvt), gulp_pvt_dtor))) {
 		return NULL;
@@ -552,27 +552,28 @@
 
 	if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "Gulp/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
 		ast_atomic_fetchadd_int((int *)&chan_idx, +1)))) {
-		ao2_cleanup(pvt);
 		return NULL;
 	}
 
 	ast_channel_tech_set(chan, &gulp_tech);
 
-	ao2_ref(session, +1);
-	pvt->session = session;
+	if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
+		ast_hangup(chan);
+		return NULL;
+	}
+
 	/* If res_sip_session is ever updated to create/destroy ast_sip_session_media
 	 * during a call such as if multiple same-type stream support is introduced,
 	 * these will need to be recaptured as well */
 	pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
-	ast_channel_tech_pvt_set(chan, pvt);
+	ast_channel_tech_pvt_set(chan, channel);
 	if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(chan));
 	}
 	if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) {
 		ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan));
 	}
-
 
 	if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) {
 		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
@@ -637,8 +638,7 @@
 /*! \brief Function called by core when we should answer a Gulp session */
 static int gulp_answer(struct ast_channel *ast)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
 
 	if (ast_channel_state(ast) == AST_STATE_UP) {
 		return 0;
@@ -646,10 +646,10 @@
 
 	ast_setstate(ast, AST_STATE_UP);
 
-	ao2_ref(session, +1);
-	if (ast_sip_push_task(session->serializer, answer, session)) {
+	ao2_ref(channel->session, +1);
+	if (ast_sip_push_task(channel->session->serializer, answer, channel->session)) {
 		ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
-		ao2_cleanup(session);
+		ao2_cleanup(channel->session);
 		return -1;
 	}
 
@@ -659,8 +659,8 @@
 /*! \brief Function called by core to read any waiting frames */
 static struct ast_frame *gulp_read(struct ast_channel *ast)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_frame *f;
 	struct ast_sip_session_media *media = NULL;
 	int rtcp = 0;
@@ -702,8 +702,8 @@
 		ast_set_write_format(ast, ast_channel_writeformat(ast));
 	}
 
-	if (session->dsp) {
-		f = ast_dsp_process(ast, session->dsp, f);
+	if (channel->session->dsp) {
+		f = ast_dsp_process(ast, channel->session->dsp, f);
 
 		if (f && (f->frametype == AST_FRAME_DTMF)) {
 			ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
@@ -717,7 +717,8 @@
 /*! \brief Function called by core to write frames */
 static int gulp_write(struct ast_channel *ast, struct ast_frame *frame)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_sip_session_media *media;
 	int res = 0;
 
@@ -764,9 +765,10 @@
 static int fixup(void *data)
 {
 	struct fixup_data *fix_data = data;
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(fix_data->chan);
-
-	fix_data->session->channel = fix_data->chan;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(fix_data->chan);
+	struct gulp_pvt *pvt = channel->pvt;
+
+	channel->session->channel = fix_data->chan;
 	if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(fix_data->chan));
 	}
@@ -780,18 +782,17 @@
 /*! \brief Function called by core to change the underlying owner channel */
 static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(newchan);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
 	struct fixup_data fix_data;
 
-	fix_data.session = session;
+	fix_data.session = channel->session;
 	fix_data.chan = newchan;
 
-	if (session->channel != oldchan) {
-		return -1;
-	}
-
-	if (ast_sip_push_task_synchronous(session->serializer, fixup, &fix_data)) {
+	if (channel->session->channel != oldchan) {
+		return -1;
+	}
+
+	if (ast_sip_push_task_synchronous(channel->session->serializer, fixup, &fix_data)) {
 		ast_log(LOG_WARNING, "Unable to perform channel fixup\n");
 		return -1;
 	}
@@ -990,8 +991,8 @@
 /*! \brief Function called by core to ask the channel to indicate some sort of condition */
 static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_sip_session_media *media;
 	int response_code = 0;
 	int res = 0;
@@ -999,7 +1000,7 @@
 	switch (condition) {
 	case AST_CONTROL_RINGING:
 		if (ast_channel_state(ast) == AST_STATE_RING) {
-			if (session->endpoint->inband_progress) {
+			if (channel->session->endpoint->inband_progress) {
 				response_code = 183;
 				res = -1;
 			} else {
@@ -1008,7 +1009,7 @@
 		} else {
 			res = -1;
 		}
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Gulp/%s", ast_sorcery_object_get_id(session->endpoint));
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Gulp/%s", ast_sorcery_object_get_id(channel->session->endpoint));
 		break;
 	case AST_CONTROL_BUSY:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
@@ -1048,19 +1049,19 @@
 	case AST_CONTROL_VIDUPDATE:
 		media = pvt->media[SIP_MEDIA_VIDEO];
 		if (media && media->rtp) {
-			ao2_ref(session, +1);
-
-			if (ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session)) {
-				ao2_cleanup(session);
+			ao2_ref(channel->session, +1);
+
+			if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
+				ao2_cleanup(channel->session);
 			}
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_CONNECTED_LINE:
-		ao2_ref(session, +1);
-		if (ast_sip_push_task(session->serializer, update_connected_line_information, session)) {
-			ao2_cleanup(session);
+		ao2_ref(channel->session, +1);
+		if (ast_sip_push_task(channel->session->serializer, update_connected_line_information, channel->session)) {
+			ao2_cleanup(channel->session);
 		}
 		break;
 	case AST_CONTROL_UPDATE_RTP_PEER:
@@ -1095,10 +1096,10 @@
 	}
 
 	if (response_code) {
-		struct indicate_data *ind_data = indicate_data_alloc(session, condition, response_code, data, datalen);
-		if (!ind_data || ast_sip_push_task(session->serializer, indicate, ind_data)) {
+		struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
+		if (!ind_data || ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
 			ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
-					response_code, ast_sorcery_object_get_id(session->endpoint));
+					response_code, ast_sorcery_object_get_id(channel->session->endpoint));
 			ao2_cleanup(ind_data);
 			res = -1;
 		}
@@ -1214,15 +1215,14 @@
 /*! \brief Function called by core for Asterisk initiated transfer */
 static int gulp_transfer(struct ast_channel *chan, const char *target)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
-	struct ast_sip_session *session = pvt->session;
-	struct transfer_data *trnf_data = transfer_data_alloc(session, target);
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+	struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
 
 	if (!trnf_data) {
 		return -1;
 	}
 
-	if (ast_sip_push_task(session->serializer, transfer, trnf_data)) {
+	if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
 		ast_log(LOG_WARNING, "Error requesting transfer\n");
 		ao2_cleanup(trnf_data);
 		return -1;
@@ -1234,12 +1234,12 @@
 /*! \brief Function called by core to start a DTMF digit */
 static int gulp_digit_begin(struct ast_channel *chan, char digit)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
 	int res = 0;
 
-	switch (session->endpoint->dtmf) {
+	switch (channel->session->endpoint->dtmf) {
 	case AST_SIP_DTMF_RFC_4733:
 		if (!media || !media->rtp) {
 			return -1;
@@ -1322,21 +1322,21 @@
 /*! \brief Function called by core to stop a DTMF digit */
 static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
 	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
 	int res = 0;
 
-	switch (session->endpoint->dtmf) {
+	switch (channel->session->endpoint->dtmf) {
 	case AST_SIP_DTMF_INFO:
 	{
-		struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(session, digit, duration);
+		struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
 
 		if (!dtmf_data) {
 			return -1;
 		}
 
-		if (ast_sip_push_task(session->serializer, transmit_info_dtmf, dtmf_data)) {
+		if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
 			ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
 			ao2_cleanup(dtmf_data);
 			return -1;
@@ -1378,13 +1378,12 @@
 /*! \brief Function called by core to actually start calling a remote party */
 static int gulp_call(struct ast_channel *ast, const char *dest, int timeout)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
-
-	ao2_ref(session, +1);
-	if (ast_sip_push_task(session->serializer, call, session)) {
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+
+	ao2_ref(channel->session, +1);
+	if (ast_sip_push_task(channel->session->serializer, call, channel->session)) {
 		ast_log(LOG_WARNING, "Error attempting to place outbound call to call '%s'\n", dest);
-		ao2_cleanup(session);
+		ao2_cleanup(channel->session);
 		return -1;
 	}
 
@@ -1484,8 +1483,9 @@
 	pjsip_tx_data *packet = NULL;
 	struct hangup_data *h_data = data;
 	struct ast_channel *ast = h_data->chan;
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
+	struct ast_sip_session *session = channel->session;
 	int cause = h_data->cause;
 
 	if (!session->defer_terminate &&
@@ -1507,16 +1507,16 @@
 /*! \brief Function called by core to hang up a Gulp session */
 static int gulp_hangup(struct ast_channel *ast)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct ast_sip_session *session = pvt->session;
-	int cause = hangup_cause2sip(ast_channel_hangupcause(session->channel));
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct gulp_pvt *pvt = channel->pvt;
+	int cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
 	struct hangup_data *h_data = hangup_data_alloc(cause, ast);
 
 	if (!h_data) {
 		goto failure;
 	}
 
-	if (ast_sip_push_task(session->serializer, hangup, h_data)) {
+	if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
 		ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
 		goto failure;
 	}
@@ -1527,7 +1527,7 @@
 	/* Go ahead and do our cleanup of the session and channel even if we're not going
 	 * to be able to send our SIP request/response
 	 */
-	clear_session_and_channel(session, ast, pvt);
+	clear_session_and_channel(channel->session, ast, pvt);
 	ao2_cleanup(pvt);
 	ao2_cleanup(h_data);
 
@@ -1665,10 +1665,10 @@
 /*! \brief Function called by core to send text on Gulp session */
 static int gulp_sendtext(struct ast_channel *ast, const char *text)
 {
-	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
-	struct sendtext_data *data = sendtext_data_create(pvt->session, text);
-
-	if (!data || ast_sip_push_task(pvt->session->serializer, sendtext, data)) {
+	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
+	struct sendtext_data *data = sendtext_data_create(channel->session, text);
+
+	if (!data || ast_sip_push_task(channel->session->serializer, sendtext, data)) {
 		ao2_ref(data, -1);
 		return -1;
 	}

Modified: trunk/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/res_sip_session.h?view=diff&rev=395102&r1=395101&r2=395102
==============================================================================
--- trunk/include/asterisk/res_sip_session.h (original)
+++ trunk/include/asterisk/res_sip_session.h Tue Jul 23 07:27:03 2013
@@ -273,6 +273,27 @@
 };
 
 /*!
+ * \brief A structure which contains a channel implementation and session
+ */
+struct ast_sip_channel_pvt {
+	/*! \brief Pointer to channel specific implementation information, must be ao2 object */
+	void *pvt;
+	/*! \brief Pointer to session */
+	struct ast_sip_session *session;
+};
+
+/*!
+ * \brief Allocate a new SIP channel pvt structure
+ *
+ * \param pvt Pointer to channel specific implementation
+ * \param session Pointer to SIP session
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session);
+
+/*!
  * \brief Allocate a new SIP session
  *
  * This will take care of allocating the datastores container on the session as well

Modified: trunk/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_sip_session.c?view=diff&rev=395102&r1=395101&r2=395102
==============================================================================
--- trunk/res/res_sip_session.c (original)
+++ trunk/res/res_sip_session.c Tue Jul 23 07:27:03 2013
@@ -899,6 +899,31 @@
 	strcpy(session_media->stream_type, handler_list->stream_type);
 	ao2_link(session->media, session_media);
 	return 0;
+}
+
+/*! \brief Destructor for SIP channel */
+static void sip_channel_destroy(void *obj)
+{
+	struct ast_sip_channel_pvt *channel = obj;
+
+	ao2_cleanup(channel->pvt);
+	ao2_cleanup(channel->session);
+}
+
+struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
+{
+	struct ast_sip_channel_pvt *channel = ao2_alloc(sizeof(*channel), sip_channel_destroy);
+
+	if (!channel) {
+		return NULL;
+	}
+
+	ao2_ref(pvt, +1);
+	channel->pvt = pvt;
+	ao2_ref(session, +1);
+	channel->session = session;
+
+	return channel;
 }
 
 struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv_session)

Modified: trunk/res/res_sip_session.exports.in
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_sip_session.exports.in?view=diff&rev=395102&r1=395101&r2=395102
==============================================================================
--- trunk/res/res_sip_session.exports.in (original)
+++ trunk/res/res_sip_session.exports.in Tue Jul 23 07:27:03 2013
@@ -16,6 +16,7 @@
 		LINKER_SYMBOL_PREFIXast_sip_session_create_invite;
 		LINKER_SYMBOL_PREFIXast_sip_session_create_outgoing;
 		LINKER_SYMBOL_PREFIXast_sip_dialog_get_session;
+		LINKER_SYMBOL_PREFIXast_sip_channel_pvt_alloc;
 	local:
 		*;
 };




More information about the svn-commits mailing list