mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395102 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -114,7 +114,6 @@ enum sip_session_media_position { | ||||
| }; | ||||
|  | ||||
| struct gulp_pvt { | ||||
| 	struct ast_sip_session *session; | ||||
| 	struct ast_sip_session_media *media[SIP_MEDIA_SIZE]; | ||||
| }; | ||||
|  | ||||
| @@ -123,9 +122,6 @@ static void gulp_pvt_dtor(void *obj) | ||||
| 	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]); | ||||
| 		pvt->media[i] = NULL; | ||||
| @@ -336,12 +332,12 @@ static int media_offer_write_av(void *obj) | ||||
|  | ||||
| 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_read(struct ast_channel *chan, const char *cmd, char *dat | ||||
|  | ||||
| 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 @@ static int media_offer_write(struct ast_channel *chan, const char *cmd, char *da | ||||
| 		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 @@ static struct ast_custom_function media_offer_function = { | ||||
| /*! \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 @@ static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, stru | ||||
| /*! \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); | ||||
| 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); | ||||
| 	struct gulp_pvt *pvt = channel->pvt; | ||||
|  | ||||
| 	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) { | ||||
| 	if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) { | ||||
| 		return AST_RTP_GLUE_RESULT_FORBID; | ||||
| 	} | ||||
|  | ||||
| @@ -412,9 +410,9 @@ static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, str | ||||
| /*! \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); | ||||
| 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); | ||||
|  | ||||
| 	ast_format_cap_copy(result, pvt->session->endpoint->codecs); | ||||
| 	ast_format_cap_copy(result, channel->session->endpoint->codecs); | ||||
| } | ||||
|  | ||||
| static int send_direct_media_request(void *data) | ||||
| @@ -486,8 +484,9 @@ static int gulp_set_rtp_peer(struct ast_channel *chan, | ||||
| 		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 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, | ||||
| { | ||||
| 	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,20 +552,22 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, | ||||
|  | ||||
| 	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)); | ||||
| 	} | ||||
| @@ -573,7 +575,6 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, | ||||
| 		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); | ||||
| 	} else { | ||||
| @@ -637,8 +638,7 @@ static int answer(void *data) | ||||
| /*! \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 @@ static int gulp_answer(struct ast_channel *ast) | ||||
|  | ||||
| 	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 @@ static int gulp_answer(struct ast_channel *ast) | ||||
| /*! \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 @@ static struct ast_frame *gulp_read(struct ast_channel *ast) | ||||
| 		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 @@ static struct ast_frame *gulp_read(struct ast_channel *ast) | ||||
| /*! \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 @@ struct fixup_data { | ||||
| static int fixup(void *data) | ||||
| { | ||||
| 	struct fixup_data *fix_data = data; | ||||
| 	struct gulp_pvt *pvt = ast_channel_tech_pvt(fix_data->chan); | ||||
| 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(fix_data->chan); | ||||
| 	struct gulp_pvt *pvt = channel->pvt; | ||||
|  | ||||
| 	fix_data->session->channel = fix_data->chan; | ||||
| 	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 @@ static int fixup(void *data) | ||||
| /*! \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) { | ||||
| 	if (channel->session->channel != oldchan) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_sip_push_task_synchronous(session->serializer, fixup, &fix_data)) { | ||||
| 	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 @@ static int update_connected_line_information(void *data) | ||||
| /*! \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 @@ static int gulp_indicate(struct ast_channel *ast, int condition, const void *dat | ||||
| 	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 @@ static int gulp_indicate(struct ast_channel *ast, int condition, const void *dat | ||||
| 		} 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 @@ static int gulp_indicate(struct ast_channel *ast, int condition, const void *dat | ||||
| 	case AST_CONTROL_VIDUPDATE: | ||||
| 		media = pvt->media[SIP_MEDIA_VIDEO]; | ||||
| 		if (media && media->rtp) { | ||||
| 			ao2_ref(session, +1); | ||||
| 			ao2_ref(channel->session, +1); | ||||
|  | ||||
| 			if (ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session)) { | ||||
| 				ao2_cleanup(session); | ||||
| 			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 @@ static int gulp_indicate(struct ast_channel *ast, int condition, const void *dat | ||||
| 	} | ||||
|  | ||||
| 	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 @@ static int transfer(void *data) | ||||
| /*! \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 @@ static int gulp_transfer(struct ast_channel *chan, const char *target) | ||||
| /*! \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 @@ static int transmit_info_dtmf(void *data) | ||||
| /*! \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 @@ static int call(void *data) | ||||
| /*! \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; | ||||
| 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast); | ||||
|  | ||||
| 	ao2_ref(session, +1); | ||||
| 	if (ast_sip_push_task(session->serializer, call, session)) { | ||||
| 	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 @@ static int hangup(void *data) | ||||
| 	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 @@ static int hangup(void *data) | ||||
| /*! \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 @@ failure: | ||||
| 	/* 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 @@ static int sendtext(void *obj) | ||||
| /*! \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); | ||||
| 	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(pvt->session->serializer, sendtext, data)) { | ||||
| 	if (!data || ast_sip_push_task(channel->session->serializer, sendtext, data)) { | ||||
| 		ao2_ref(data, -1); | ||||
| 		return -1; | ||||
| 	} | ||||
|   | ||||
| @@ -272,6 +272,27 @@ struct ast_sip_session_sdp_handler { | ||||
| 	AST_LIST_ENTRY(ast_sip_session_sdp_handler) next; | ||||
| }; | ||||
|  | ||||
| /*! | ||||
|  * \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 | ||||
|  * | ||||
|   | ||||
| @@ -901,6 +901,31 @@ static int add_session_media(void *obj, void *arg, int flags) | ||||
| 	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) | ||||
| { | ||||
| 	RAII_VAR(struct ast_sip_session *, session, ao2_alloc(sizeof(*session), session_destructor), ao2_cleanup); | ||||
|   | ||||
| @@ -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: | ||||
| 		*; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user