chan_pjsip.c File Reference

PSJIP SIP Channel Driver. More...

#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include <pjlib.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/causes.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/dsp.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/indications.h"
#include "asterisk/format_cache.h"
#include "asterisk/translate.h"
#include "asterisk/threadstorage.h"
#include "asterisk/features_config.h"
#include "asterisk/pickup.h"
#include "asterisk/test.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "pjsip/include/chan_pjsip.h"
#include "pjsip/include/dialplan_functions.h"

Include dependency graph for chan_pjsip.c:

Go to the source code of this file.

Data Structures

struct  hangup_data
struct  indicate_data
struct  info_dtmf_data
struct  request_data
struct  sendtext_data
struct  transfer_data

Defines

#define UNIQUEID_BUFSIZE   256

Functions

static void __init_uniqueid_threadbuf (void)
static void __reg_module (void)
static void __unreg_module (void)
static int answer (void *data)
static int call (void *data)
static int call_pickup_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
static int chan_pjsip_add_hold (const char *chan_uid)
 Add a channel ID to the list of PJSIP channels on hold.
static int chan_pjsip_answer (struct ast_channel *ast)
 Function called by core when we should answer a PJSIP session.
static int chan_pjsip_call (struct ast_channel *ast, const char *dest, int timeout)
 Function called by core to actually start calling a remote party.
static struct ast_framechan_pjsip_cng_tone_detected (struct ast_sip_session *session, struct ast_frame *f)
 Internal helper function called when CNG tone is detected.
static int chan_pjsip_devicestate (const char *data)
 Function called to get the device state of an endpoint.
static int chan_pjsip_digit_begin (struct ast_channel *chan, char digit)
 Function called by core to start a DTMF digit.
static int chan_pjsip_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Function called by core to stop a DTMF digit.
static int chan_pjsip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 Function called by core to change the underlying owner channel.
static void chan_pjsip_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
 Function called by RTP engine to get peer capabilities.
static int chan_pjsip_get_hold (const char *chan_uid)
 Determine whether a channel ID is in the list of PJSIP channels on hold.
static enum ast_rtp_glue_result chan_pjsip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 Function called by RTP engine to get local audio RTP peer.
static const char * chan_pjsip_get_uniqueid (struct ast_channel *ast)
static enum ast_rtp_glue_result chan_pjsip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **instance)
 Function called by RTP engine to get local video RTP peer.
static int chan_pjsip_hangup (struct ast_channel *ast)
 Function called by core to hang up a PJSIP session.
static int chan_pjsip_incoming_ack (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static int chan_pjsip_incoming_request (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a request is received on the session.
static void chan_pjsip_incoming_response (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 Function called when a response is received on the session.
static int chan_pjsip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Function called by core to ask the channel to indicate some sort of condition.
static struct ast_channelchan_pjsip_new (struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
 Function called to create a new PJSIP Asterisk channel.
static void chan_pjsip_pvt_dtor (void *obj)
static int chan_pjsip_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
 Function called to query options on a channel.
static struct ast_framechan_pjsip_read (struct ast_channel *ast)
 Function called by core to read any waiting frames.
static void chan_pjsip_remove_hold (const char *chan_uid)
 Remove a channel ID from the list of PJSIP channels on hold.
static struct ast_channelchan_pjsip_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Function called by core to create a new outgoing PJSIP session.
static int chan_pjsip_sendtext (struct ast_channel *ast, const char *text)
 Function called by core to send text on PJSIP session.
static void chan_pjsip_session_begin (struct ast_sip_session *session)
 SIP session interaction functions.
static void chan_pjsip_session_end (struct ast_sip_session *session)
 Function called when the session ends.
static int chan_pjsip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
 Function called by RTP engine to change where the remote party should send media.
static int chan_pjsip_transfer (struct ast_channel *chan, const char *target)
 Function called by core for Asterisk initiated transfer.
static int chan_pjsip_write (struct ast_channel *ast, struct ast_frame *frame)
 Function called by core to write frames.
static int check_for_rtp_changes (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_sip_session_media *media, int rtcp_fd)
static void clear_session_and_channel (struct ast_sip_session *session, struct ast_channel *ast, struct chan_pjsip_pvt *pvt)
 Clear a channel from a session along with its PVT.
static int direct_media_mitigate_glare (struct ast_sip_session *session)
static int hangup (void *data)
static int hangup_cause2sip (int cause)
 Internal function which translates from Asterisk cause codes to SIP response codes.
static struct hangup_datahangup_data_alloc (int cause, struct ast_channel *chan)
static void hangup_data_destroy (void *obj)
static int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int indicate (void *data)
static struct indicate_dataindicate_data_alloc (struct ast_sip_session *session, int condition, int response_code, const void *frame_data, size_t datalen)
static void indicate_data_destroy (void *obj)
static struct info_dtmf_datainfo_dtmf_data_alloc (struct ast_sip_session *session, char digit, unsigned int duration)
static void info_dtmf_data_destroy (void *obj)
static int is_colp_update_allowed (struct ast_sip_session *session)
static int load_module (void)
 Load the module.
static int local_hold_set_state (void *obj, void *arg, int flags)
 Callback which changes the value of locally held on the media stream.
static int pbx_start_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
static int remote_send_hold (void *data)
 Update local hold state to be held.
static int remote_send_hold_refresh (struct ast_sip_session *session, unsigned int held)
 Update local hold state and send a re-INVITE with the new SDP.
static int remote_send_unhold (void *data)
 Update local hold state to be unheld.
static int request (void *obj)
static int send_direct_media_request (void *data)
static int sendtext (void *obj)
static struct sendtext_datasendtext_data_create (struct ast_sip_session *session, const char *text)
static void sendtext_data_destroy (void *obj)
static void set_channel_on_rtp_instance (struct chan_pjsip_pvt *pvt, const char *channel_id)
static int transfer (void *data)
static struct transfer_datatransfer_data_alloc (struct ast_sip_session *session, const char *target)
static void transfer_data_destroy (void *obj)
static void transfer_redirect (struct ast_sip_session *session, const char *target)
static void transfer_refer (struct ast_sip_session *session, const char *target)
static int transmit_info_dtmf (void *data)
static int transmit_info_with_vidupdate (void *data)
 Send SIP INFO with video update request.
static void transport_info_destroy (void *obj)
 Destructor function for transport_info_data.
static int uid_hold_hash_fn (const void *obj, const int flags)
static int uid_hold_sort_fn (const void *obj_left, const void *obj_right, const int flags)
static int unload_module (void)
 Unload the PJSIP channel from Asterisk.
static int update_connected_line_information (void *data)
 Update connected line information.
static int update_devstate (void *obj, void *arg, int flags)
static void update_initial_connected_line (struct ast_sip_session *session)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static struct ast_module_infoast_module_info = &__mod_info
static struct
ast_sip_session_supplement 
call_pickup_supplement
static unsigned int chan_idx
static struct
ast_sip_session_supplement 
chan_pjsip_ack_supplement
static struct ast_custom_function chan_pjsip_dial_contacts_function
static struct ast_rtp_glue chan_pjsip_rtp_glue
 Local glue for interacting with the RTP engine core.
static struct
ast_sip_session_supplement 
chan_pjsip_supplement
 SIP session supplement structure.
struct ast_channel_tech chan_pjsip_tech
 PBX interface structure for channel registration.
static const char channel_type [] = "PJSIP"
static struct ast_datastore_info direct_media_mitigation_info = { }
static struct ast_custom_function media_offer_function
static struct
ast_sip_session_supplement 
pbx_start_supplement
static struct ao2_containerpjsip_uids_onhold
static struct ast_datastore_info transport_info
 Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel.
static struct ast_threadstorage uniqueid_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_uniqueid_threadbuf , .custom_init = NULL , }


Detailed Description

PSJIP SIP Channel Driver.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file chan_pjsip.c.


Define Documentation

#define UNIQUEID_BUFSIZE   256

Definition at line 74 of file chan_pjsip.c.

Referenced by chan_pjsip_get_uniqueid().


Function Documentation

static void __init_uniqueid_threadbuf ( void   )  [static]

Definition at line 73 of file chan_pjsip.c.

00081 {

static void __reg_module ( void   )  [static]

Definition at line 2428 of file chan_pjsip.c.

static void __unreg_module ( void   )  [static]

Definition at line 2428 of file chan_pjsip.c.

static int answer ( void *  data  )  [static]

Definition at line 489 of file chan_pjsip.c.

References ast_channel_name(), ast_log, ast_sip_session_send_response(), ast_sip_session::channel, ast_sip_session::inv_session, LOG_ERROR, NULL, session, and status.

Referenced by add_sdp_streams(), ast_raw_answer(), chan_pjsip_answer(), dump_answer(), find_and_retrans(), pbx_builtin_incomplete(), session_inv_on_rx_offer(), tds_log(), verify_mock_cdr_record(), and zapateller_exec().

00490 {
00491    pj_status_t status = PJ_SUCCESS;
00492    pjsip_tx_data *packet = NULL;
00493    struct ast_sip_session *session = data;
00494 
00495    if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
00496       return 0;
00497    }
00498 
00499    pjsip_dlg_inc_lock(session->inv_session->dlg);
00500    if (session->inv_session->invite_tsx) {
00501       status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet);
00502    } else {
00503       ast_log(LOG_ERROR,"Cannot answer '%s' because there is no associated SIP transaction\n",
00504          ast_channel_name(session->channel));
00505    }
00506    pjsip_dlg_dec_lock(session->inv_session->dlg);
00507 
00508    if (status == PJ_SUCCESS && packet) {
00509       ast_sip_session_send_response(session, packet);
00510    }
00511 
00512    return (status == PJ_SUCCESS) ? 0 : -1;
00513 }

static int call ( void *  data  )  [static]

Definition at line 1664 of file chan_pjsip.c.

References ao2_ref, ast_channel_name(), ast_channel_uniqueid(), ast_queue_hangup(), ast_set_hangupsource(), ast_sip_session_create_invite(), ast_sip_session_send_request(), ast_sip_session::channel, ast_sip_channel_pvt::pvt, ast_sip_channel_pvt::session, session, set_channel_on_rtp_instance(), and update_initial_connected_line().

Referenced by ast_call(), ast_create_callid(), chan_pjsip_call(), and native_start().

01665 {
01666    struct ast_sip_channel_pvt *channel = data;
01667    struct ast_sip_session *session = channel->session;
01668    struct chan_pjsip_pvt *pvt = channel->pvt;
01669    pjsip_tx_data *tdata;
01670 
01671    int res = ast_sip_session_create_invite(session, &tdata);
01672 
01673    if (res) {
01674       ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
01675       ast_queue_hangup(session->channel);
01676    } else {
01677       set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(session->channel));
01678       update_initial_connected_line(session);
01679       ast_sip_session_send_request(session, tdata);
01680    }
01681    ao2_ref(channel, -1);
01682    return res;
01683 }

static int call_pickup_incoming_request ( struct ast_sip_session session,
pjsip_rx_data *  rdata 
) [static]

Definition at line 2149 of file chan_pjsip.c.

References ao2_ref, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_hangupcause_set(), ast_channel_ref, ast_channel_unref, ast_get_chan_features_pickup_config(), ast_hangup(), ast_log, ast_pickup_call(), ast_sip_session::channel, ast_sip_session::exten, ast_sip_session::inv_session, LOG_ERROR, and ast_features_pickup_config::pickupexten.

02150 {
02151    struct ast_features_pickup_config *pickup_cfg;
02152    struct ast_channel *chan;
02153 
02154    /* We don't care about reinvites */
02155    if (session->inv_session->state >= PJSIP_INV_STATE_CONFIRMED) {
02156       return 0;
02157    }
02158 
02159    pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
02160    if (!pickup_cfg) {
02161       ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
02162       return 0;
02163    }
02164 
02165    if (strcmp(session->exten, pickup_cfg->pickupexten)) {
02166       ao2_ref(pickup_cfg, -1);
02167       return 0;
02168    }
02169    ao2_ref(pickup_cfg, -1);
02170 
02171    /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
02172     * changing the channel pointer in session to a different channel. To ensure we work on the right channel
02173     * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
02174     */
02175    chan = ast_channel_ref(session->channel);
02176    if (ast_pickup_call(chan)) {
02177       ast_channel_hangupcause_set(chan, AST_CAUSE_CALL_REJECTED);
02178    } else {
02179       ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
02180    }
02181    /* A hangup always occurs because the pickup operation will have either failed resulting in the call
02182     * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
02183     * the channel that was replaced, which should be hung up since it is literally in limbo not connected
02184     * to anything at all.
02185     */
02186    ast_hangup(chan);
02187    ast_channel_unref(chan);
02188 
02189    return 1;
02190 }

static int chan_pjsip_add_hold ( const char *  chan_uid  )  [static]

Add a channel ID to the list of PJSIP channels on hold.

Parameters:
chan_uid - Unique ID of the channel being put into the hold list
Return values:
0 Channel has been added to or was already in the hold list
-1 Failed to add channel to the hold list

Definition at line 775 of file chan_pjsip.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_find, ao2_link, ast_copy_string(), NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_indicate().

00776 {
00777    RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
00778 
00779    hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
00780    if (hold_uid) {
00781       /* Device is already on hold. Nothing to do. */
00782       return 0;
00783    }
00784 
00785    /* Device wasn't in hold list already. Create a new one. */
00786    hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
00787       AO2_ALLOC_OPT_LOCK_NOLOCK);
00788    if (!hold_uid) {
00789       return -1;
00790    }
00791 
00792    ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
00793 
00794    if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
00795       return -1;
00796    }
00797 
00798    return 0;
00799 }

