Beispiel #1
0
/*! \brief Helper function which retrieves or allocates a T.38 state information datastore */
static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session)
{
	RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup);
	struct t38_state *state;

	/* While the datastore refcount is decremented this is operating in the serializer so it will remain valid regardless */
	if (datastore) {
		return datastore->data;
	}

	if (!(datastore = ast_sip_session_alloc_datastore(&t38_datastore, "t38"))
		|| !(datastore->data = ast_calloc(1, sizeof(struct t38_state)))
		|| ast_sip_session_add_datastore(session, datastore)) {
		return NULL;
	}

	state = datastore->data;

	/* This will get bumped up before scheduling */
	state->timer.user_data = session;
	state->timer.cb = t38_automatic_reject_timer_cb;

	datastore->data = state;

	return state;
}
Beispiel #2
0
/*!
 * \internal
 * \brief Session supplement callback on an incoming INVITE request
 *
 * Retrieve the header_datastore from the session or create one if it doesn't exist.
 * Create and initialize the list if needed.
 * Insert the headers.
 */
static int incoming_request(struct ast_sip_session *session, pjsip_rx_data * rdata)
{
	pj_pool_t *pool = session->inv_session->dlg->pool;
	RAII_VAR(struct ast_datastore *, datastore,
			 ast_sip_session_get_datastore(session, header_datastore.type), ao2_cleanup);

	if (!datastore) {
		if (!(datastore =
			  ast_sip_session_alloc_datastore(&header_datastore, header_datastore.type))
			||
			!(datastore->data = pj_pool_alloc(pool, sizeof(struct hdr_list))) ||
			ast_sip_session_add_datastore(session, datastore)) {
			ast_log(AST_LOG_ERROR, "Unable to create datastore for header functions.\n");
			return 0;
		}
		AST_LIST_HEAD_INIT((struct hdr_list *) datastore->data);
	}
	insert_headers(pool, (struct hdr_list *) datastore->data, rdata->msg_info.msg);

	return 0;
}
Beispiel #3
0
/*!
 * \internal
 * \brief Implements PJSIP_HEADER 'add' by inserting the specified header into thge list.
 *
 * Retrieve the header_datastore from the session or create one if it doesn't exist.
 * Create and initialize the list if needed.
 * Create the pj_strs for name and value.
 * Create pjsip_msg and hdr_list_entry.
 * Add the entry to the list.
 */
static int add_header(void *obj)
{
	struct header_data *data = obj;
	struct ast_sip_session *session = data->channel->session;
	pj_pool_t *pool = session->inv_session->dlg->pool;
	pj_str_t pj_header_name;
	pj_str_t pj_header_value;
	struct hdr_list_entry *le;
	struct hdr_list *list;

	RAII_VAR(struct ast_datastore *, datastore,
			 ast_sip_session_get_datastore(session, header_datastore.type), ao2_cleanup);

	if (!datastore) {
		if (!(datastore = ast_sip_session_alloc_datastore(&header_datastore,
														  header_datastore.type))
			|| !(datastore->data = pj_pool_alloc(pool, sizeof(struct hdr_list)))
			|| ast_sip_session_add_datastore(session, datastore)) {
			ast_log(AST_LOG_ERROR, "Unable to create datastore for header functions.\n");
			return -1;
		}
		AST_LIST_HEAD_INIT((struct hdr_list *) datastore->data);
	}

	ast_debug(1, "Adding header %s with value %s\n", data->header_name,
			  data->header_value);

	pj_cstr(&pj_header_name, data->header_name);
	pj_cstr(&pj_header_value, data->header_value);
	le = pj_pool_zalloc(pool, sizeof(struct hdr_list_entry));
	le->hdr = (pjsip_hdr *) pjsip_generic_string_hdr_create(pool, &pj_header_name,
															&pj_header_value);
	list = datastore->data;

	AST_LIST_INSERT_TAIL(list, le, nextptr);

	return 0;
}
static int handle_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
	struct ast_datastore *sip_session_datastore;
	struct ast_channel *other_party;
	int has_feature;
	int has_reason;

	if (!session->channel) {
		return 0;
	}

	has_feature = has_call_feature(rdata);
	has_reason = has_diversion_reason(rdata);
	if (!has_feature && !has_reason) {
		/* If we don't have a call feature or diversion reason or if
		   it's not a feature this module is related to then there
		   is nothing to do. */
		return 0;
	}

	/* Check bridge status... */
	other_party = ast_channel_bridge_peer(session->channel);
	if (!other_party) {
		/* The channel wasn't in a two party bridge */
		ast_log(LOG_WARNING, "%s (%s) attempted to transfer to voicemail, "
			"but was not in a two party bridge.\n",
			ast_sorcery_object_get_id(session->endpoint),
			ast_channel_name(session->channel));
		send_response(session, 400, rdata);
		return -1;
	}

	sip_session_datastore = ast_sip_session_alloc_datastore(
		&call_feature_info, DATASTORE_NAME);
	if (!sip_session_datastore) {
		ast_channel_unref(other_party);
		send_response(session, 500, rdata);
		return -1;
	}

	sip_session_datastore->data = other_party;

	if (ast_sip_session_add_datastore(session, sip_session_datastore)) {
		ast_channel_unref(other_party);
		ao2_ref(sip_session_datastore, -1);
		send_response(session, 500, rdata);
		return -1;
	}
	ao2_ref(sip_session_datastore, -1);

	if (has_feature) {
		pbx_builtin_setvar_helper(other_party, SEND_TO_VM_HEADER,
					  SEND_TO_VM_HEADER_VALUE);
	}

	if (has_reason) {
		pbx_builtin_setvar_helper(other_party, SEND_TO_VM_REDIRECT,
					  SEND_TO_VM_REDIRECT_VALUE);
	}

	return 0;
}