static int chan_pjsip_answer ( struct ast_channel ast  )  [static]

Function called by core when we should answer a PJSIP session.

Definition at line 516 of file chan_pjsip.c.

References answer(), ao2_bump, ao2_ref, ast_channel_lock, ast_channel_tech_pvt(), ast_channel_unlock, ast_log, ast_setstate(), ast_sip_push_task_synchronous(), AST_STATE_UP, LOG_WARNING, ast_sip_session::serializer, ast_sip_channel_pvt::session, and session.

00517 {
00518    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
00519    struct ast_sip_session *session;
00520 
00521    if (ast_channel_state(ast) == AST_STATE_UP) {
00522       return 0;
00523    }
00524 
00525    ast_setstate(ast, AST_STATE_UP);
00526    session = ao2_bump(channel->session);
00527 
00528    /* the answer task needs to be pushed synchronously otherwise a race condition
00529       can occur between this thread and bridging (specifically when native bridging
00530       attempts to do direct media) */
00531    ast_channel_unlock(ast);
00532    if (ast_sip_push_task_synchronous(session->serializer, answer, session)) {
00533       ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
00534       ao2_ref(session, -1);
00535       ast_channel_lock(ast);
00536       return -1;
00537    }
00538    ao2_ref(session, -1);
00539    ast_channel_lock(ast);
00540 
00541    return 0;
00542 }

static int chan_pjsip_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
) [static]

Function called by core to actually start calling a remote party.

Definition at line 1686 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), call(), LOG_WARNING, ast_sip_session::serializer, and ast_sip_channel_pvt::session.

01687 {
01688    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01689 
01690    ao2_ref(channel, +1);
01691    if (ast_sip_push_task(channel->session->serializer, call, channel)) {
01692       ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
01693       ao2_cleanup(channel);
01694       return -1;
01695    }
01696 
01697    return 0;
01698 }

static struct ast_frame* chan_pjsip_cng_tone_detected ( struct ast_sip_session session,
struct ast_frame f 
) [static, read]

Internal helper function called when CNG tone is detected.

Definition at line 545 of file chan_pjsip.c.

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_name(), ast_channel_unlock, ast_dsp_free(), ast_dsp_set_features(), ast_exists_extension(), ast_frfree, ast_log, ast_null_frame, AST_SIP_DTMF_AUTO, AST_SIP_DTMF_INBAND, ast_verb, ast_sip_session::channel, ast_sip_session::dsp, DSP_FEATURE_DIGIT_DETECT, ast_sip_endpoint::dtmf, ast_sip_session::endpoint, exists(), ast_party_caller::id, LOG_ERROR, LOG_NOTICE, NULL, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, ast_party_number::str, and ast_party_number::valid.

Referenced by chan_pjsip_read().

00546 {
00547    const char *target_context;
00548    int exists;
00549 
00550    /* If we only needed this DSP for fax detection purposes we can just drop it now */
00551    if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND || session->endpoint->dtmf == AST_SIP_DTMF_AUTO) {
00552       ast_dsp_set_features(session->dsp, DSP_FEATURE_DIGIT_DETECT);
00553    } else {
00554       ast_dsp_free(session->dsp);
00555       session->dsp = NULL;
00556    }
00557 
00558    /* If already executing in the fax extension don't do anything */
00559    if (!strcmp(ast_channel_exten(session->channel), "fax")) {
00560       return f;
00561    }
00562 
00563    target_context = S_OR(ast_channel_macrocontext(session->channel), ast_channel_context(session->channel));
00564 
00565    /* We need to unlock the channel here because ast_exists_extension has the
00566     * potential to start and stop an autoservice on the channel. Such action
00567     * is prone to deadlock if the channel is locked.
00568     */
00569    ast_channel_unlock(session->channel);
00570    exists = ast_exists_extension(session->channel, target_context, "fax", 1,
00571       S_COR(ast_channel_caller(session->channel)->id.number.valid,
00572          ast_channel_caller(session->channel)->id.number.str, NULL));
00573    ast_channel_lock(session->channel);
00574 
00575    if (exists) {
00576       ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",
00577          ast_channel_name(session->channel));
00578       pbx_builtin_setvar_helper(session->channel, "FAXEXTEN", ast_channel_exten(session->channel));
00579       if (ast_async_goto(session->channel, target_context, "fax", 1)) {
00580          ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",
00581             ast_channel_name(session->channel), target_context);
00582       }
00583       ast_frfree(f);
00584       f = &ast_null_frame;
00585    } else {
00586       ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",
00587          ast_channel_name(session->channel), target_context);
00588    }
00589 
00590    return f;
00591 }

static int chan_pjsip_devicestate ( const char *  data  )  [static]

Function called to get the device state of an endpoint.

Definition at line 832 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_cache(), ast_channel_snapshot_type(), AST_DEVICE_BUSY, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_aggregate_add(), ast_devstate_aggregate_init(), ast_devstate_aggregate_result(), ast_endpoint_get_resource(), ast_endpoint_get_tech(), ast_endpoint_latest_snapshot(), AST_ENDPOINT_OFFLINE, AST_ENDPOINT_ONLINE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_id(), AST_STATE_BUSY, ast_state_chan2dev(), AST_STATE_RING, AST_STATE_UP, cache, chan_pjsip_get_hold(), ast_devstate_aggregate::inuse, NULL, RAII_VAR, stasis_cache_get(), stasis_message_data(), ast_channel_snapshot::state, and ast_channel_snapshot::uniqueid.

00833 {
00834    RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
00835    enum ast_device_state state = AST_DEVICE_UNKNOWN;
00836    RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
00837    RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
00838    struct ast_devstate_aggregate aggregate;
00839    int num, inuse = 0;
00840 
00841    if (!endpoint) {
00842       return AST_DEVICE_INVALID;
00843    }
00844 
00845    endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
00846       ast_endpoint_get_resource(endpoint->persistent));
00847 
00848    if (!endpoint_snapshot) {
00849       return AST_DEVICE_INVALID;
00850    }
00851 
00852    if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
00853       state = AST_DEVICE_UNAVAILABLE;
00854    } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
00855       state = AST_DEVICE_NOT_INUSE;
00856    }
00857 
00858    if (!endpoint_snapshot->num_channels || !(cache = ast_channel_cache())) {
00859       return state;
00860    }
00861 
00862    ast_devstate_aggregate_init(&aggregate);
00863 
00864    ao2_ref(cache, +1);
00865 
00866    for (num = 0; num < endpoint_snapshot->num_channels; num++) {
00867       RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
00868       struct ast_channel_snapshot *snapshot;
00869 
00870       msg = stasis_cache_get(cache, ast_channel_snapshot_type(),
00871          endpoint_snapshot->channel_ids[num]);
00872 
00873       if (!msg) {
00874          continue;
00875       }
00876 
00877       snapshot = stasis_message_data(msg);
00878 
00879       if (chan_pjsip_get_hold(snapshot->uniqueid)) {
00880          ast_devstate_aggregate_add(&aggregate, AST_DEVICE_ONHOLD);
00881       } else {
00882          ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
00883       }
00884 
00885       if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
00886          (snapshot->state == AST_STATE_BUSY)) {
00887          inuse++;
00888       }
00889    }
00890 
00891    if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
00892       state = AST_DEVICE_BUSY;
00893    } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
00894       state = ast_devstate_aggregate_result(&aggregate);
00895    }
00896 
00897    return state;
00898 }

static int chan_pjsip_digit_begin ( struct ast_channel ast,
char  digit 
) [static]

Function called by core to start a DTMF digit.

Definition at line 1495 of file chan_pjsip.c.

References ast_channel_tech_pvt(), AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_begin(), ast_rtp_instance_dtmf_mode_get(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, ast_sip_endpoint::dtmf, ast_sip_session::endpoint, chan_pjsip_pvt::media, ast_sip_channel_pvt::pvt, ast_sip_session_media::rtp, ast_sip_channel_pvt::session, and SIP_MEDIA_AUDIO.

01496 {
01497    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
01498    struct chan_pjsip_pvt *pvt = channel->pvt;
01499    struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
01500    int res = 0;
01501 
01502    switch (channel->session->endpoint->dtmf) {
01503    case AST_SIP_DTMF_RFC_4733:
01504       if (!media || !media->rtp) {
01505          return -1;
01506       }
01507 
01508       ast_rtp_instance_dtmf_begin(media->rtp, digit);
01509                 break;
01510    case AST_SIP_DTMF_AUTO:
01511                        if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {
01512                         return -1;
01513                 }
01514 
01515                 ast_rtp_instance_dtmf_begin(media->rtp, digit);
01516                 break;
01517    case AST_SIP_DTMF_NONE:
01518       break;
01519    case AST_SIP_DTMF_INBAND:
01520       res = -1;
01521       break;
01522    default:
01523       break;
01524    }
01525 
01526    return res;
01527 }

static int chan_pjsip_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Function called by core to stop a DTMF digit.

Definition at line 1591 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_tech_pvt(), ast_log, AST_RTP_DTMF_MODE_INBAND, ast_rtp_instance_dtmf_end_with_duration(), ast_rtp_instance_dtmf_mode_get(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_INFO, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, ast_sip_push_task(), ast_sip_endpoint::dtmf, ast_sip_session::endpoint, info_dtmf_data_alloc(), LOG_WARNING, chan_pjsip_pvt::media, ast_sip_channel_pvt::pvt, ast_sip_session_media::rtp, ast_sip_session::serializer, ast_sip_channel_pvt::session, SIP_MEDIA_AUDIO, and transmit_info_dtmf().

01592 {
01593    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01594    struct chan_pjsip_pvt *pvt = channel->pvt;
01595    struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
01596    int res = 0;
01597 
01598    switch (channel->session->endpoint->dtmf) {
01599    case AST_SIP_DTMF_INFO:
01600    {
01601       struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
01602 
01603       if (!dtmf_data) {
01604          return -1;
01605       }
01606 
01607       if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
01608          ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
01609          ao2_cleanup(dtmf_data);
01610          return -1;
01611       }
01612       break;
01613    }
01614    case AST_SIP_DTMF_RFC_4733:
01615       if (!media || !media->rtp) {
01616          return -1;
01617       }
01618 
01619       ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);
01620                 break;
01621         case AST_SIP_DTMF_AUTO:
01622                 if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_INBAND)) {
01623                         return -1;
01624                 }
01625 
01626                 ast_rtp_instance_dtmf_end_with_duration(media->rtp, digit, duration);
01627                 break;
01628 
01629    case AST_SIP_DTMF_NONE:
01630       break;
01631    case AST_SIP_DTMF_INBAND:
01632       res = -1;
01633       break;
01634    }
01635 
01636    return res;
01637 }

static int chan_pjsip_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Function called by core to change the underlying owner channel.

Definition at line 702 of file chan_pjsip.c.

References ast_channel_tech_pvt(), ast_channel_uniqueid(), ast_sip_session::channel, ast_sip_channel_pvt::pvt, ast_sip_channel_pvt::session, and set_channel_on_rtp_instance().

00703 {
00704    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
00705    struct chan_pjsip_pvt *pvt = channel->pvt;
00706 
00707    if (channel->session->channel != oldchan) {
00708       return -1;
00709    }
00710 
00711    /*
00712     * The masquerade has suspended the channel's session
00713     * serializer so we can safely change it outside of
00714     * the serializer thread.
00715     */
00716    channel->session->channel = newchan;
00717 
00718    set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(newchan));
00719 
00720    return 0;
00721 }

static void chan_pjsip_get_codec ( struct ast_channel chan,
struct ast_format_cap result 
) [static]

static int chan_pjsip_get_hold ( const char *  chan_uid  )  [static]

Determine whether a channel ID is in the list of PJSIP channels on hold.

Parameters:
chan_uid - Channel being checked
Return values:
0 The channel is not in the hold list
1 The channel is in the hold list

Definition at line 819 of file chan_pjsip.c.

References ao2_cleanup, ao2_find, NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by chan_pjsip_devicestate().

00820 {
00821    RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
00822 
00823    hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
00824    if (!hold_uid) {
00825       return 0;
00826    }
00827 
00828    return 1;
00829 }

static enum ast_rtp_glue_result chan_pjsip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Function called by RTP engine to get local audio RTP peer.

Definition at line 160 of file chan_pjsip.c.

References ao2_ref, ast_assert, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, AST_SIP_MEDIA_ENCRYPT_NONE, ast_sip_endpoint_media_configuration::direct_media, ast_sip_direct_media_configuration::enabled, ast_sip_media_rtp_configuration::encryption, ast_sip_session::endpoint, ast_sip_endpoint::media, chan_pjsip_pvt::media, NULL, ast_sip_channel_pvt::pvt, ast_sip_endpoint_media_configuration::rtp, ast_sip_session_media::rtp, ast_sip_channel_pvt::session, and SIP_MEDIA_AUDIO.

00161 {
00162    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
00163    struct chan_pjsip_pvt *pvt = channel->pvt;
00164    struct ast_sip_endpoint *endpoint;
00165 
00166    if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
00167       return AST_RTP_GLUE_RESULT_FORBID;
00168    }
00169 
00170    endpoint = channel->session->endpoint;
00171 
00172    *instance = pvt->media[SIP_MEDIA_AUDIO]->rtp;
00173    ao2_ref(*instance, +1);
00174 
00175    ast_assert(endpoint != NULL);
00176    if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
00177       return AST_RTP_GLUE_RESULT_FORBID;
00178    }
00179 
00180    if (endpoint->media.direct_media.enabled) {
00181       return AST_RTP_GLUE_RESULT_REMOTE;
00182    }
00183 
00184    return AST_RTP_GLUE_RESULT_LOCAL;
00185 }

static const char * chan_pjsip_get_uniqueid ( struct ast_channel ast  )  [static]

Definition at line 939 of file chan_pjsip.c.

References ast_channel_tech_pvt(), ast_copy_pj_str(), ast_threadstorage_get(), ast_sip_session::inv_session, ast_sip_channel_pvt::session, UNIQUEID_BUFSIZE, and uniqueid_threadbuf.

00940 {
00941    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
00942    char *uniqueid = ast_threadstorage_get(&uniqueid_threadbuf, UNIQUEID_BUFSIZE);
00943 
00944    if (!uniqueid) {
00945       return "";
00946    }
00947 
00948    ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
00949 
00950    return uniqueid;
00951 }

static enum ast_rtp_glue_result chan_pjsip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  instance 
) [static]

Function called by RTP engine to get local video RTP peer.

Definition at line 188 of file chan_pjsip.c.

References ao2_ref, ast_assert, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_SIP_MEDIA_ENCRYPT_NONE, ast_sip_media_rtp_configuration::encryption, ast_sip_session::endpoint, ast_sip_endpoint::media, chan_pjsip_pvt::media, NULL, ast_sip_channel_pvt::pvt, ast_sip_endpoint_media_configuration::rtp, ast_sip_session_media::rtp, ast_sip_channel_pvt::session, and SIP_MEDIA_VIDEO.

00189 {
00190    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
00191    struct chan_pjsip_pvt *pvt = channel->pvt;
00192    struct ast_sip_endpoint *endpoint;
00193 
00194    if (!pvt || !channel->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
00195       return AST_RTP_GLUE_RESULT_FORBID;
00196    }
00197 
00198    endpoint = channel->session->endpoint;
00199 
00200    *instance = pvt->media[SIP_MEDIA_VIDEO]->rtp;
00201    ao2_ref(*instance, +1);
00202 
00203    ast_assert(endpoint != NULL);
00204    if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
00205       return AST_RTP_GLUE_RESULT_FORBID;
00206    }
00207 
00208    return AST_RTP_GLUE_RESULT_LOCAL;
00209 }

static int chan_pjsip_hangup ( struct ast_channel ast  )  [static]

Function called by core to hang up a PJSIP session.

Definition at line 1800 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_hangupcause(), ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), ast_sip_session::channel, clear_session_and_channel(), hangup(), hangup_cause2sip(), hangup_data_alloc(), LOG_WARNING, ast_sip_channel_pvt::pvt, ast_sip_session::serializer, and ast_sip_channel_pvt::session.

01801 {
01802    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01803    struct chan_pjsip_pvt *pvt = channel->pvt;
01804    int cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
01805    struct hangup_data *h_data = hangup_data_alloc(cause, ast);
01806 
01807    if (!h_data) {
01808       goto failure;
01809    }
01810 
01811    if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
01812       ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
01813       goto failure;
01814    }
01815 
01816    return 0;
01817 
01818 failure:
01819    /* Go ahead and do our cleanup of the session and channel even if we're not going
01820     * to be able to send our SIP request/response
01821     */
01822    clear_session_and_channel(channel->session, ast, pvt);
01823    ao2_cleanup(channel);
01824    ao2_cleanup(h_data);
01825 
01826    return -1;
01827 }

static int chan_pjsip_incoming_ack ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
) [static]

Definition at line 2282 of file chan_pjsip.c.

References AST_CONTROL_SRCCHANGE, ast_queue_control(), ast_sip_session::channel, ast_sip_endpoint_media_configuration::direct_media, ast_sip_direct_media_configuration::enabled, ast_sip_session::endpoint, and ast_sip_endpoint::media.

02283 {
02284    if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
02285       if (session->endpoint->media.direct_media.enabled && session->channel) {
02286          ast_queue_control(session->channel, AST_CONTROL_SRCCHANGE);
02287       }
02288    }
02289    return 0;
02290 }

static int chan_pjsip_incoming_request ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
) [static]

Function called when a request is received on the session.

Definition at line 2097 of file chan_pjsip.c.

References ao2_cleanup, ast_calloc, ast_log, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_send_response(), ast_sip_session_terminate(), AST_STATE_RING, chan_pjsip_new(), ast_sip_session::channel, ast_sip_session::defer_terminate, ast_sip_session::exten, ast_sip_session::inv_session, transport_info_data::local_addr, LOG_ERROR, NULL, RAII_VAR, and transport_info_data::remote_addr.

02098 {
02099    RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
02100    struct transport_info_data *transport_data;
02101    pjsip_tx_data *packet = NULL;
02102 
02103    if (session->channel) {
02104       return 0;
02105    }
02106 
02107    if (session->inv_session->state >= PJSIP_INV_STATE_CONFIRMED) {
02108       /* Weird case. We've received a reinvite but we don't have a channel. The most
02109        * typical case for this happening is that a blind transfer fails, and so the
02110        * transferer attempts to reinvite himself back into the call. We already got
02111        * rid of that channel, and the other side of the call is unrecoverable.
02112        *
02113        * We treat this as a failure, so our best bet is to just hang this call
02114        * up and not create a new channel. Clearing defer_terminate here ensures that
02115        * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
02116        */
02117       session->defer_terminate = 0;
02118       ast_sip_session_terminate(session, 400);
02119       return -1;
02120    }
02121 
02122    datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
02123    if (!datastore) {
02124       return -1;
02125    }
02126 
02127    transport_data = ast_calloc(1, sizeof(*transport_data));
02128    if (!transport_data) {
02129       return -1;
02130    }
02131    pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
02132    pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
02133    datastore->data = transport_data;
02134    ast_sip_session_add_datastore(session, datastore);
02135 
02136    if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
02137       if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS) {
02138          ast_sip_session_send_response(session, packet);
02139       }
02140 
02141       ast_log(LOG_ERROR, "Failed to allocate new PJSIP channel on incoming SIP INVITE\n");
02142       return -1;
02143    }
02144    /* channel gets created on incoming request, but we wait to call start
02145            so other supplements have a chance to run */
02146    return 0;
02147 }

static void chan_pjsip_incoming_response ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
) [static]

Function called when a response is received on the session.

Definition at line 2237 of file chan_pjsip.c.

References ast_alloca, ast_control_pvt_cause_code::ast_cause, ast_channel_hangupcause_hash_set(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_name(), ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RINGING, ast_copy_string(), ast_queue_control(), ast_queue_control_data(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_control_pvt_cause_code::chan_name, ast_sip_session::channel, ast_control_pvt_cause_code::code, and hangup_sip2cause().

02238 {
02239    struct pjsip_status_line status = rdata->msg_info.msg->line.status;
02240    struct ast_control_pvt_cause_code *cause_code;
02241    int data_size = sizeof(*cause_code);
02242 
02243    if (!session->channel) {
02244       return;
02245    }
02246 
02247    switch (status.code) {
02248    case 180:
02249       ast_queue_control(session->channel, AST_CONTROL_RINGING);
02250       ast_channel_lock(session->channel);
02251       if (ast_channel_state(session->channel) != AST_STATE_UP) {
02252          ast_setstate(session->channel, AST_STATE_RINGING);
02253       }
02254       ast_channel_unlock(session->channel);
02255       break;
02256    case 183:
02257       ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
02258       break;
02259    case 200:
02260       ast_queue_control(session->channel, AST_CONTROL_ANSWER);
02261       break;
02262    default:
02263       break;
02264    }
02265 
02266    /* Build and send the tech-specific cause information */
02267    /* size of the string making up the cause code is "SIP " number + " " + reason length */
02268    data_size += 4 + 4 + pj_strlen(&status.reason);
02269    cause_code = ast_alloca(data_size);
02270    memset(cause_code, 0, data_size);
02271 
02272    ast_copy_string(cause_code->chan_name, ast_channel_name(session->channel), AST_CHANNEL_NAME);
02273 
02274    snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
02275       (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
02276 
02277    cause_code->ast_cause = hangup_sip2cause(status.code);
02278    ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
02279    ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
02280 }

static int chan_pjsip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Function called by core to ask the channel to indicate some sort of condition.

Definition at line 1161 of file chan_pjsip.c.

References ao2_bump, ao2_cleanup, ao2_ref, ast_assert, ast_channel_get_device_name(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_tech_pvt(), ast_channel_uniqueid(), ast_channel_unlock, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_DEVICE_ONHOLD, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_devstate_changed_literal(), ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_vp8, AST_FRAME_CONTROL, ast_log, ast_moh_start(), ast_moh_stop(), ast_rtp_instance_write(), ast_sip_push_task(), ast_sip_session_suspend(), ast_sip_session_unsuspend(), ast_sorcery_object_get_id(), AST_STATE_RING, AST_STATE_UP, AST_T38_REQUEST_PARMS, ast_test_suite_event_notify, chan_pjsip_add_hold(), chan_pjsip_remove_hold(), ast_sip_session::endpoint, ast_frame::frametype, ast_sip_endpoint::inband_progress, indicate(), indicate_data_alloc(), ast_frame_subclass::integer, LOG_NOTICE, LOG_WARNING, chan_pjsip_pvt::media, ast_sip_endpoint::moh_passthrough, NULL, ast_sip_channel_pvt::pvt, remote_send_hold(), remote_send_unhold(), ast_control_t38_parameters::request_response, ast_sip_session_media::rtp, ast_sip_session::serializer, ast_sip_channel_pvt::session, SIP_MEDIA_VIDEO, ast_frame::subclass, T38_PEER_REINVITE, ast_sip_session::t38state, transmit_info_with_vidupdate(), and update_connected_line_information().

01162 {
01163    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01164    struct chan_pjsip_pvt *pvt = channel->pvt;
01165    struct ast_sip_session_media *media;
01166    int response_code = 0;
01167    int res = 0;
01168    char *device_buf;
01169    size_t device_buf_size;
01170 
01171    switch (condition) {
01172    case AST_CONTROL_RINGING:
01173       if (ast_channel_state(ast) == AST_STATE_RING) {
01174          if (channel->session->endpoint->inband_progress) {
01175             response_code = 183;
01176             res = -1;
01177          } else {
01178             response_code = 180;
01179          }
01180       } else {
01181          res = -1;
01182       }
01183       ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "PJSIP/%s", ast_sorcery_object_get_id(channel->session->endpoint));
01184       break;
01185    case AST_CONTROL_BUSY:
01186       if (ast_channel_state(ast) != AST_STATE_UP) {
01187          response_code = 486;
01188       } else {
01189          res = -1;
01190       }
01191       break;
01192    case AST_CONTROL_CONGESTION:
01193       if (ast_channel_state(ast) != AST_STATE_UP) {
01194          response_code = 503;
01195       } else {
01196          res = -1;
01197       }
01198       break;
01199    case AST_CONTROL_INCOMPLETE:
01200       if (ast_channel_state(ast) != AST_STATE_UP) {
01201          response_code = 484;
01202       } else {
01203          res = -1;
01204       }
01205       break;
01206    case AST_CONTROL_PROCEEDING:
01207       if (ast_channel_state(ast) != AST_STATE_UP) {
01208          response_code = 100;
01209       } else {
01210          res = -1;
01211       }
01212       break;
01213    case AST_CONTROL_PROGRESS:
01214       if (ast_channel_state(ast) != AST_STATE_UP) {
01215          response_code = 183;
01216       } else {
01217          res = -1;
01218       }
01219       break;
01220    case AST_CONTROL_VIDUPDATE:
01221       media = pvt->media[SIP_MEDIA_VIDEO];
01222       if (media && media->rtp) {
01223          /* FIXME: Only use this for VP8. Additional work would have to be done to
01224           * fully support other video codecs */
01225 
01226          if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), ast_format_vp8) != AST_FORMAT_CMP_NOT_EQUAL) {
01227             /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
01228              * RTP engine would provide a way to externally write/schedule RTCP
01229              * packets */
01230             struct ast_frame fr;
01231             fr.frametype = AST_FRAME_CONTROL;
01232             fr.subclass.integer = AST_CONTROL_VIDUPDATE;
01233             res = ast_rtp_instance_write(media->rtp, &fr);
01234          } else {
01235             ao2_ref(channel->session, +1);
01236 
01237             if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
01238                ao2_cleanup(channel->session);
01239             }
01240          }
01241          ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
01242       } else {
01243          ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
01244          res = -1;
01245       }
01246       break;
01247    case AST_CONTROL_CONNECTED_LINE:
01248       ao2_ref(channel->session, +1);
01249       if (ast_sip_push_task(channel->session->serializer, update_connected_line_information, channel->session)) {
01250          ao2_cleanup(channel->session);
01251       }
01252       break;
01253    case AST_CONTROL_UPDATE_RTP_PEER:
01254       break;
01255    case AST_CONTROL_PVT_CAUSE_CODE:
01256       res = -1;
01257       break;
01258    case AST_CONTROL_MASQUERADE_NOTIFY:
01259       ast_assert(datalen == sizeof(int));
01260       if (*(int *) data) {
01261          /*
01262           * Masquerade is beginning:
01263           * Wait for session serializer to get suspended.
01264           */
01265          ast_channel_unlock(ast);
01266          ast_sip_session_suspend(channel->session);
01267          ast_channel_lock(ast);
01268       } else {
01269          /*
01270           * Masquerade is complete:
01271           * Unsuspend the session serializer.
01272           */
01273          ast_sip_session_unsuspend(channel->session);
01274       }
01275       break;
01276    case AST_CONTROL_HOLD:
01277       chan_pjsip_add_hold(ast_channel_uniqueid(ast));
01278       device_buf_size = strlen(ast_channel_name(ast)) + 1;
01279       device_buf = alloca(device_buf_size);
01280       ast_channel_get_device_name(ast, device_buf, device_buf_size);
01281       ast_devstate_changed_literal(AST_DEVICE_ONHOLD, 1, device_buf);
01282       if (!channel->session->endpoint->moh_passthrough) {
01283          ast_moh_start(ast, data, NULL);
01284       } else {
01285          if (ast_sip_push_task(channel->session->serializer, remote_send_hold, ao2_bump(channel->session))) {
01286             ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
01287                ast_sorcery_object_get_id(channel->session), ast_sorcery_object_get_id(channel->session->endpoint));
01288             ao2_ref(channel->session, -1);
01289          }
01290       }
01291       break;
01292    case AST_CONTROL_UNHOLD:
01293       chan_pjsip_remove_hold(ast_channel_uniqueid(ast));
01294       device_buf_size = strlen(ast_channel_name(ast)) + 1;
01295       device_buf = alloca(device_buf_size);
01296       ast_channel_get_device_name(ast, device_buf, device_buf_size);
01297       ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, 1, device_buf);
01298       if (!channel->session->endpoint->moh_passthrough) {
01299          ast_moh_stop(ast);
01300       } else {
01301          if (ast_sip_push_task(channel->session->serializer, remote_send_unhold, ao2_bump(channel->session))) {
01302             ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
01303                ast_sorcery_object_get_id(channel->session), ast_sorcery_object_get_id(channel->session->endpoint));
01304             ao2_ref(channel->session, -1);
01305          }
01306       }
01307       break;
01308    case AST_CONTROL_SRCUPDATE:
01309       break;
01310    case AST_CONTROL_SRCCHANGE:
01311       break;
01312    case AST_CONTROL_REDIRECTING:
01313       if (ast_channel_state(ast) != AST_STATE_UP) {
01314          response_code = 181;
01315       } else {
01316          res = -1;
01317       }
01318       break;
01319    case AST_CONTROL_T38_PARAMETERS:
01320       res = 0;
01321 
01322       if (channel->session->t38state == T38_PEER_REINVITE) {
01323          const struct ast_control_t38_parameters *parameters = data;
01324 
01325          if (parameters->request_response == AST_T38_REQUEST_PARMS) {
01326             res = AST_T38_REQUEST_PARMS;
01327          }
01328       }
01329 
01330       break;
01331    case -1:
01332       res = -1;
01333       break;
01334    default:
01335       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
01336       res = -1;
01337       break;
01338    }
01339 
01340    if (response_code) {
01341       struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
01342       if (!ind_data || ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
01343          ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
01344                response_code, ast_sorcery_object_get_id(channel->session->endpoint));
01345          ao2_cleanup(ind_data);
01346          res = -1;
01347       }
01348    }
01349 
01350    return res;
01351 }

static struct ast_channel* chan_pjsip_new ( struct ast_sip_session session,
int  state,
const char *  exten,
const char *  title,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  cid_name 
) [static, read]

Function called to create a new PJSIP Asterisk channel.

Definition at line 372 of file chan_pjsip.c.

References ast_sip_endpoint::accountcode, ao2_alloc, ao2_cleanup, ao2_find, ao2_ref, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_channel_adsicpe_set(), ast_channel_alloc_with_endpoint, ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_zone_set(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_count(), ast_format_cap_empty(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_best_by_type(), ast_format_cap_get_format(), ast_format_cap_iscompatible(), ast_get_encoded_str(), ast_get_indication_zone(), ast_hangup(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_party_id_copy(), ast_sip_channel_pvt_alloc(), ast_sorcery_object_get_id(), AST_STATE_RING, ast_strlen_zero, buf, ast_sip_endpoint_pickup_configuration::callgroup, chan_pjsip_pvt_dtor(), ast_sip_endpoint::channel_vars, ast_sip_endpoint_media_configuration::codecs, ast_sip_endpoint::context, ast_sip_session::endpoint, ast_sip_session::id, ast_sip_endpoint::language, LOG_ERROR, ast_sip_session::media, ast_sip_endpoint::media, ast_variable::name, ast_party_id::name, ast_sip_endpoint_pickup_configuration::named_callgroups, ast_sip_endpoint_pickup_configuration::named_pickupgroups, ast_variable::next, NULL, ast_party_id::number, OBJ_KEY, pbx_builtin_setvar_helper(), ast_sip_endpoint::persistent, ast_sip_endpoint::pickup, ast_sip_endpoint_pickup_configuration::pickupgroup, RAII_VAR, ast_sip_session::req_caps, S_COR, S_OR, set_channel_on_rtp_instance(), SIP_MEDIA_AUDIO, SIP_MEDIA_VIDEO, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, and ast_sip_endpoint::zone.

Referenced by chan_pjsip_incoming_request(), and chan_pjsip_request().

00373 {
00374    struct ast_channel *chan;
00375    struct ast_format_cap *caps;
00376    RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
00377    struct ast_sip_channel_pvt *channel;
00378    struct ast_variable *var;
00379 
00380    if (!(pvt = ao2_alloc(sizeof(*pvt), chan_pjsip_pvt_dtor))) {
00381       return NULL;
00382    }
00383    caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
00384    if (!caps) {
00385       return NULL;
00386    }
00387 
00388    chan = ast_channel_alloc_with_endpoint(1, state,
00389       S_COR(session->id.number.valid, session->id.number.str, ""),
00390       S_COR(session->id.name.valid, session->id.name.str, ""),
00391       session->endpoint->accountcode, "", "", assignedids, requestor, 0,
00392       session->endpoint->persistent, "PJSIP/%s-%08x",
00393       ast_sorcery_object_get_id(session->endpoint),
00394       (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
00395    if (!chan) {
00396       ao2_ref(caps, -1);
00397       return NULL;
00398    }
00399 
00400    ast_channel_tech_set(chan, &chan_pjsip_tech);
00401 
00402    if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
00403       ao2_ref(caps, -1);
00404       ast_channel_unlock(chan);
00405       ast_hangup(chan);
00406       return NULL;
00407    }
00408 
00409    ast_channel_stage_snapshot(chan);
00410 
00411    ast_channel_tech_pvt_set(chan, channel);
00412 
00413    if (!ast_format_cap_count(session->req_caps) ||
00414       !ast_format_cap_iscompatible(session->req_caps, session->endpoint->media.codecs)) {
00415       ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
00416    } else {
00417       ast_format_cap_append_from_cap(caps, session->req_caps, AST_MEDIA_TYPE_UNKNOWN);
00418    }
00419 
00420    ast_channel_nativeformats_set(chan, caps);
00421 
00422    if (!ast_format_cap_empty(caps)) {
00423       struct ast_format *fmt;
00424 
00425       fmt = ast_format_cap_get_best_by_type(caps, AST_MEDIA_TYPE_AUDIO);
00426       if (!fmt) {
00427          /* Since our capabilities aren't empty, this will succeed */
00428          fmt = ast_format_cap_get_format(caps, 0);
00429       }
00430       ast_channel_set_writeformat(chan, fmt);
00431       ast_channel_set_rawwriteformat(chan, fmt);
00432       ast_channel_set_readformat(chan, fmt);
00433       ast_channel_set_rawreadformat(chan, fmt);
00434       ao2_ref(fmt, -1);
00435    }
00436 
00437    ao2_ref(caps, -1);
00438 
00439    if (state == AST_STATE_RING) {
00440       ast_channel_rings_set(chan, 1);
00441    }
00442 
00443    ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
00444 
00445    ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
00446    ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
00447 
00448    ast_channel_context_set(chan, session->endpoint->context);
00449    ast_channel_exten_set(chan, S_OR(exten, "s"));
00450    ast_channel_priority_set(chan, 1);
00451 
00452    ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
00453    ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
00454 
00455    ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
00456    ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
00457 
00458    if (!ast_strlen_zero(session->endpoint->language)) {
00459       ast_channel_language_set(chan, session->endpoint->language);
00460    }
00461 
00462    if (!ast_strlen_zero(session->endpoint->zone)) {
00463       struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
00464       if (!zone) {
00465          ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
00466       }
00467       ast_channel_zone_set(chan, zone);
00468    }
00469 
00470    for (var = session->endpoint->channel_vars; var; var = var->next) {
00471       char buf[512];
00472       pbx_builtin_setvar_helper(chan, var->name, ast_get_encoded_str(
00473                     var->value, buf, sizeof(buf)));
00474    }
00475 
00476    ast_channel_stage_snapshot_done(chan);
00477    ast_channel_unlock(chan);
00478 
00479    /* If res_pjsip_session is ever updated to create/destroy ast_sip_session_media
00480     * during a call such as if multiple same-type stream support is introduced,
00481     * these will need to be recaptured as well */
00482    pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY);
00483    pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
00484    set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(chan));
00485 
00486    return chan;
00487 }

static void chan_pjsip_pvt_dtor ( void *  obj  )  [static]

Definition at line 80 of file chan_pjsip.c.

References ao2_cleanup, chan_pjsip_pvt::media, NULL, and SIP_MEDIA_SIZE.

Referenced by chan_pjsip_new().

00081 {
00082    struct chan_pjsip_pvt *pvt = obj;
00083    int i;
00084 
00085    for (i = 0; i < SIP_MEDIA_SIZE; ++i) {
00086       ao2_cleanup(pvt->media[i]);
00087       pvt->media[i] = NULL;
00088    }
00089 }

static int chan_pjsip_queryoption ( struct ast_channel ast,
int  option,
void *  data,
int *  datalen 
) [static]

Function called to query options on a channel.

Definition at line 901 of file chan_pjsip.c.

References ast_channel_tech_pvt(), AST_OPTION_T38_STATE, ast_sip_t38_configuration::enabled, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_channel_pvt::session, session, ast_sip_endpoint_media_configuration::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_REJECTED, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_REJECTED, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_sip_session::t38state.

00902 {
00903    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
00904    struct ast_sip_session *session = channel->session;
00905    int res = -1;
00906    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
00907 
00908    switch (option) {
00909    case AST_OPTION_T38_STATE:
00910       if (session->endpoint->media.t38.enabled) {
00911          switch (session->t38state) {
00912          case T38_LOCAL_REINVITE:
00913          case T38_PEER_REINVITE:
00914             state = T38_STATE_NEGOTIATING;
00915             break;
00916          case T38_ENABLED:
00917             state = T38_STATE_NEGOTIATED;
00918             break;
00919          case T38_REJECTED:
00920             state = T38_STATE_REJECTED;
00921             break;
00922          default:
00923             state = T38_STATE_UNKNOWN;
00924             break;
00925          }
00926       }
00927 
00928       *((enum ast_t38_state *) data) = state;
00929       res = 0;
00930 
00931       break;
00932    default:
00933       break;
00934    }
00935 
00936    return res;
00937 }

static struct ast_frame * chan_pjsip_read ( struct ast_channel ast  )  [static, read]

Function called by core to read any waiting frames.

Definition at line 594 of file chan_pjsip.c.

References ast_channel_fdno(), ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_VOICE, ast_null_frame, ast_rtp_instance_read(), chan_pjsip_cng_tone_detected(), ast_sip_session::dsp, f, ast_frame::frametype, ast_frame_subclass::integer, chan_pjsip_pvt::media, NULL, ast_sip_channel_pvt::pvt, ast_sip_session_media::rtp, ast_sip_channel_pvt::session, SIP_MEDIA_AUDIO, SIP_MEDIA_VIDEO, and ast_frame::subclass.

00595 {
00596    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
00597    struct chan_pjsip_pvt *pvt = channel->pvt;
00598    struct ast_frame *f;
00599    struct ast_sip_session_media *media = NULL;
00600    int rtcp = 0;
00601    int fdno = ast_channel_fdno(ast);
00602 
00603    switch (fdno) {
00604    case 0:
00605       media = pvt->media[SIP_MEDIA_AUDIO];
00606       break;
00607    case 1:
00608       media = pvt->media[SIP_MEDIA_AUDIO];
00609       rtcp = 1;
00610       break;
00611    case 2:
00612       media = pvt->media[SIP_MEDIA_VIDEO];
00613       break;
00614    case 3:
00615       media = pvt->media[SIP_MEDIA_VIDEO];
00616       rtcp = 1;
00617       break;
00618    }
00619 
00620    if (!media || !media->rtp) {
00621       return &ast_null_frame;
00622    }
00623 
00624    if (!(f = ast_rtp_instance_read(media->rtp, rtcp))) {
00625       return f;
00626    }
00627 
00628    if (f->frametype != AST_FRAME_VOICE) {
00629       return f;
00630    }
00631 
00632    if (channel->session->dsp) {
00633       f = ast_dsp_process(ast, channel->session->dsp, f);
00634 
00635       if (f && (f->frametype == AST_FRAME_DTMF)) {
00636          if (f->subclass.integer == 'f') {
00637             ast_debug(3, "Fax CNG detected on %s\n", ast_channel_name(ast));
00638             f = chan_pjsip_cng_tone_detected(channel->session, f);
00639          } else {
00640             ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
00641                ast_channel_name(ast));
00642          }
00643       }
00644    }
00645 
00646    return f;
00647 }

static void chan_pjsip_remove_hold ( const char *  chan_uid  )  [static]

Remove a channel ID from the list of PJSIP channels on hold.

Parameters:
chan_uid - Unique ID of the channel being taken out of the hold list

Definition at line 806 of file chan_pjsip.c.

References ao2_find, OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by chan_pjsip_indicate(), and chan_pjsip_session_end().

00807 {
00808    ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
00809 }

static struct ast_channel * chan_pjsip_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
) [static, read]

Function called by core to create a new outgoing PJSIP session.

Definition at line 1885 of file chan_pjsip.c.

References ao2_cleanup, ast_sip_push_task_synchronous(), AST_STATE_DOWN, request_data::caps, request_data::cause, chan_pjsip_new(), request_data::dest, NULL, RAII_VAR, request(), request_data::session, and session.

01886 {
01887    struct request_data req_data;
01888    RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
01889 
01890    req_data.caps = cap;
01891    req_data.dest = data;
01892 
01893    if (ast_sip_push_task_synchronous(NULL, request, &req_data)) {
01894       *cause = req_data.cause;
01895       return NULL;
01896    }
01897 
01898    session = req_data.session;
01899 
01900    if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
01901       /* Session needs to be terminated prematurely */
01902       return NULL;
01903    }
01904 
01905    return session->channel;
01906 }

static int chan_pjsip_sendtext ( struct ast_channel ast,
const char *  text 
) [static]

Function called by core to send text on PJSIP session.

Definition at line 1955 of file chan_pjsip.c.

References ao2_ref, ast_channel_tech_pvt(), ast_sip_push_task(), sendtext(), sendtext_data_create(), ast_sip_session::serializer, and ast_sip_channel_pvt::session.

01956 {
01957    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01958    struct sendtext_data *data = sendtext_data_create(channel->session, text);
01959 
01960    if (!data || ast_sip_push_task(channel->session->serializer, sendtext, data)) {
01961       ao2_ref(data, -1);
01962       return -1;
01963    }
01964    return 0;
01965 }

static void chan_pjsip_session_begin ( struct ast_sip_session session  )  [static]

SIP session interaction functions.

Definition at line 2058 of file chan_pjsip.c.

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::endpoint, ast_sip_direct_media_configuration::glare_mitigation, ast_sip_endpoint::media, NULL, and RAII_VAR.

02059 {
02060    RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
02061 
02062    if (session->endpoint->media.direct_media.glare_mitigation ==
02063          AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
02064       return;
02065    }
02066 
02067    datastore = ast_sip_session_alloc_datastore(&direct_media_mitigation_info,
02068          "direct_media_glare_mitigation");
02069 
02070    if (!datastore) {
02071       return;
02072    }
02073 
02074    ast_sip_session_add_datastore(session, datastore);
02075 }

static void chan_pjsip_session_end ( struct ast_sip_session session  )  [static]

Function called when the session ends.

Definition at line 2078 of file chan_pjsip.c.

References ast_channel_hangupcause(), ast_channel_name(), ast_channel_uniqueid(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_hangupsource(), chan_pjsip_remove_hold(), ast_sip_session::channel, hangup_sip2cause(), and ast_sip_session::inv_session.

02079 {
02080    if (!session->channel) {
02081       return;
02082    }
02083 
02084    chan_pjsip_remove_hold(ast_channel_uniqueid(session->channel));
02085 
02086    ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
02087    if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
02088       int cause = hangup_sip2cause(session->inv_session->cause);
02089 
02090       ast_queue_hangup_with_cause(session->channel, cause);
02091    } else {
02092       ast_queue_hangup(session->channel);
02093    }
02094 }

static int chan_pjsip_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_rtp_instance vrtp,
struct ast_rtp_instance tpeer,
const struct ast_format_cap cap,
int  nat_active 
) [static]

Function called by RTP engine to change where the remote party should send media.

Definition at line 299 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_channel_is_bridged(), ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_format_cap_append_from_cap(), ast_format_cap_count(), ast_format_cap_identical(), ast_format_cap_remove_by_type(), AST_MEDIA_TYPE_UNKNOWN, ast_sip_push_task(), check_for_rtp_changes(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::direct_media_cap, direct_media_mitigate_glare(), ast_sip_direct_media_configuration::disable_on_nat, ast_sip_session::endpoint, chan_pjsip_pvt::media, ast_sip_endpoint::media, ast_sip_channel_pvt::pvt, send_direct_media_request(), ast_sip_session::serializer, ast_sip_channel_pvt::session, session, SIP_MEDIA_AUDIO, and SIP_MEDIA_VIDEO.

00305 {
00306    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
00307    struct chan_pjsip_pvt *pvt = channel->pvt;
00308    struct ast_sip_session *session = channel->session;
00309    int changed = 0;
00310 
00311    /* Don't try to do any direct media shenanigans on early bridges */
00312    if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
00313       ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
00314       return 0;
00315    }
00316 
00317    if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
00318       ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
00319       return 0;
00320    }
00321 
00322    if (pvt->media[SIP_MEDIA_AUDIO]) {
00323       changed |= check_for_rtp_changes(chan, rtp, pvt->media[SIP_MEDIA_AUDIO], 1);
00324    }
00325    if (pvt->media[SIP_MEDIA_VIDEO]) {
00326       changed |= check_for_rtp_changes(chan, vrtp, pvt->media[SIP_MEDIA_VIDEO], 3);
00327    }
00328 
00329    if (direct_media_mitigate_glare(session)) {
00330       ast_debug(4, "Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(chan));
00331       return 0;
00332    }
00333 
00334    if (cap && ast_format_cap_count(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
00335       ast_format_cap_remove_by_type(session->direct_media_cap, AST_MEDIA_TYPE_UNKNOWN);
00336       ast_format_cap_append_from_cap(session->direct_media_cap, cap, AST_MEDIA_TYPE_UNKNOWN);
00337       changed = 1;
00338    }
00339 
00340    if (changed) {
00341       ao2_ref(session, +1);
00342 
00343       ast_debug(4, "RTP changed on %s; initiating direct media update\n", ast_channel_name(chan));
00344       if (ast_sip_push_task(session->serializer, send_direct_media_request, session)) {
00345          ao2_cleanup(session);
00346       }
00347    }
00348 
00349    return 0;
00350 }

static int chan_pjsip_transfer ( struct ast_channel ast,
const char *  target 
) [static]

Function called by core for Asterisk initiated transfer.

Definition at line 1476 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_tech_pvt(), ast_log, ast_sip_push_task(), LOG_WARNING, ast_sip_session::serializer, ast_sip_channel_pvt::session, transfer, and transfer_data_alloc().

01477 {
01478    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
01479    struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
01480 
01481    if (!trnf_data) {
01482       return -1;
01483    }
01484 
01485    if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
01486       ast_log(LOG_WARNING, "Error requesting transfer\n");
01487       ao2_cleanup(trnf_data);
01488       return -1;
01489    }
01490 
01491    return 0;
01492 }

static int chan_pjsip_write ( struct ast_channel ast,
struct ast_frame f 
) [static]

Function called by core to write frames.

Definition at line 650 of file chan_pjsip.c.

References ast_channel_name(), ast_channel_nativeformats(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_channel_readformat(), ast_channel_readtrans(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_channel_writetrans(), ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log, ast_rtp_instance_write(), ast_str_alloca, ast_translate_path_to_str(), ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, chan_pjsip_pvt::media, ast_sip_channel_pvt::pvt, ast_sip_session_media::rtp, SIP_MEDIA_AUDIO, SIP_MEDIA_VIDEO, and ast_frame::subclass.

00651 {
00652    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
00653    struct chan_pjsip_pvt *pvt = channel->pvt;
00654    struct ast_sip_session_media *media;
00655    int res = 0;
00656 
00657    switch (frame->frametype) {
00658    case AST_FRAME_VOICE:
00659       media = pvt->media[SIP_MEDIA_AUDIO];
00660 
00661       if (!media) {
00662          return 0;
00663       }
00664       if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
00665          struct ast_str *cap_buf = ast_str_alloca(128);
00666          struct ast_str *write_transpath = ast_str_alloca(256);
00667          struct ast_str *read_transpath = ast_str_alloca(256);
00668 
00669          ast_log(LOG_WARNING,
00670             "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
00671             ast_channel_name(ast),
00672             ast_format_get_name(frame->subclass.format),
00673             ast_format_cap_get_names(ast_channel_nativeformats(ast), &cap_buf),
00674             ast_format_get_name(ast_channel_rawreadformat(ast)),
00675             ast_format_get_name(ast_channel_readformat(ast)),
00676             ast_translate_path_to_str(ast_channel_readtrans(ast), &read_transpath),
00677             ast_format_get_name(ast_channel_writeformat(ast)),
00678             ast_format_get_name(ast_channel_rawwriteformat(ast)),
00679             ast_translate_path_to_str(ast_channel_writetrans(ast), &write_transpath));
00680          return 0;
00681       }
00682       if (media->rtp) {
00683          res = ast_rtp_instance_write(media->rtp, frame);
00684       }
00685       break;
00686    case AST_FRAME_VIDEO:
00687       if ((media = pvt->media[SIP_MEDIA_VIDEO]) && media->rtp) {
00688          res = ast_rtp_instance_write(media->rtp, frame);
00689       }
00690       break;
00691    case AST_FRAME_MODEM:
00692       break;
00693    default:
00694       ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
00695       break;
00696    }
00697 
00698    return res;
00699 }

static int check_for_rtp_changes ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_sip_session_media media,
int  rtcp_fd 
) [static]

Definition at line 275 of file chan_pjsip.c.

References ast_channel_set_fd(), ast_rtp_instance_fd(), ast_rtp_instance_get_and_cmp_remote_address, ast_rtp_instance_set_prop(), AST_RTP_PROPERTY_RTCP, ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sip_session_media::direct_media_addr, and ast_sip_session_media::rtp.

Referenced by chan_pjsip_set_rtp_peer().

00277 {
00278    int changed = 0;
00279 
00280    if (rtp) {
00281       changed = ast_rtp_instance_get_and_cmp_remote_address(rtp, &media->direct_media_addr);
00282       if (media->rtp) {
00283          ast_channel_set_fd(chan, rtcp_fd, -1);
00284          ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 0);
00285       }
00286    } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
00287       ast_sockaddr_setnull(&media->direct_media_addr);
00288       changed = 1;
00289       if (media->rtp) {
00290          ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 1);
00291          ast_channel_set_fd(chan, rtcp_fd, ast_rtp_instance_fd(media->rtp, 1));
00292       }
00293    }
00294 
00295    return changed;
00296 }

static void clear_session_and_channel ( struct ast_sip_session session,
struct ast_channel ast,
struct chan_pjsip_pvt pvt 
) [static]

Clear a channel from a session along with its PVT.

Definition at line 1775 of file chan_pjsip.c.

References ast_channel_tech_pvt_set(), ast_sip_session::channel, NULL, and set_channel_on_rtp_instance().

Referenced by chan_pjsip_hangup(), and hangup().

01776 {
01777    session->channel = NULL;
01778    set_channel_on_rtp_instance(pvt, "");
01779    ast_channel_tech_pvt_set(ast, NULL);
01780 }

static int direct_media_mitigate_glare ( struct ast_sip_session session  )  [static]

Definition at line 246 of file chan_pjsip.c.

References ao2_cleanup, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE, AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING, ast_sip_session_get_datastore(), ast_sip_session_remove_datastore(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::endpoint, ast_sip_direct_media_configuration::glare_mitigation, ast_sip_session::inv_session, ast_sip_endpoint::media, NULL, and RAII_VAR.

Referenced by chan_pjsip_set_rtp_peer().

00247 {
00248    RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
00249 
00250    if (session->endpoint->media.direct_media.glare_mitigation ==
00251          AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
00252       return 0;
00253    }
00254 
00255    datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
00256    if (!datastore) {
00257       return 0;
00258    }
00259 
00260    /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
00261    ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
00262 
00263    if ((session->endpoint->media.direct_media.glare_mitigation ==
00264          AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING &&
00265          session->inv_session->role == PJSIP_ROLE_UAC) ||
00266          (session->endpoint->media.direct_media.glare_mitigation ==
00267          AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING &&
00268          session->inv_session->role == PJSIP_ROLE_UAS)) {
00269       return 1;
00270    }
00271 
00272    return 0;
00273 }

static int hangup ( void *  data  )  [static]

Definition at line 1782 of file chan_pjsip.c.

References ao2_cleanup, ast_channel_tech_pvt(), ast_sip_session_terminate(), hangup_data::cause, hangup_data::chan, clear_session_and_channel(), ast_sip_channel_pvt::pvt, ast_sip_channel_pvt::session, and session.

Referenced by ast_hangup(), chan_pjsip_hangup(), and manage_calls().

01783 {
01784    struct hangup_data *h_data = data;
01785    struct ast_channel *ast = h_data->chan;
01786    struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
01787    struct chan_pjsip_pvt *pvt = channel->pvt;
01788    struct ast_sip_session *session = channel->session;
01789    int cause = h_data->cause;
01790 
01791    ast_sip_session_terminate(session, cause);
01792    clear_session_and_channel(session, ast, pvt);
01793    ao2_cleanup(channel);
01794    ao2_cleanup(h_data);
01795 
01796    return 0;
01797 }

static int hangup_cause2sip ( int  cause  )  [static]

Internal function which translates from Asterisk cause codes to SIP response codes.

Definition at line 1701 of file chan_pjsip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.

Referenced by chan_pjsip_hangup(), and sip_hangup().

01702 {
01703    switch (cause) {
01704    case AST_CAUSE_UNALLOCATED:             /* 1 */
01705    case AST_CAUSE_NO_ROUTE_DESTINATION:    /* 3 IAX2: Can't find extension in context */
01706    case AST_CAUSE_NO_ROUTE_TRANSIT_NET:    /* 2 */
01707       return 404;
01708    case AST_CAUSE_CONGESTION:              /* 34 */
01709    case AST_CAUSE_SWITCH_CONGESTION:       /* 42 */
01710       return 503;
01711    case AST_CAUSE_NO_USER_RESPONSE:        /* 18 */
01712       return 408;
01713    case AST_CAUSE_NO_ANSWER:               /* 19 */
01714    case AST_CAUSE_UNREGISTERED:        /* 20 */
01715       return 480;
01716    case AST_CAUSE_CALL_REJECTED:           /* 21 */
01717       return 403;
01718    case AST_CAUSE_NUMBER_CHANGED:          /* 22 */
01719       return 410;
01720    case AST_CAUSE_NORMAL_UNSPECIFIED:      /* 31 */
01721       return 480;
01722    case AST_CAUSE_INVALID_NUMBER_FORMAT:
01723       return 484;
01724    case AST_CAUSE_USER_BUSY:
01725       return 486;
01726    case AST_CAUSE_FAILURE:
01727       return 500;
01728    case AST_CAUSE_FACILITY_REJECTED:       /* 29 */
01729       return 501;
01730    case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
01731       return 503;
01732    case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
01733       return 502;
01734    case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:       /* Can't find codec to connect to host */
01735       return 488;
01736    case AST_CAUSE_INTERWORKING:    /* Unspecified Interworking issues */
01737       return 500;
01738    case AST_CAUSE_NOTDEFINED:
01739    default:
01740       ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
01741       return 0;
01742    }
01743 
01744    /* Never reached */
01745    return 0;
01746 }

static struct hangup_data* hangup_data_alloc ( int  cause,
struct ast_channel chan 
) [static, read]

Definition at line 1760 of file chan_pjsip.c.

References ao2_alloc, ast_channel_ref, hangup_data::cause, hangup_data::chan, hangup_data_destroy(), and NULL.

Referenced by chan_pjsip_hangup().

01761 {
01762    struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
01763 
01764    if (!h_data) {
01765       return NULL;
01766    }
01767 
01768    h_data->cause = cause;
01769    h_data->chan = ast_channel_ref(chan);
01770 
01771    return h_data;
01772 }

static void hangup_data_destroy ( void *  obj  )  [static]

Definition at line 1753 of file chan_pjsip.c.

References ast_channel_unref, and hangup_data::chan.

Referenced by hangup_data_alloc().

01754 {
01755    struct hangup_data *h_data = obj;
01756 
01757    h_data->chan = ast_channel_unref(h_data->chan);
01758 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 1968 of file chan_pjsip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by __transmit_response(), chan_pjsip_incoming_response(), chan_pjsip_session_end(), handle_incoming(), handle_response(), and handle_response_invite().

01969 {
01970    /* Possible values taken from causes.h */
01971 
01972    switch(cause) {
01973    case 401:       /* Unauthorized */
01974       return AST_CAUSE_CALL_REJECTED;
01975    case 403:       /* Not found */
01976       return AST_CAUSE_CALL_REJECTED;
01977    case 404:       /* Not found */
01978       return AST_CAUSE_UNALLOCATED;
01979    case 405:       /* Method not allowed */
01980       return AST_CAUSE_INTERWORKING;
01981    case 407:       /* Proxy authentication required */
01982       return AST_CAUSE_CALL_REJECTED;
01983    case 408:       /* No reaction */
01984       return AST_CAUSE_NO_USER_RESPONSE;
01985    case 409:       /* Conflict */
01986       return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
01987    case 410:       /* Gone */
01988       return AST_CAUSE_NUMBER_CHANGED;
01989    case 411:       /* Length required */
01990       return AST_CAUSE_INTERWORKING;
01991    case 413:       /* Request entity too large */
01992       return AST_CAUSE_INTERWORKING;
01993    case 414:       /* Request URI too large */
01994       return AST_CAUSE_INTERWORKING;
01995    case 415:       /* Unsupported media type */
01996       return AST_CAUSE_INTERWORKING;
01997    case 420:       /* Bad extension */
01998       return AST_CAUSE_NO_ROUTE_DESTINATION;
01999    case 480:       /* No answer */
02000       return AST_CAUSE_NO_ANSWER;
02001    case 481:       /* No answer */
02002       return AST_CAUSE_INTERWORKING;
02003    case 482:       /* Loop detected */
02004       return AST_CAUSE_INTERWORKING;
02005    case 483:       /* Too many hops */
02006       return AST_CAUSE_NO_ANSWER;
02007    case 484:       /* Address incomplete */
02008       return AST_CAUSE_INVALID_NUMBER_FORMAT;
02009    case 485:       /* Ambiguous */
02010       return AST_CAUSE_UNALLOCATED;
02011    case 486:       /* Busy everywhere */
02012       return AST_CAUSE_BUSY;
02013    case 487:       /* Request terminated */
02014       return AST_CAUSE_INTERWORKING;
02015    case 488:       /* No codecs approved */
02016       return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02017    case 491:       /* Request pending */
02018       return AST_CAUSE_INTERWORKING;
02019    case 493:       /* Undecipherable */
02020       return AST_CAUSE_INTERWORKING;
02021    case 500:       /* Server internal failure */
02022       return AST_CAUSE_FAILURE;
02023    case 501:       /* Call rejected */
02024       return AST_CAUSE_FACILITY_REJECTED;
02025    case 502:
02026       return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02027    case 503:       /* Service unavailable */
02028       return AST_CAUSE_CONGESTION;
02029    case 504:       /* Gateway timeout */
02030       return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
02031    case 505:       /* SIP version not supported */
02032       return AST_CAUSE_INTERWORKING;
02033    case 600:       /* Busy everywhere */
02034       return AST_CAUSE_USER_BUSY;
02035    case 603:       /* Decline */
02036       return AST_CAUSE_CALL_REJECTED;
02037    case 604:       /* Does not exist anywhere */
02038       return AST_CAUSE_UNALLOCATED;
02039    case 606:       /* Not acceptable */
02040       return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02041    default:
02042       if (cause < 500 && cause >= 400) {
02043          /* 4xx class error that is unknown - someting wrong with our request */
02044          return AST_CAUSE_INTERWORKING;
02045       } else if (cause < 600 && cause >= 500) {
02046          /* 5xx class error - problem in the remote end */
02047          return AST_CAUSE_CONGESTION;
02048       } else if (cause < 700 && cause >= 600) {
02049          /* 6xx - global errors in the 4xx class */
02050          return AST_CAUSE_INTERWORKING;
02051       }
02052       return AST_CAUSE_NORMAL;
02053    }
02054    /* Never reached */
02055    return 0;
02056 }

static int indicate ( void *  data  )  [static]

Definition at line 994 of file chan_pjsip.c.

References ao2_ref, ast_sip_session_send_response(), ast_sip_session::inv_session, NULL, indicate_data::response_code, indicate_data::session, and session.

Referenced by ast_indicate_data(), and chan_pjsip_indicate().

00995 {
00996    pjsip_tx_data *packet = NULL;
00997    struct indicate_data *ind_data = data;
00998    struct ast_sip_session *session = ind_data->session;
00999    int response_code = ind_data->response_code;
01000 
01001    if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
01002       (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
01003       ast_sip_session_send_response(session, packet);
01004    }
01005 
01006    ao2_ref(ind_data, -1);
01007 
01008    return 0;
01009 }

static struct indicate_data* indicate_data_alloc ( struct ast_sip_session session,
int  condition,
int  response_code,
const void *  frame_data,
size_t  datalen 
) [static, read]

Definition at line 969 of file chan_pjsip.c.

References ao2_alloc, ao2_ref, ast_malloc, indicate_data::condition, indicate_data::datalen, indicate_data::frame_data, indicate_data_destroy(), NULL, indicate_data::response_code, and indicate_data::session.

Referenced by chan_pjsip_indicate().

00971 {
00972    struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
00973 
00974    if (!ind_data) {
00975       return NULL;
00976    }
00977 
00978    ind_data->frame_data = ast_malloc(datalen);
00979    if (!ind_data->frame_data) {
00980       ao2_ref(ind_data, -1);
00981       return NULL;
00982    }
00983 
00984    memcpy(ind_data->frame_data, frame_data, datalen);
00985    ind_data->datalen = datalen;
00986    ind_data->condition = condition;
00987    ind_data->response_code = response_code;
00988    ao2_ref(session, +1);
00989    ind_data->session = session;
00990 
00991    return ind_data;
00992 }

static void indicate_data_destroy ( void *  obj  )  [static]

Definition at line 961 of file chan_pjsip.c.

References ao2_ref, ast_free, indicate_data::frame_data, and indicate_data::session.

Referenced by indicate_data_alloc().

00962 {
00963    struct indicate_data *ind_data = obj;
00964 
00965    ast_free(ind_data->frame_data);
00966    ao2_ref(ind_data->session, -1);
00967 }

static struct info_dtmf_data* info_dtmf_data_alloc ( struct ast_sip_session session,
char  digit,
unsigned int  duration 
) [static, read]

Definition at line 1541 of file chan_pjsip.c.

References ao2_alloc, ao2_ref, info_dtmf_data::digit, info_dtmf_data::duration, info_dtmf_data_destroy(), NULL, and info_dtmf_data::session.

Referenced by chan_pjsip_digit_end().

01542 {
01543    struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
01544    if (!dtmf_data) {
01545       return NULL;
01546    }
01547    ao2_ref(session, +1);
01548    dtmf_data->session = session;
01549    dtmf_data->digit = digit;
01550    dtmf_data->duration = duration;
01551    return dtmf_data;
01552 }

static void info_dtmf_data_destroy ( void *  obj  )  [static]

Definition at line 1535 of file chan_pjsip.c.

References ao2_ref, and info_dtmf_data::session.

Referenced by info_dtmf_data_alloc().

01536 {
01537    struct info_dtmf_data *dtmf_data = obj;
01538    ao2_ref(dtmf_data->session, -1);
01539 }

static int is_colp_update_allowed ( struct ast_sip_session session  )  [static]

Definition at line 1056 of file chan_pjsip.c.

References ast_channel_connected_effective_id(), ast_channel_lock, ast_channel_unlock, ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_endpoint::id, ast_party_id::number, ast_sip_endpoint_id_configuration::send_pai, ast_sip_endpoint_id_configuration::send_rpid, ast_sip_endpoint_id_configuration::trust_outbound, and ast_party_number::valid.

Referenced by update_connected_line_information().

01057 {
01058    struct ast_party_id connected_id;
01059    int update_allowed = 0;
01060 
01061    if (!session->endpoint->id.send_pai && !session->endpoint->id.send_rpid) {
01062       return 0;
01063    }
01064 
01065    /*
01066     * Check if privacy allows the update.  Check while the channel
01067     * is locked so we can work with the shallow connected_id copy.
01068     */
01069    ast_channel_lock(session->channel);
01070    connected_id = ast_channel_connected_effective_id(session->channel);
01071    if (connected_id.number.valid
01072       && (session->endpoint->id.trust_outbound
01073          || (ast_party_id_presentation(&connected_id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED)) {
01074       update_allowed = 1;
01075    }
01076    ast_channel_unlock(session->channel);
01077 
01078    return update_allowed;
01079 }

static int load_module ( void   )  [static]

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 2320 of file chan_pjsip.c.

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_hash, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_ref, ast_channel_register(), ast_channel_unregister(), ast_custom_function_register, ast_custom_function_unregister(), ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_rtp_glue_register, ast_rtp_glue_unregister(), ast_sip_get_endpoints(), ast_sip_session_register_supplement(), ast_sip_session_unregister_supplement(), ast_channel_tech::capabilities, CHECK_PJSIP_SESSION_MODULE_LOADED, end, endpoints, LOG_ERROR, LOG_WARNING, NULL, OBJ_NODATA, uid_hold_hash_fn(), uid_hold_sort_fn(), and update_devstate().

02321 {
02322    struct ao2_container *endpoints;
02323 
02324    CHECK_PJSIP_SESSION_MODULE_LOADED();
02325 
02326    if (!(chan_pjsip_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
02327       return AST_MODULE_LOAD_DECLINE;
02328    }
02329 
02330    ast_format_cap_append_by_type(chan_pjsip_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
02331 
02332    ast_rtp_glue_register(&chan_pjsip_rtp_glue);
02333 
02334    if (ast_channel_register(&chan_pjsip_tech)) {
02335       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
02336       goto end;
02337    }
02338 
02339    if (ast_custom_function_register(&chan_pjsip_dial_contacts_function)) {
02340       ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
02341       goto end;
02342    }
02343 
02344    if (ast_custom_function_register(&media_offer_function)) {
02345       ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
02346       goto end;
02347    }
02348 
02349    if (ast_sip_session_register_supplement(&chan_pjsip_supplement)) {
02350       ast_log(LOG_ERROR, "Unable to register PJSIP supplement\n");
02351       goto end;
02352    }
02353 
02354    if (!(pjsip_uids_onhold = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK,
02355          AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, 37, uid_hold_hash_fn,
02356          uid_hold_sort_fn, NULL))) {
02357       ast_log(LOG_ERROR, "Unable to create held channels container\n");
02358       goto end;
02359    }
02360 
02361    if (ast_sip_session_register_supplement(&call_pickup_supplement)) {
02362       ast_log(LOG_ERROR, "Unable to register PJSIP call pickup supplement\n");
02363       ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
02364       goto end;
02365    }
02366 
02367    if (ast_sip_session_register_supplement(&pbx_start_supplement)) {
02368       ast_log(LOG_ERROR, "Unable to register PJSIP pbx start supplement\n");
02369       ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
02370       ast_sip_session_unregister_supplement(&call_pickup_supplement);
02371       goto end;
02372    }
02373 
02374    if (ast_sip_session_register_supplement(&chan_pjsip_ack_supplement)) {
02375       ast_log(LOG_ERROR, "Unable to register PJSIP ACK supplement\n");
02376       ast_sip_session_unregister_supplement(&pbx_start_supplement);
02377       ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
02378       ast_sip_session_unregister_supplement(&call_pickup_supplement);
02379       goto end;
02380    }
02381 
02382    /* since endpoints are loaded before the channel driver their device
02383       states get set to 'invalid', so they need to be updated */
02384    if ((endpoints = ast_sip_get_endpoints())) {
02385       ao2_callback(endpoints, OBJ_NODATA, update_devstate, NULL);
02386       ao2_ref(endpoints, -1);
02387    }
02388 
02389    return 0;
02390 
02391 end:
02392    ao2_cleanup(pjsip_uids_onhold);
02393    pjsip_uids_onhold = NULL;
02394    ast_custom_function_unregister(&media_offer_function);
02395    ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
02396    ast_channel_unregister(&chan_pjsip_tech);
02397    ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
02398 
02399    return AST_MODULE_LOAD_FAILURE;
02400 }

static int local_hold_set_state ( void *  obj,
void *  arg,
int  flags 
) [static]

Callback which changes the value of locally held on the media stream.

Definition at line 1128 of file chan_pjsip.c.

References ast_sip_session_media::locally_held.

Referenced by remote_send_hold_refresh().

01129 {
01130    struct ast_sip_session_media *session_media = obj;
01131    unsigned int *held = arg;
01132 
01133    session_media->locally_held = *held;
01134 
01135    return 0;
01136 }

static int pbx_start_incoming_request ( struct ast_sip_session session,
pjsip_rx_data *  rdata 
) [static]

Definition at line 2198 of file chan_pjsip.c.

References AST_CAUSE_SWITCH_CONGESTION, ast_channel_hangupcause_set(), ast_channel_name(), ast_debug, ast_hangup(), ast_log, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_sip_session::channel, ast_sip_session::inv_session, and LOG_WARNING.

02199 {
02200    int res;
02201 
02202    /* We don't care about reinvites */
02203    if (session->inv_session->state >= PJSIP_INV_STATE_CONFIRMED) {
02204       return 0;
02205    }
02206 
02207    res = ast_pbx_start(session->channel);
02208 
02209    switch (res) {
02210    case AST_PBX_FAILED:
02211       ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
02212       ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
02213       ast_hangup(session->channel);
02214       break;
02215    case AST_PBX_CALL_LIMIT:
02216       ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
02217       ast_channel_hangupcause_set(session->channel, AST_CAUSE_SWITCH_CONGESTION);
02218       ast_hangup(session->channel);
02219       break;
02220    case AST_PBX_SUCCESS:
02221    default:
02222       break;
02223    }
02224 
02225    ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
02226 
02227    return (res == AST_PBX_SUCCESS) ? 0 : -1;
02228 }

static int remote_send_hold ( void *  data  )  [static]

Update local hold state to be held.

Definition at line 1149 of file chan_pjsip.c.

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

01150 {
01151    return remote_send_hold_refresh(data, 1);
01152 }

static int remote_send_hold_refresh ( struct ast_sip_session session,
unsigned int  held 
) [static]

Update local hold state and send a re-INVITE with the new SDP.

Definition at line 1139 of file chan_pjsip.c.

References ao2_callback, ao2_ref, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, local_hold_set_state(), ast_sip_session::media, NULL, and OBJ_NODATA.

Referenced by remote_send_hold(), and remote_send_unhold().

01140 {
01141    ao2_callback(session->media, OBJ_NODATA, local_hold_set_state, &held);
01142    ast_sip_session_refresh(session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
01143    ao2_ref(session, -1);
01144 
01145    return 0;
01146 }

static int remote_send_unhold ( void *  data  )  [static]

Update local hold state to be unheld.

Definition at line 1155 of file chan_pjsip.c.

References remote_send_hold_refresh().

Referenced by chan_pjsip_indicate().

01156 {
01157    return remote_send_hold_refresh(data, 0);
01158 }

static int request ( void *  obj  )  [static]

Definition at line 1836 of file chan_pjsip.c.

References ao2_cleanup, ast_sip_session::aor, args, AST_APP_ARG, AST_CAUSE_CHANNEL_UNACCEPTABLE, AST_CAUSE_NO_ROUTE_DESTINATION, AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, ast_sip_get_sorcery(), ast_sip_session_create_outgoing(), ast_sorcery_retrieve_by_id(), ast_strdupa, ast_strlen_zero, request_data::caps, request_data::cause, request_data::dest, ast_sip_session::endpoint, LOG_ERROR, NULL, RAII_VAR, request_data::session, session, and tmp().

Referenced by ast_http_body_discard(), ast_http_body_read_status(), ast_http_get_contents(), ast_http_request_close_on_completion(), ast_http_send(), AST_TEST_DEFINE(), bridge_manager_destroy(), bridge_manager_service_req(), bridge_manager_thread(), chan_pjsip_request(), ewscal_write_event(), get_ewscal_ids_for(), http_request_tracking_setup(), httpd_process_request(), parse_ewscal_id(), xmpp_pubsub_build_node_request(), xmpp_pubsub_build_publish_skeleton(), xmpp_pubsub_delete_node(), xmpp_pubsub_handle_error(), xmpp_pubsub_iq_create(), xmpp_pubsub_publish_device_state(), xmpp_pubsub_publish_mwi(), xmpp_pubsub_purge_nodes(), xmpp_pubsub_request_nodes(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

01837 {
01838    struct request_data *req_data = obj;
01839    struct ast_sip_session *session = NULL;
01840    char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
01841    RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
01842 
01843    AST_DECLARE_APP_ARGS(args,
01844       AST_APP_ARG(endpoint);
01845       AST_APP_ARG(aor);
01846    );
01847 
01848    if (ast_strlen_zero(tmp)) {
01849       ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty destination\n");
01850       req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
01851       return -1;
01852    }
01853 
01854    AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
01855 
01856    /* If a request user has been specified extract it from the endpoint name portion */
01857    if ((endpoint_name = strchr(args.endpoint, '@'))) {
01858       request_user = args.endpoint;
01859       *endpoint_name++ = '\0';
01860    } else {
01861       endpoint_name = args.endpoint;
01862    }
01863 
01864    if (ast_strlen_zero(endpoint_name)) {
01865       ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
01866       req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
01867    } else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
01868       ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
01869       req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
01870       return -1;
01871    }
01872 
01873    if (!(session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user, req_data->caps))) {
01874       ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
01875       req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
01876       return -1;
01877    }
01878 
01879    req_data->session = session;
01880 
01881    return 0;
01882 }

static int send_direct_media_request ( void *  data  )  [static]

Definition at line 219 of file chan_pjsip.c.

References ao2_ref, ast_sip_session_refresh(), ast_sip_endpoint_media_configuration::direct_media, ast_sip_session::endpoint, ast_sip_endpoint::media, ast_sip_direct_media_configuration::method, NULL, and session.

Referenced by chan_pjsip_set_rtp_peer().

00220 {
00221    struct ast_sip_session *session = data;
00222    int res;
00223 
00224    res = ast_sip_session_refresh(session, NULL, NULL, NULL,
00225       session->endpoint->media.direct_media.method, 1);
00226    ao2_ref(session, -1);
00227    return res;
00228 }

static int sendtext ( void *  obj  )  [static]

Definition at line 1934 of file chan_pjsip.c.

References ao2_cleanup, ast_debug, ast_sip_add_body(), ast_sip_create_request(), ast_sip_send_request(), NULL, RAII_VAR, and ast_sip_body::type.

Referenced by chan_pjsip_sendtext().

01935 {
01936    RAII_VAR(struct sendtext_data *, data, obj, ao2_cleanup);
01937    pjsip_tx_data *tdata;
01938 
01939    const struct ast_sip_body body = {
01940       .type = "text",
01941       .subtype = "plain",
01942       .body_text = data->text
01943    };
01944 
01945    ast_debug(3, "Sending in dialog SIP message\n");
01946 
01947    ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
01948    ast_sip_add_body(tdata, &body);
01949    ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
01950 
01951    return 0;
01952 }

static struct sendtext_data* sendtext_data_create ( struct ast_sip_session session,
const char *  text 
) [static, read]

Definition at line 1919 of file chan_pjsip.c.

References ao2_alloc, ao2_ref, ast_copy_string(), NULL, sendtext_data_destroy(), sendtext_data::session, and sendtext_data::text.

Referenced by chan_pjsip_sendtext().

01920 {
01921    int size = strlen(text) + 1;
01922    struct sendtext_data *data = ao2_alloc(sizeof(*data)+size, sendtext_data_destroy);
01923 
01924    if (!data) {
01925       return NULL;
01926    }
01927 
01928    data->session = session;
01929    ao2_ref(data->session, +1);
01930    ast_copy_string(data->text, text, size);
01931    return data;
01932 }

static void sendtext_data_destroy ( void *  obj  )  [static]

Definition at line 1913 of file chan_pjsip.c.

References ao2_ref, and sendtext_data::session.

Referenced by sendtext_data_create().

01914 {
01915    struct sendtext_data *data = obj;
01916    ao2_ref(data->session, -1);
01917 }

static void set_channel_on_rtp_instance ( struct chan_pjsip_pvt pvt,
const char *  channel_id 
) [static]

static int transfer ( void *  data  )  [static]

Definition at line 1447 of file chan_pjsip.c.

References ao2_cleanup, ao2_ref, ast_sip_endpoint::aors, ast_sip_get_sorcery(), ast_sip_location_retrieve_contact_from_aor_list(), ast_sorcery_retrieve_by_id(), AST_STATE_RING, ast_strlen_zero, ast_sip_session::channel, NULL, transfer_data::session, transfer_data::target, transfer_redirect(), transfer_refer(), and ast_sip_contact::uri.

01448 {
01449    struct transfer_data *trnf_data = data;
01450    struct ast_sip_endpoint *endpoint = NULL;
01451    struct ast_sip_contact *contact = NULL;
01452    const char *target = trnf_data->target;
01453 
01454    /* See if we have an endpoint; if so, use its contact */
01455    endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", target);
01456    if (endpoint) {
01457       contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
01458       if (contact && !ast_strlen_zero(contact->uri)) {
01459          target = contact->uri;
01460       }
01461    }
01462 
01463    if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
01464       transfer_redirect(trnf_data->session, target);
01465    } else {
01466       transfer_refer(trnf_data->session, target);
01467    }
01468 
01469    ao2_ref(trnf_data, -1);
01470    ao2_cleanup(endpoint);
01471    ao2_cleanup(contact);
01472    return 0;
01473 }

static struct transfer_data* transfer_data_alloc ( struct ast_sip_session session,
const char *  target 
) [static, read]

Definition at line 1366 of file chan_pjsip.c.

References ao2_alloc, ao2_ref, ast_strdup, NULL, transfer_data::session, transfer_data::target, and transfer_data_destroy().

Referenced by chan_pjsip_transfer().

01367 {
01368    struct transfer_data *trnf_data = ao2_alloc(sizeof(*trnf_data), transfer_data_destroy);
01369 
01370    if (!trnf_data) {
01371       return NULL;
01372    }
01373 
01374    if (!(trnf_data->target = ast_strdup(target))) {
01375       ao2_ref(trnf_data, -1);
01376       return NULL;
01377    }
01378 
01379    ao2_ref(session, +1);
01380    trnf_data->session = session;
01381 
01382    return trnf_data;
01383 }

static void transfer_data_destroy ( void *  obj  )  [static]

Definition at line 1358 of file chan_pjsip.c.

References ao2_cleanup, ast_free, transfer_data::session, and transfer_data::target.

Referenced by transfer_data_alloc().

01359 {
01360    struct transfer_data *trnf_data = obj;
01361 
01362    ast_free(trnf_data->target);
01363    ao2_cleanup(trnf_data->session);
01364 }

static void transfer_redirect ( struct ast_sip_session session,
const char *  target 
) [static]

Definition at line 1385 of file chan_pjsip.c.

References ast_channel_name(), AST_CONTROL_TRANSFER, ast_log, ast_queue_control_data(), ast_sip_session_send_response(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, ast_sip_session::channel, ast_sip_session::inv_session, LOG_WARNING, NULL, and tmp().

Referenced by transfer().

01386 {
01387    pjsip_tx_data *packet;
01388    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
01389    pjsip_contact_hdr *contact;
01390    pj_str_t tmp;
01391 
01392    if (pjsip_inv_end_session(session->inv_session, 302, NULL, &packet) != PJ_SUCCESS) {
01393       ast_log(LOG_WARNING, "Failed to redirect PJSIP session for channel %s\n",
01394          ast_channel_name(session->channel));
01395       message = AST_TRANSFER_FAILED;
01396       ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01397 
01398       return;
01399    }
01400 
01401    if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
01402       contact = pjsip_contact_hdr_create(packet->pool);
01403    }
01404 
01405    pj_strdup2_with_null(packet->pool, &tmp, target);
01406    if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
01407       ast_log(LOG_WARNING, "Failed to parse destination URI '%s' for channel %s\n",
01408          target, ast_channel_name(session->channel));
01409       message = AST_TRANSFER_FAILED;
01410       ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01411       pjsip_tx_data_dec_ref(packet);
01412 
01413       return;
01414    }
01415    pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
01416 
01417    ast_sip_session_send_response(session, packet);
01418    ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01419 }

static void transfer_refer ( struct ast_sip_session session,
const char *  target 
) [static]

Definition at line 1421 of file chan_pjsip.c.

References AST_CONTROL_TRANSFER, ast_queue_control_data(), AST_TRANSFER_FAILED, AST_TRANSFER_SUCCESS, ast_sip_session::channel, ast_sip_session::inv_session, NULL, sub, and tmp().

Referenced by transfer().

01422 {
01423    pjsip_evsub *sub;
01424    enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
01425    pj_str_t tmp;
01426    pjsip_tx_data *packet;
01427 
01428    if (pjsip_xfer_create_uac(session->inv_session->dlg, NULL, &sub) != PJ_SUCCESS) {
01429       message = AST_TRANSFER_FAILED;
01430       ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01431 
01432       return;
01433    }
01434 
01435    if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
01436       message = AST_TRANSFER_FAILED;
01437       ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01438       pjsip_evsub_terminate(sub, PJ_FALSE);
01439 
01440       return;
01441    }
01442 
01443    pjsip_xfer_send_request(sub, packet);
01444    ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));
01445 }

static int transmit_info_dtmf ( void *  data  )  [static]

Definition at line 1554 of file chan_pjsip.c.

References ao2_cleanup, ast_free_ptr, ast_log, ast_sip_add_body(), ast_sip_create_request(), ast_sip_session_send_request(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_sip_body::body_text, ast_sip_session::endpoint, ast_sip_session::inv_session, LOG_ERROR, NULL, RAII_VAR, session, and ast_sip_body::type.

Referenced by chan_pjsip_digit_end().

01555 {
01556    RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
01557 
01558    struct ast_sip_session *session = dtmf_data->session;
01559    struct pjsip_tx_data *tdata;
01560 
01561    RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
01562 
01563    struct ast_sip_body body = {
01564       .type = "application",
01565       .subtype = "dtmf-relay",
01566    };
01567 
01568    if (!(body_text = ast_str_create(32))) {
01569       ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
01570       return -1;
01571    }
01572    ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
01573 
01574    body.body_text = ast_str_buffer(body_text);
01575 
01576    if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
01577       ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
01578       return -1;
01579    }
01580    if (ast_sip_add_body(tdata, &body)) {
01581       ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
01582       pjsip_tx_data_dec_ref(tdata);
01583       return -1;
01584    }
01585    ast_sip_session_send_request(session, tdata);
01586 
01587    return 0;
01588 }

static int transmit_info_with_vidupdate ( void *  data  )  [static]

Send SIP INFO with video update request.

Definition at line 1012 of file chan_pjsip.c.

References ao2_cleanup, ast_log, ast_sip_add_body(), ast_sip_create_request(), ast_sip_session_send_request(), LOG_ERROR, NULL, RAII_VAR, session, and ast_sip_body::type.

Referenced by chan_pjsip_indicate(), and sip_indicate().

01013 {
01014    const char * xml =
01015       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
01016       " <media_control>\r\n"
01017       "  <vc_primitive>\r\n"
01018       "   <to_encoder>\r\n"
01019       "    <picture_fast_update/>\r\n"
01020       "   </to_encoder>\r\n"
01021       "  </vc_primitive>\r\n"
01022       " </media_control>\r\n";
01023 
01024    const struct ast_sip_body body = {
01025       .type = "application",
01026       .subtype = "media_control+xml",
01027       .body_text = xml
01028    };
01029 
01030    RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
01031    struct pjsip_tx_data *tdata;
01032 
01033    if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
01034       ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
01035       return -1;
01036    }
01037    if (ast_sip_add_body(tdata, &body)) {
01038       ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
01039       return -1;
01040    }
01041    ast_sip_session_send_request(session, tdata);
01042 
01043    return 0;
01044 }

static void transport_info_destroy ( void *  obj  )  [static]

Destructor function for transport_info_data.

Definition at line 231 of file chan_pjsip.c.

References ast_free.

00232 {
00233    struct transport_info_data *data = obj;
00234    ast_free(data);
00235 }

static int uid_hold_hash_fn ( const void *  obj,
const int  flags 
) [static]

AO2 hash function for on hold UIDs

Definition at line 724 of file chan_pjsip.c.

References ast_assert, ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by load_module().

00725 {
00726    const char *key = obj;
00727 
00728    switch (flags & OBJ_SEARCH_MASK) {
00729    case OBJ_SEARCH_KEY:
00730       break;
00731    case OBJ_SEARCH_OBJECT:
00732       break;
00733    default:
00734       /* Hash can only work on something with a full key. */
00735       ast_assert(0);
00736       return 0;
00737    }
00738    return ast_str_hash(key);
00739 }

static int uid_hold_sort_fn ( const void *  obj_left,
const void *  obj_right,
const int  flags 
) [static]

AO2 sort function for on hold UIDs

Definition at line 742 of file chan_pjsip.c.

References ast_assert, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by load_module().

00743 {
00744    const char *left = obj_left;
00745    const char *right = obj_right;
00746    int cmp;
00747 
00748    switch (flags & OBJ_SEARCH_MASK) {
00749    case OBJ_SEARCH_OBJECT:
00750    case OBJ_SEARCH_KEY:
00751       cmp = strcmp(left, right);
00752       break;
00753    case OBJ_SEARCH_PARTIAL_KEY:
00754       cmp = strncmp(left, right, strlen(right));
00755       break;
00756    default:
00757       /* Sort can only work on something with a full or partial key. */
00758       ast_assert(0);
00759       cmp = 0;
00760       break;
00761    }
00762    return cmp;
00763 }

static int unload_module ( void   )  [static]

static int update_connected_line_information ( void *  data  )  [static]

Update connected line information.

Definition at line 1082 of file chan_pjsip.c.

References ao2_ref, ast_sip_session_refresh(), AST_SIP_SESSION_REFRESH_METHOD_INVITE, AST_SIP_SESSION_REFRESH_METHOD_UPDATE, ast_sip_session_send_response(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_sip_session::channel, ast_sip_session::endpoint, ast_sip_endpoint::id, ast_sip_endpoint::inband_progress, ast_sip_session::inv_session, is_colp_update_allowed(), method, NULL, ast_sip_endpoint_id_configuration::refresh_method, ast_sip_endpoint_id_configuration::rpid_immediate, and session.

Referenced by chan_pjsip_indicate().

01083 {
01084    struct ast_sip_session *session = data;
01085 
01086    if (ast_channel_state(session->channel) == AST_STATE_UP
01087       || session->inv_session->role == PJSIP_ROLE_UAC) {
01088       if (is_colp_update_allowed(session)) {
01089          enum ast_sip_session_refresh_method method;
01090          int generate_new_sdp;
01091 
01092          method = session->endpoint->id.refresh_method;
01093          if (session->inv_session->invite_tsx
01094             && (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE)) {
01095             method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
01096          }
01097 
01098          /* Only the INVITE method actually needs SDP, UPDATE can do without */
01099          generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
01100 
01101          ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp);
01102       }
01103    } else if (session->endpoint->id.rpid_immediate
01104       && session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED
01105       && is_colp_update_allowed(session)) {
01106       int response_code = 0;
01107 
01108       if (ast_channel_state(session->channel) == AST_STATE_RING) {
01109          response_code = !session->endpoint->inband_progress ? 180 : 183;
01110       } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {
01111          response_code = 183;
01112       }
01113 
01114       if (response_code) {
01115          struct pjsip_tx_data *packet = NULL;
01116 
01117          if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
01118             ast_sip_session_send_response(session, packet);
01119          }
01120       }
01121    }
01122 
01123    ao2_ref(session, -1);
01124    return 0;
01125 }

static int update_devstate ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 2292 of file chan_pjsip.c.

References AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), and ast_sorcery_object_get_id().

Referenced by load_module().

02293 {
02294    ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE,
02295               "PJSIP/%s", ast_sorcery_object_get_id(obj));
02296    return 0;
02297 }

static void update_initial_connected_line ( struct ast_sip_session session  )  [static]

Definition at line 1639 of file chan_pjsip.c.

References ast_channel_caller(), ast_channel_lock, ast_channel_queue_connected_line_update(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, ast_party_connected_line_init(), ast_party_id_copy(), ast_sip_session::channel, ast_party_connected_line::id, ast_party_caller::id, ast_sip_session::id, ast_party_id::name, NULL, ast_party_id::number, ast_party_connected_line::source, ast_party_name::valid, and ast_party_number::valid.

Referenced by call().

01640 {
01641    struct ast_party_connected_line connected;
01642 
01643    /*
01644     * Use the channel CALLERID() as the initial connected line data.
01645     * The core or a predial handler may have supplied missing values
01646     * from the session->endpoint->id.self about who we are calling.
01647     */
01648    ast_channel_lock(session->channel);
01649    ast_party_id_copy(&session->id, &ast_channel_caller(session->channel)->id);
01650    ast_channel_unlock(session->channel);
01651 
01652    /* Supply initial connected line information if available. */
01653    if (!session->id.number.valid && !session->id.name.valid) {
01654       return;
01655    }
01656 
01657    ast_party_connected_line_init(&connected);
01658    connected.id = session->id;
01659    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
01660 
01661    ast_channel_queue_connected_line_update(session->channel, &connected, NULL);
01662 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static]

Definition at line 2428 of file chan_pjsip.c.

Definition at line 2428 of file chan_pjsip.c.

Initial value:

 {
   .method = "INVITE",
   .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
   .incoming_request = call_pickup_incoming_request,
}

Definition at line 2192 of file chan_pjsip.c.

unsigned int chan_idx [static]

Definition at line 78 of file chan_pjsip.c.

Initial value:

 {
   .method = "ACK",
   .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
   .incoming_request = chan_pjsip_incoming_ack,
}

Definition at line 153 of file chan_pjsip.c.

Initial value:

 {
   .name = "PJSIP_DIAL_CONTACTS",
   .read = pjsip_acf_dial_contacts_read,
}

Definition at line 2299 of file chan_pjsip.c.

Local glue for interacting with the RTP engine core.

Definition at line 353 of file chan_pjsip.c.

SIP session supplement structure.

Definition at line 140 of file chan_pjsip.c.

PBX interface structure for channel registration.

Definition at line 109 of file chan_pjsip.c.

const char channel_type[] = "PJSIP" [static]

Definition at line 76 of file chan_pjsip.c.

Definition at line 244 of file chan_pjsip.c.

Initial value:

 {
   .name = "PJSIP_MEDIA_OFFER",
   .read = pjsip_acf_media_offer_read,
   .write = pjsip_acf_media_offer_write
}

Definition at line 2304 of file chan_pjsip.c.

Initial value:

 {
   .method = "INVITE",
   .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST,
   .incoming_request = pbx_start_incoming_request,
}

Definition at line 2230 of file chan_pjsip.c.

struct ao2_container* pjsip_uids_onhold [static]

Definition at line 765 of file chan_pjsip.c.

Initial value:

 {
   .type = "chan_pjsip_transport_info",
   .destroy = transport_info_destroy,
}
Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel.

Definition at line 239 of file chan_pjsip.c.

struct ast_threadstorage uniqueid_threadbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_uniqueid_threadbuf , .custom_init = NULL , } [static]

Definition at line 73 of file chan_pjsip.c.

Referenced by chan_pjsip_get_uniqueid().


Generated on Thu Apr 16 06:29:49 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6