57 #include "asterisk/stasis_channels.h"
62 #include "asterisk/features_config.h"
67 #include "asterisk/res_pjsip.h"
68 #include "asterisk/res_pjsip_session.h"
76 #define UNIQUEID_BUFSIZE 256
78 static const char channel_type[] =
"PJSIP";
80 static unsigned int chan_idx;
82 static void chan_pjsip_pvt_dtor(
void *obj)
92 static int chan_pjsip_sendtext(
struct ast_channel *ast,
const char *text);
106 static const char *chan_pjsip_get_uniqueid(
struct ast_channel *ast);
110 .type = channel_type,
111 .description =
"PJSIP Channel Driver",
114 .send_text = chan_pjsip_sendtext,
122 .write = chan_pjsip_write,
123 .write_stream = chan_pjsip_write_stream,
131 .get_pvt_uniqueid = chan_pjsip_get_uniqueid,
145 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
151 .response_priority = AST_SIP_SESSION_AFTER_MEDIA,
157 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
159 .response_priority = AST_SIP_SESSION_BEFORE_MEDIA | AST_SIP_SESSION_AFTER_MEDIA,
162 static int chan_pjsip_incoming_ack(
struct ast_sip_session *session,
struct pjsip_rx_data *rdata);
166 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
167 .incoming_request = chan_pjsip_incoming_ack,
170 static int chan_pjsip_incoming_prack(
struct ast_sip_session *session,
struct pjsip_rx_data *rdata);
174 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL,
175 .incoming_request = chan_pjsip_incoming_prack,
186 if (!channel || !channel->
session) {
195 if (!media || !media->
rtp) {
199 datastore = ast_sip_session_get_datastore(channel->
session,
"t38");
207 *instance = media->
rtp;
210 ast_assert(endpoint != NULL);
229 if (!channel || !channel->
session) {
234 if (!media || !media->
rtp) {
240 *instance = media->
rtp;
243 ast_assert(endpoint != NULL);
254 SCOPE_ENTER(1,
"%s Native formats %s\n", ast_channel_name(chan),
270 .
type =
"chan_pjsip_transport_info",
276 static int direct_media_mitigate_glare(
struct ast_sip_session *session)
281 AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
285 datastore = ast_sip_session_get_datastore(session,
"direct_media_glare_mitigation");
291 ast_sip_session_remove_datastore(session,
"direct_media_glare_mitigation");
294 AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING &&
297 AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING &&
330 int changed = 0, position = -1;
339 if (position != -1) {
349 if (position != -1) {
366 static void rtp_direct_media_data_destroy(
void *data)
370 ao2_cleanup(cdata->session);
371 ao2_cleanup(cdata->cap);
372 ao2_cleanup(cdata->vrtp);
373 ao2_cleanup(cdata->rtp);
374 ao2_cleanup(cdata->chan);
396 static int send_direct_media_request(
void *data)
412 ast_channel_lock(cdata->chan);
422 ast_channel_unlock(cdata->chan);
424 if (direct_media_mitigate_glare(cdata->session)) {
425 ast_debug(4,
"Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(cdata->chan));
438 ast_debug(4,
"RTP changed on %s; initiating direct media update\n", ast_channel_name(cdata->chan));
439 res = ast_sip_session_refresh(cdata->session, NULL, NULL, NULL,
458 SCOPE_ENTER(1,
"%s %s\n", ast_channel_name(chan),
463 ast_debug(4,
"Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
464 SCOPE_EXIT_RTN_VALUE(0,
"Channel not bridged\n");
468 ast_debug(4,
"Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
469 SCOPE_EXIT_RTN_VALUE(0,
"NAT is active\n");
472 cdata = rtp_direct_media_data_create(chan, rtp, vrtp, cap, session);
474 SCOPE_EXIT_RTN_VALUE(0);
478 ast_log(LOG_ERROR,
"Unable to send direct media request for channel %s\n", ast_channel_name(chan));
482 SCOPE_EXIT_RTN_VALUE(0);
494 static void set_channel_on_rtp_instance(
const struct ast_sip_session *session,
495 const char *channel_id)
503 if (!session_media || !session_media->
rtp) {
530 SCOPE_ENTER(1,
"Topology: %s Formats: %s\n",
537 SCOPE_EXIT_RTN_VALUE(0,
"Topology had no formats\n");
543 SCOPE_EXIT_RTN_VALUE(res,
"Compatible? %s\n", res ?
"yes" :
"no");
555 SCOPE_ENTER(1,
"%s\n", ast_sip_session_get_name(session));
558 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't create pvt\n");
561 chan = ast_channel_alloc_with_endpoint(1, state,
566 assignedids, requestor, 0,
571 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't create channel\n");
574 ast_channel_tech_set(chan, &chan_pjsip_tech);
576 if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
577 ast_channel_unlock(chan);
579 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't create pvt channel\n");
582 ast_channel_tech_pvt_set(chan, channel);
588 ast_channel_unlock(chan);
590 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't create caps\n");
599 if (!topology || !caps) {
602 ast_channel_unlock(chan);
604 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't get caps or clone topology\n");
609 ast_channel_nativeformats_set(chan, caps);
620 ast_channel_set_writeformat(chan, fmt);
621 ast_channel_set_rawwriteformat(chan, fmt);
622 ast_channel_set_readformat(chan, fmt);
623 ast_channel_set_rawreadformat(chan, fmt);
630 ast_channel_rings_set(chan, 1);
633 ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
637 ast_channel_caller(chan)->
ani2 = session->
ani2;
639 if (!ast_strlen_zero(exten)) {
644 ast_channel_priority_set(chan, 1);
659 ast_log(LOG_ERROR,
"Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->
endpoint->
zone);
661 ast_channel_zone_set(chan, zone);
667 var->
value, buf,
sizeof(buf)));
671 ast_channel_unlock(chan);
673 set_channel_on_rtp_instance(session, ast_channel_uniqueid(chan));
675 SCOPE_EXIT_RTN_VALUE(chan);
680 unsigned long indent;
683 static int answer(
void *data)
686 pj_status_t status = PJ_SUCCESS;
687 pjsip_tx_data *packet = NULL;
689 SCOPE_ENTER_TASK(1, ans_data->indent,
"%s\n", ast_sip_session_get_name(session));
691 if (session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
692 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
694 pjsip_get_status_text(session->
inv_session->cause)->ptr);
695 SCOPE_EXIT_RTN_VALUE(0,
"Disconnected\n");
700 status = pjsip_inv_answer(session->
inv_session, 200, NULL, NULL, &packet);
702 ast_log(LOG_ERROR,
"Cannot answer '%s' because there is no associated SIP transaction\n",
703 ast_channel_name(session->
channel));
707 if (status == PJ_SUCCESS && packet) {
708 ast_sip_session_send_response(session, packet);
711 if (status != PJ_SUCCESS) {
712 char err[PJ_ERR_MSG_SIZE];
714 pj_strerror(status, err,
sizeof(err));
715 ast_log(LOG_WARNING,
"Cannot answer '%s': %s\n",
716 ast_channel_name(session->
channel), err);
721 SCOPE_EXIT_RTN_VALUE(-2,
"pjproject failure\n");
723 SCOPE_EXIT_RTN_VALUE(0);
733 SCOPE_ENTER(1,
"%s\n", ast_channel_name(ast));
736 SCOPE_EXIT_RTN_VALUE(0,
"Already up\n");
746 ast_channel_unlock(ast);
747 ans_data.session = session;
748 ans_data.indent = ast_trace_get_indent();
752 ast_log(LOG_ERROR,
"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
753 ast_channel_name(session->
channel));
756 ast_channel_lock(ast);
757 SCOPE_EXIT_RTN_VALUE(-1,
"Couldn't push task\n");
760 ast_channel_lock(ast);
762 SCOPE_EXIT_RTN_VALUE(0);
769 const char *target_context;
774 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
778 ast_dsp_free(session->
dsp);
783 if (!strcmp(ast_channel_exten(ast),
"fax")) {
787 target_context = ast_channel_context(ast);
796 ast_channel_unlock(ast);
801 ast_channel_caller(ast)->
id.
number.str, NULL));
803 ast_verb(2,
"Redirecting '%s' to fax extension due to CNG detection\n",
804 ast_channel_name(ast));
807 ast_log(LOG_ERROR,
"Failed to async goto '%s' into fax extension in '%s'\n",
808 ast_channel_name(ast), target_context);
811 ast_log(LOG_NOTICE,
"FAX CNG detected on '%s' but no fax extension in '%s'\n",
812 ast_channel_name(ast), target_context);
819 ast_channel_lock(ast);
882 ast_debug(1,
"Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
891 ast_channel_nativeformats_set(ast, caps);
905 ast_debug(1,
"Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
915 if ((dsp_features & DSP_FEATURE_FAX_DETECT)
918 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
922 ast_dsp_free(session->
dsp);
925 ast_debug(3,
"Channel driver fax CNG detection timeout on %s\n",
926 ast_channel_name(ast));
931 if (f && (f->
frametype == AST_FRAME_DTMF)) {
933 ast_debug(3,
"Channel driver fax CNG detected on %s\n",
934 ast_channel_name(ast));
942 ast_channel_name(ast));
950 static int chan_pjsip_write_stream(
struct ast_channel *ast,
int stream_num,
struct ast_frame *frame)
958 if (stream_num >= 0) {
969 }
else if (media->
type != AST_MEDIA_TYPE_AUDIO) {
970 ast_debug(3,
"Channel %s stream %d is of type '%s', not audio!\n",
976 struct ast_str *write_transpath = ast_str_alloca(256);
977 struct ast_str *read_transpath = ast_str_alloca(256);
980 "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
981 ast_channel_name(ast),
999 }
else if (media->
type != AST_MEDIA_TYPE_VIDEO) {
1000 ast_debug(3,
"Channel %s stream %d is of type '%s', not video!\n",
1010 }
else if (media->
type != AST_MEDIA_TYPE_IMAGE) {
1011 ast_debug(3,
"Channel %s stream %d is of type '%s', not image!\n",
1024 }
else if (media->
type != AST_MEDIA_TYPE_VIDEO) {
1025 ast_debug(3,
"Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n",
1033 ast_log(LOG_WARNING,
"Can't send %u type frames with PJSIP\n", frame->
frametype);
1042 return chan_pjsip_write_stream(ast, -1, frame);
1061 set_channel_on_rtp_instance(channel->
session, ast_channel_uniqueid(newchan));
1069 const char *key = obj;
1087 const char *left = obj_left;
1088 const char *right = obj_right;
1094 cmp = strcmp(left, right);
1097 cmp = strncmp(left, right, strlen(right));
1120 RAII_VAR(
char *, hold_uid, NULL, ao2_cleanup);
1122 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid,
OBJ_SEARCH_KEY);
1129 hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1137 if (
ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1164 RAII_VAR(
char *, hold_uid, NULL, ao2_cleanup);
1166 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid,
OBJ_SEARCH_KEY);
1190 if (!endpoint_snapshot) {
1200 if (!endpoint_snapshot->num_channels) {
1206 for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1228 if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
1249 case AST_OPTION_T38_STATE:
1252 case T38_LOCAL_REINVITE:
1253 case T38_PEER_REINVITE:
1279 static const char *chan_pjsip_get_uniqueid(
struct ast_channel *ast)
1284 if (!channel || !uniqueid) {
1288 ast_copy_pj_str(uniqueid, &channel->
session->
inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1301 static void indicate_data_destroy(
void *obj)
1305 ast_free(ind_data->frame_data);
1306 ao2_ref(ind_data->session, -1);
1310 int condition,
int response_code,
const void *frame_data,
size_t datalen)
1312 struct indicate_data *ind_data = ao2_alloc(
sizeof(*ind_data), indicate_data_destroy);
1319 if (!ind_data->frame_data) {
1324 memcpy(ind_data->frame_data, frame_data, datalen);
1325 ind_data->datalen = datalen;
1326 ind_data->condition = condition;
1327 ind_data->response_code = response_code;
1329 ind_data->session = session;
1334 static int indicate(
void *data)
1336 pjsip_tx_data *packet = NULL;
1339 int response_code = ind_data->response_code;
1341 if ((session->
inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1342 (pjsip_inv_answer(session->
inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1343 ast_sip_session_send_response(session, packet);
1355 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
1356 " <media_control>\r\n"
1357 " <vc_primitive>\r\n"
1359 " <picture_fast_update/>\r\n"
1360 " </to_encoder>\r\n"
1361 " </vc_primitive>\r\n"
1362 " </media_control>\r\n";
1365 .
type =
"application",
1366 .subtype =
"media_control+xml",
1371 struct pjsip_tx_data *tdata;
1373 if (session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1374 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
1376 pjsip_get_status_text(session->
inv_session->cause)->ptr);
1380 if (ast_sip_create_request(
"INFO", session->
inv_session->dlg, session->
endpoint, NULL, NULL, &tdata)) {
1381 ast_log(LOG_ERROR,
"Could not create text video update INFO request\n");
1384 if (ast_sip_add_body(tdata, &body)) {
1385 ast_log(LOG_ERROR,
"Could not add body to text video update INFO request\n");
1388 ast_sip_session_send_request(session, tdata);
1406 int update_allowed = 0;
1417 ast_channel_lock(session->
channel);
1418 connected_id = ast_channel_connected_effective_id(session->
channel);
1419 if (connected_id.number.valid
1424 ast_channel_unlock(session->
channel);
1426 return update_allowed;
1434 if (session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1435 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
1437 pjsip_get_status_text(session->
inv_session->cause)->ptr);
1443 || session->
inv_session->role == PJSIP_ROLE_UAC) {
1444 if (is_colp_update_allowed(session)) {
1445 enum ast_sip_session_refresh_method method;
1446 int generate_new_sdp;
1449 if (session->
inv_session->options & PJSIP_INV_SUPPORT_UPDATE) {
1450 method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
1454 generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
1456 ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp, NULL);
1459 && session->
inv_session->state != PJSIP_INV_STATE_DISCONNECTED
1460 && is_colp_update_allowed(session)) {
1461 int response_code = 0;
1466 response_code = 183;
1469 if (response_code) {
1470 struct pjsip_tx_data *packet = NULL;
1472 if (pjsip_inv_answer(session->
inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
1473 ast_sip_session_send_response(session, packet);
1486 if (session_media) {
1489 ast_sip_session_refresh(session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, NULL);
1514 ao2_cleanup(refresh_data->session);
1516 ast_sip_session_media_state_free(refresh_data->media_state);
1517 ast_free(refresh_data);
1525 refresh_data =
ast_calloc(1,
sizeof(*refresh_data));
1526 if (!refresh_data) {
1530 refresh_data->session =
ao2_bump(session);
1531 refresh_data->media_state = ast_sip_session_media_state_alloc();
1532 if (!refresh_data->media_state) {
1533 topology_change_refresh_data_free(refresh_data);
1537 if (!refresh_data->media_state->
topology) {
1538 topology_change_refresh_data_free(refresh_data);
1542 return refresh_data;
1545 static int on_topology_change_response(
struct ast_sip_session *session, pjsip_rx_data *rdata)
1547 SCOPE_ENTER(3,
"%s: Received response code %d. PT: %s AT: %s\n", ast_sip_session_get_name(session),
1548 rdata->msg_info.msg->line.status.code,
1553 if (PJSIP_IS_STATUS_IN_CLASS(rdata->msg_info.msg->line.status.code, 200)) {
1559 SCOPE_EXIT_RTN_VALUE(0,
"%s: Queued topology change frame\n", ast_sip_session_get_name(session));
1561 SCOPE_EXIT_RTN_VALUE(0,
"%s: No channel? Can't queue topology change frame\n", ast_sip_session_get_name(session));
1562 }
else if (300 <= rdata->msg_info.msg->line.status.code) {
1565 SCOPE_EXIT_RTN_VALUE(0,
"%s: response code > 300. Resetting pending media state\n", ast_sip_session_get_name(session));
1568 SCOPE_EXIT_RTN_VALUE(0,
"%s: Nothing to do\n", ast_sip_session_get_name(session));
1571 static int send_topology_change_refresh(
void *data)
1576 enum ast_sip_session_refresh_method method = AST_SIP_SESSION_REFRESH_METHOD_INVITE;
1578 SCOPE_ENTER(3,
"%s: %s\n", ast_sip_session_get_name(session),
1586 method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
1589 ret = ast_sip_session_refresh(session, NULL, NULL, on_topology_change_response,
1590 method, 1, refresh_data->media_state);
1591 refresh_data->media_state = NULL;
1592 topology_change_refresh_data_free(refresh_data);
1594 SCOPE_EXIT_RTN_VALUE(ret,
"%s\n", ast_sip_session_get_name(session));
1597 static int handle_topology_request_change(
struct ast_sip_session *session,
1604 refresh_data = topology_change_refresh_data_alloc(session, proposed);
1605 if (!refresh_data) {
1606 SCOPE_EXIT_RTN_VALUE(-1,
"Couldn't create refresh_data\n");
1611 topology_change_refresh_data_free(refresh_data);
1613 SCOPE_EXIT_RTN_VALUE(res,
"RC: %d\n", res);
1617 static int transmit_info_dtmf(
void *data);
1625 int response_code = 0;
1628 size_t device_buf_size;
1634 .integer = condition
1637 .data.ptr = (
void *)data,
1639 char condition_name[256];
1640 unsigned int duration;
1644 SCOPE_ENTER(3,
"%s: Indicated %s\n", ast_channel_name(ast),
1647 switch (condition) {
1652 pjmedia_sdp_neg_get_state(channel->
session->
inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1654 if (ast_sip_get_allow_sending_180_after_183()) {
1655 response_code = 180;
1657 response_code = 183;
1660 response_code = 180;
1669 response_code = 486;
1676 response_code = 503;
1683 response_code = 484;
1690 response_code = 100;
1697 response_code = 183;
1706 dtmf_data = info_dtmf_data_alloc(channel->
session, digit, duration);
1714 ast_log(LOG_WARNING,
"Error sending FLASH via INFO on channel %s\n", ast_channel_name(ast));
1722 if (!media || media->
type != AST_MEDIA_TYPE_VIDEO) {
1744 ao2_cleanup(channel->
session);
1760 ao2_cleanup(channel->
session);
1769 ast_assert(datalen ==
sizeof(
int));
1770 if (*(
int *) data) {
1775 ast_channel_unlock(ast);
1776 ast_sip_session_suspend(channel->
session);
1777 ast_channel_lock(ast);
1783 ast_sip_session_unsuspend(channel->
session);
1788 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1789 device_buf = alloca(device_buf_size);
1796 ast_log(LOG_WARNING,
"Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1804 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1805 device_buf = alloca(device_buf_size);
1812 ast_log(LOG_WARNING,
"Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1824 response_code = 181;
1843 ast_trace(-1,
"%s: New topology: %s\n", ast_channel_name(ast),
1845 res = handle_topology_request_change(channel->
session, topology);
1855 ast_log(LOG_WARNING,
"Don't know how to indicate condition %d\n", condition);
1860 if (response_code) {
1861 struct indicate_data *ind_data = indicate_data_alloc(channel->
session, condition, response_code, data, datalen);
1864 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
"%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1868 ast_log(LOG_ERROR,
"%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1870 ao2_cleanup(ind_data);
1875 SCOPE_EXIT_RTN_VALUE(res,
"%s\n", ast_channel_name(ast));
1883 static void transfer_data_destroy(
void *obj)
1887 ast_free(trnf_data->target);
1888 ao2_cleanup(trnf_data->session);
1893 struct transfer_data *trnf_data = ao2_alloc(
sizeof(*trnf_data), transfer_data_destroy);
1899 if (!(trnf_data->target =
ast_strdup(target))) {
1905 trnf_data->session = session;
1910 static void transfer_redirect(
struct ast_sip_session *session,
const char *target)
1912 pjsip_tx_data *packet;
1914 pjsip_contact_hdr *contact;
1917 if (pjsip_inv_end_session(session->
inv_session, 302, NULL, &packet) != PJ_SUCCESS
1919 ast_log(LOG_WARNING,
"Failed to redirect PJSIP session for channel %s\n",
1920 ast_channel_name(session->
channel));
1927 if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
1928 contact = pjsip_contact_hdr_create(packet->pool);
1931 pj_strdup2_with_null(packet->pool, &tmp, target);
1932 if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
1933 ast_log(LOG_WARNING,
"Failed to parse destination URI '%s' for channel %s\n",
1934 target, ast_channel_name(session->
channel));
1937 pjsip_tx_data_dec_ref(packet);
1941 pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
1943 ast_sip_session_send_response(session, packet);
1949 .name = {
"REFER Callback", 14 },
1970 chan = pjsip_evsub_get_mod_data(sub, refer_callback_module.id);
1975 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
1977 pjsip_rx_data *rdata;
1978 pjsip_generic_string_hdr *refer_sub;
1979 const pj_str_t REFER_SUB = {
"Refer-Sub", 9 };
1981 ast_debug(3,
"Transfer accepted on channel %s\n", ast_channel_name(chan));
1984 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1985 rdata =
event->body.tsx_state.src.rdata;
1988 refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB, NULL);
1994 if (refer_sub && !pj_stricmp2(&refer_sub->hvalue,
"false")) {
1998 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
1999 pjsip_evsub_terminate(sub, PJ_TRUE);
2003 }
else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
2004 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
2007 pjsip_msg_body *body;
2008 pjsip_status_line status_line = { .code = 0 };
2012 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
2013 pjsip_rx_data *rdata;
2015 rdata =
event->body.tsx_state.src.rdata;
2016 msg = rdata->msg_info.msg;
2018 if (msg->type == PJSIP_REQUEST_MSG) {
2019 if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
2021 if (body && !pj_stricmp2(&body->content_type.type,
"message")
2022 && !pj_stricmp2(&body->content_type.subtype,
"sipfrag")) {
2023 pjsip_parse_status_line((
char *)body->data, body->len, &status_line);
2027 status_line.code = msg->line.status.code;
2028 status_line.reason = msg->line.status.reason;
2031 status_line.code = 500;
2032 status_line.reason = *pjsip_get_status_text(500);
2035 is_last = (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED);
2037 if (status_line.code >= 200 || is_last) {
2045 if (status_line.code < 200) {
2047 }
else if (status_line.code >= 300) {
2048 message = status_line.code;
2054 pjsip_tx_data *tdata;
2056 status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(), 0, &tdata);
2057 if (status == PJ_SUCCESS) {
2058 pjsip_evsub_send_request(sub, tdata);
2062 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2063 ast_debug(3,
"Transfer channel %s completed: %d %.*s (%s)\n",
2064 ast_channel_name(chan),
2066 (
int)status_line.reason.slen, status_line.reason.ptr,
2077 static void transfer_refer(
struct ast_sip_session *session,
const char *target)
2082 pjsip_tx_data *packet;
2083 const char *ref_by_val;
2084 char local_info[pj_strlen(&session->
inv_session->dlg->local.info_str) + 1];
2085 struct pjsip_evsub_user xfer_cb;
2088 pj_bzero(&xfer_cb,
sizeof(xfer_cb));
2091 if (pjsip_xfer_create_uac(session->
inv_session->dlg, &xfer_cb, &sub) != PJ_SUCCESS) {
2101 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, chan);
2104 if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
2109 if (!ast_strlen_zero(ref_by_val)) {
2110 ast_sip_add_header(packet,
"Referred-By", ref_by_val);
2112 ast_copy_pj_str(local_info, &session->
inv_session->dlg->local.info_str,
sizeof(local_info));
2113 ast_sip_add_header(packet,
"Referred-By", local_info);
2116 if (pjsip_xfer_send_request(sub, packet) == PJ_SUCCESS) {
2123 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2124 pjsip_evsub_terminate(sub, PJ_FALSE);
2129 static int transfer(
void *data)
2134 const char *target = trnf_data->target;
2136 if (trnf_data->session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2137 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
2139 pjsip_get_status_text(trnf_data->session->
inv_session->cause)->ptr);
2144 contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->
aors);
2145 if (contact && !ast_strlen_zero(contact->
uri)) {
2146 target = contact->
uri;
2151 transfer_redirect(trnf_data->session, target);
2153 transfer_refer(trnf_data->session, target);
2158 ao2_cleanup(endpoint);
2159 ao2_cleanup(contact);
2174 ast_log(LOG_WARNING,
"Error requesting transfer\n");
2175 ao2_cleanup(trnf_data);
2191 case AST_SIP_DTMF_RFC_4733:
2192 if (!media || !media->
rtp) {
2198 case AST_SIP_DTMF_AUTO:
2199 if (!media || !media->
rtp) {
2209 case AST_SIP_DTMF_AUTO_INFO:
2215 case AST_SIP_DTMF_NONE:
2217 case AST_SIP_DTMF_INBAND:
2229 unsigned int duration;
2232 static void info_dtmf_data_destroy(
void *obj)
2235 ao2_ref(dtmf_data->session, -1);
2240 struct info_dtmf_data *dtmf_data = ao2_alloc(
sizeof(*dtmf_data), info_dtmf_data_destroy);
2245 dtmf_data->session = session;
2246 dtmf_data->digit = digit;
2247 dtmf_data->duration = duration;
2251 static int transmit_info_dtmf(
void *data)
2256 struct pjsip_tx_data *tdata;
2261 .
type =
"application",
2262 .subtype =
"dtmf-relay",
2265 if (session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2266 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
2268 pjsip_get_status_text(session->
inv_session->cause)->ptr);
2273 ast_log(LOG_ERROR,
"Could not allocate buffer for INFO DTMF.\n");
2276 ast_str_set(&
body_text, 0,
"Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
2280 if (ast_sip_create_request(
"INFO", session->
inv_session->dlg, session->
endpoint, NULL, NULL, &tdata)) {
2281 ast_log(LOG_ERROR,
"Could not create DTMF INFO request\n");
2284 if (ast_sip_add_body(tdata, &body)) {
2285 ast_log(LOG_ERROR,
"Could not add body to DTMF INFO request\n");
2286 pjsip_tx_data_dec_ref(tdata);
2289 ast_sip_session_send_request(session, tdata);
2300 if (!channel || !channel->
session) {
2302 ast_debug(3,
"Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2309 case AST_SIP_DTMF_AUTO_INFO:
2311 if (!media || !media->
rtp) {
2316 ast_debug(3,
"Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2317 ast_rtp_instance_dtmf_end_with_duration(media->
rtp, digit, duration);
2321 ast_debug(3,
"Told to send end of digit on Auto-Info channel %s RFC4733 NOT negotiated using INFO instead.\n", ast_channel_name(ast));
2324 case AST_SIP_DTMF_INFO:
2333 ast_log(LOG_WARNING,
"Error sending DTMF via INFO.\n");
2334 ao2_cleanup(dtmf_data);
2339 case AST_SIP_DTMF_RFC_4733:
2340 if (!media || !media->
rtp) {
2344 ast_rtp_instance_dtmf_end_with_duration(media->
rtp, digit, duration);
2346 case AST_SIP_DTMF_AUTO:
2347 if (!media || !media->
rtp) {
2355 ast_rtp_instance_dtmf_end_with_duration(media->
rtp, digit, duration);
2357 case AST_SIP_DTMF_NONE:
2359 case AST_SIP_DTMF_INBAND:
2366 static void update_initial_connected_line(
struct ast_sip_session *session)
2375 ast_channel_lock(session->
channel);
2377 ast_channel_unlock(session->
channel);
2385 connected.id = session->
id;
2391 static int call(
void *data)
2395 pjsip_tx_data *tdata;
2397 SCOPE_ENTER(1,
"%s Topology: %s\n",
2398 ast_sip_session_get_name(session),
2403 res = ast_sip_session_create_invite(session, &tdata);
2409 set_channel_on_rtp_instance(session, ast_channel_uniqueid(session->
channel));
2410 update_initial_connected_line(session);
2411 ast_sip_session_send_request(session, tdata);
2414 SCOPE_EXIT_RTN_VALUE(res,
"RC: %d\n", res);
2421 SCOPE_ENTER(1,
"%s Topology: %s\n", ast_sip_session_get_name(channel->
session),
2426 ast_log(LOG_WARNING,
"Error attempting to place outbound call to '%s'\n", dest);
2427 ao2_cleanup(channel);
2428 SCOPE_EXIT_RTN_VALUE(-1,
"Couldn't push task\n");
2431 SCOPE_EXIT_RTN_VALUE(0,
"'call' task pushed\n");
2438 case AST_CAUSE_UNALLOCATED:
2439 case AST_CAUSE_NO_ROUTE_DESTINATION:
2440 case AST_CAUSE_NO_ROUTE_TRANSIT_NET:
2442 case AST_CAUSE_CONGESTION:
2443 case AST_CAUSE_SWITCH_CONGESTION:
2445 case AST_CAUSE_NO_USER_RESPONSE:
2447 case AST_CAUSE_NO_ANSWER:
2448 case AST_CAUSE_UNREGISTERED:
2450 case AST_CAUSE_CALL_REJECTED:
2452 case AST_CAUSE_NUMBER_CHANGED:
2454 case AST_CAUSE_NORMAL_UNSPECIFIED:
2456 case AST_CAUSE_INVALID_NUMBER_FORMAT:
2458 case AST_CAUSE_USER_BUSY:
2460 case AST_CAUSE_FAILURE:
2462 case AST_CAUSE_FACILITY_REJECTED:
2464 case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
2466 case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
2468 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:
2470 case AST_CAUSE_INTERWORKING:
2472 case AST_CAUSE_NOTDEFINED:
2474 ast_debug(1,
"AST hangup cause %d (no match found in PJSIP)\n", cause);
2487 static void hangup_data_destroy(
void *obj)
2496 struct hangup_data *h_data = ao2_alloc(
sizeof(*h_data), hangup_data_destroy);
2502 h_data->cause = cause;
2512 set_channel_on_rtp_instance(session,
"");
2513 ast_channel_tech_pvt_set(ast, NULL);
2516 static int hangup(
void *data)
2521 SCOPE_ENTER(1,
"%s\n", ast_channel_name(ast));
2531 int cause = h_data->cause;
2547 ast_sip_session_terminate(
ao2_bump(session), cause);
2549 ao2_cleanup(session);
2551 ao2_cleanup(channel);
2553 ao2_cleanup(h_data);
2554 SCOPE_EXIT_RTN_VALUE(0);
2563 SCOPE_ENTER(1,
"%s\n", ast_channel_name(ast));
2565 if (!channel || !channel->
session) {
2566 SCOPE_EXIT_RTN_VALUE(-1,
"No channel or session\n");
2570 h_data = hangup_data_alloc(cause, ast);
2577 ast_log(LOG_WARNING,
"Unable to push hangup task to the threadpool. Expect bad things\n");
2581 SCOPE_EXIT_RTN_VALUE(0,
"Cause: %d\n", cause);
2588 ao2_cleanup(channel);
2589 ao2_cleanup(h_data);
2591 SCOPE_EXIT_RTN_VALUE(-1,
"Cause: %d\n", cause);
2601 static int request(
void *obj)
2605 char *tmp =
ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
2612 SCOPE_ENTER(1,
"%s\n",tmp);
2614 if (ast_strlen_zero(tmp)) {
2615 ast_log(LOG_ERROR,
"Unable to create PJSIP channel with empty destination\n");
2616 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
2617 SCOPE_EXIT_RTN_VALUE(-1,
"Empty destination\n");
2622 if (ast_sip_get_disable_multi_domain()) {
2624 if ((endpoint_name = strchr(args.endpoint,
'@'))) {
2625 request_user = args.endpoint;
2626 *endpoint_name++ =
'\0';
2628 endpoint_name = args.endpoint;
2631 if (ast_strlen_zero(endpoint_name)) {
2633 ast_log(LOG_ERROR,
"Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2636 ast_log(LOG_ERROR,
"Unable to create PJSIP channel with empty endpoint name\n");
2638 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
2639 SCOPE_EXIT_RTN_VALUE(-1,
"Empty endpoint name\n");
2644 ast_log(LOG_ERROR,
"Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2645 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
2646 SCOPE_EXIT_RTN_VALUE(-1,
"Endpoint not found\n");
2650 endpoint_name = args.endpoint;
2651 if (ast_strlen_zero(endpoint_name)) {
2652 ast_log(LOG_ERROR,
"Unable to create PJSIP channel with empty endpoint name\n");
2653 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
2654 SCOPE_EXIT_RTN_VALUE(-1,
"Empty endpoint name\n");
2663 endpoint_name = strchr(args.endpoint,
'@');
2664 if (!endpoint_name) {
2669 ast_log(LOG_ERROR,
"Unable to create PJSIP channel - endpoint '%s' was not found\n",
2671 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
2672 SCOPE_EXIT_RTN_VALUE(-1,
"Endpoint not found\n");
2674 request_user = args.endpoint;
2675 *endpoint_name++ =
'\0';
2677 if (ast_strlen_zero(endpoint_name)) {
2678 ast_log(LOG_ERROR,
"Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2680 req_data->cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
2681 SCOPE_EXIT_RTN_VALUE(-1,
"Empty endpoint name\n");
2687 ast_log(LOG_ERROR,
"Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2688 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
2689 SCOPE_EXIT_RTN_VALUE(-1,
"Endpoint not found\n");
2694 session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user,
2695 req_data->topology);
2698 ast_log(LOG_ERROR,
"Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
2699 req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
2700 SCOPE_EXIT_RTN_VALUE(-1,
"Couldn't create session\n");
2703 req_data->session = session;
2705 SCOPE_EXIT_RTN_VALUE(0);
2713 SCOPE_ENTER(1,
"%s Topology: %s\n", data,
2716 req_data.topology = topology;
2717 req_data.dest = data;
2719 req_data.cause = AST_CAUSE_FAILURE;
2722 *cause = req_data.cause;
2723 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't push task\n");
2726 session = req_data.session;
2730 SCOPE_EXIT_RTN_VALUE(NULL,
"Couldn't create channel\n");
2733 SCOPE_EXIT_RTN_VALUE(session->
channel,
"Channel: %s\n", ast_channel_name(session->
channel));
2758 static void sendtext_data_destroy(
void *obj)
2761 ao2_cleanup(data->session);
2762 ast_free(data->msg);
2769 struct sendtext_data *data = ao2_alloc(
sizeof(*data), sendtext_data_destroy);
2780 data->session = channel->
session;
2786 static int sendtext(
void *obj)
2789 pjsip_tx_data *tdata;
2799 if (!ast_strlen_zero(content_type)) {
2800 sep = strchr(content_type,
'/');
2803 body.
type = content_type;
2808 if (data->session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2809 ast_log(LOG_ERROR,
"Session already DISCONNECTED [reason=%d (%s)]\n",
2811 pjsip_get_status_text(data->session->
inv_session->cause)->ptr);
2813 pjsip_from_hdr *hdr;
2814 pjsip_name_addr *name_addr;
2817 int invalidate_tdata = 0;
2819 ast_sip_create_request(
"MESSAGE", data->session->
inv_session->dlg, data->session->
endpoint, NULL, NULL, &tdata);
2820 ast_sip_add_body(tdata, &body);
2826 if (!ast_strlen_zero(from)) {
2827 hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
2828 name_addr = (pjsip_name_addr *) hdr->uri;
2829 pj_strdup2(tdata->pool, &name_addr->display, from);
2830 invalidate_tdata = 1;
2837 if (!ast_strlen_zero(to)) {
2838 hdr = PJSIP_MSG_TO_HDR(tdata->msg);
2839 name_addr = (pjsip_name_addr *) hdr->uri;
2840 pj_strdup2(tdata->pool, &name_addr->display, to);
2841 invalidate_tdata = 1;
2844 if (invalidate_tdata) {
2845 pjsip_tx_data_invalidate_msg(tdata);
2848 ast_sip_send_request(tdata, data->session->
inv_session->dlg, data->session->
endpoint, NULL, NULL);
2860 struct sendtext_data *data = sendtext_data_create(ast, msg);
2862 ast_debug(1,
"Sending MESSAGE from '%s' to '%s:%s': %s\n",
2865 ast_channel_name(ast),
2879 static int chan_pjsip_sendtext(
struct ast_channel *ast,
const char *text)
2886 .type = AST_MSG_DATA_ATTR_BODY,
2887 .value = (
char *)text,
2904 SCOPE_ENTER(1,
"%s\n", ast_sip_session_get_name(session));
2907 AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
2908 SCOPE_EXIT_RTN(
"Direct media no glare mitigation\n");
2911 datastore = ast_sip_session_alloc_datastore(&direct_media_mitigation_info,
2912 "direct_media_glare_mitigation");
2915 SCOPE_EXIT_RTN(
"Couldn't create datastore\n");
2918 ast_sip_session_add_datastore(session, datastore);
2925 SCOPE_ENTER(1,
"%s\n", ast_sip_session_get_name(session));
2928 SCOPE_EXIT_RTN(
"No channel\n");
2945 int cause = ast_sip_hangup_sip2cause(session->
inv_session->cause);
2957 const pj_str_t *host = ast_sip_pjsip_uri_get_hostname(session->
request_uri);
2958 size_t size = pj_strlen(host) + 1;
2961 ast_copy_pj_str(domain, host, size);
2972 pjsip_tx_data *packet = NULL;
2973 SCOPE_ENTER(3,
"%s\n", ast_sip_session_get_name(session));
2976 SCOPE_EXIT_RTN_VALUE(0,
"%s: No channel\n", ast_sip_session_get_name(session));
2980 if (rdata->msg_info.to->tag.slen) {
2991 ast_sip_session_terminate(session, 400);
2992 SCOPE_EXIT_RTN_VALUE(-1,
"%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
2995 datastore = ast_sip_session_alloc_datastore(&transport_info,
"transport_info");
2997 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
"%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
3000 transport_data =
ast_calloc(1,
sizeof(*transport_data));
3001 if (!transport_data) {
3002 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
"%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3004 pj_sockaddr_cp(&transport_data->
local_addr, &rdata->tp_info.transport->local_addr);
3005 pj_sockaddr_cp(&transport_data->
remote_addr, &rdata->pkt_info.src_addr);
3006 datastore->data = transport_data;
3007 ast_sip_session_add_datastore(session, datastore);
3010 if (pjsip_inv_end_session(session->
inv_session, 503, NULL, &packet) == PJ_SUCCESS
3012 ast_sip_session_send_response(session, packet);
3015 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
"%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3016 ast_sip_session_get_name(session));
3019 set_sipdomain_variable(session);
3023 SCOPE_EXIT_RTN_VALUE(0,
"%s\n", ast_sip_session_get_name(session));
3026 static int call_pickup_incoming_request(
struct ast_sip_session *session, pjsip_rx_data *rdata)
3032 if (rdata->msg_info.to->tag.slen) {
3037 pickup_cfg = ast_get_chan_features_pickup_config(session->
channel);
3039 ast_log(LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3055 ast_channel_hangupcause_set(chan, AST_CAUSE_CALL_REJECTED);
3057 ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
3072 .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
3073 .incoming_request = call_pickup_incoming_request,
3076 static int pbx_start_incoming_request(
struct ast_sip_session *session, pjsip_rx_data *rdata)
3079 SCOPE_ENTER(1,
"%s\n", ast_sip_session_get_name(session));
3082 if (rdata->msg_info.to->tag.slen) {
3084 SCOPE_EXIT_RTN_VALUE(0,
"Reinvite\n");
3090 case AST_PBX_FAILED:
3091 ast_log(LOG_WARNING,
"Failed to start PBX ;(\n");
3092 ast_channel_hangupcause_set(session->
channel, AST_CAUSE_SWITCH_CONGESTION);
3095 case AST_PBX_CALL_LIMIT:
3096 ast_log(LOG_WARNING,
"Failed to start PBX (call limit reached) \n");
3097 ast_channel_hangupcause_set(session->
channel, AST_CAUSE_SWITCH_CONGESTION);
3100 case AST_PBX_SUCCESS:
3105 ast_debug(3,
"Started PBX on new PJSIP channel %s\n", ast_channel_name(session->
channel));
3107 SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1,
"RC: %d\n", res);
3112 .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST,
3113 .incoming_request = pbx_start_incoming_request,
3119 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3121 int data_size =
sizeof(*cause_code);
3122 SCOPE_ENTER(3,
"%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3125 SCOPE_EXIT_RTN(
"%s: No channel\n", ast_sip_session_get_name(session));
3130 data_size += 4 + 4 + pj_strlen(&status.reason);
3132 memset(cause_code, 0, data_size);
3136 snprintf(cause_code->
code, data_size -
sizeof(*cause_code) + 1,
"SIP %d %.*s", status.code,
3137 (
int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3139 cause_code->
ast_cause = ast_sip_hangup_sip2cause(status.code);
3143 SCOPE_EXIT_RTN(
"%s\n", ast_sip_session_get_name(session));
3149 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3150 SCOPE_ENTER(3,
"%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3153 SCOPE_EXIT_RTN(
"%s: No channel\n", ast_sip_session_get_name(session));
3156 switch (status.code) {
3158 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3159 if (sdp && sdp->body.ptr) {
3160 ast_trace(-1,
"%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3161 session->
early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3164 ast_trace(-1,
"%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3168 ast_channel_lock(session->
channel);
3172 ast_channel_unlock(session->
channel);
3177 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3178 if (sdp && sdp->body.ptr) {
3179 ast_trace(-1,
"%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3180 ast_trace(1,
"%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3181 (
int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3182 session->
early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3186 ast_trace(-1,
"%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3187 ast_trace(1,
"%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3188 (
int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3193 ast_trace(-1,
"%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3197 ast_trace(-1,
"%s: Not queueing anything\n", ast_sip_session_get_name(session));
3201 SCOPE_EXIT_RTN(
"%s\n", ast_sip_session_get_name(session));
3204 static int chan_pjsip_incoming_ack(
struct ast_sip_session *session,
struct pjsip_rx_data *rdata)
3206 SCOPE_ENTER(3,
"%s\n", ast_sip_session_get_name(session));
3208 if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3210 ast_trace(-1,
"%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3214 SCOPE_EXIT_RTN_VALUE(0,
"%s\n", ast_sip_session_get_name(session));
3217 static int chan_pjsip_incoming_prack(
struct ast_sip_session *session,
struct pjsip_rx_data *rdata)
3219 SCOPE_ENTER(3,
"%s\n", ast_sip_session_get_name(session));
3221 if (pj_strcmp2(&rdata->msg_info.msg->line.req.method.name,
"PRACK") == 0 &&
3222 pjmedia_sdp_neg_get_state(session->
inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE) {
3226 SCOPE_EXIT_RTN_VALUE(0,
"%s\n", ast_sip_session_get_name(session));
3229 static int update_devstate(
void *obj,
void *arg,
int flags)
3237 .
name =
"PJSIP_DIAL_CONTACTS",
3242 .
name =
"PJSIP_PARSE_URI",
3247 .
name =
"PJSIP_PARSE_URI_FROM",
3252 .
name =
"PJSIP_MEDIA_OFFER",
3258 .
name =
"PJSIP_DTMF_MODE",
3264 .
name =
"PJSIP_MOH_PASSTHROUGH",
3270 .
name =
"PJSIP_SEND_SESSION_REFRESH",
3274 static char *app_pjsip_hangup =
"PJSIPHangup";
3296 ast_rtp_glue_register(&chan_pjsip_rtp_glue);
3299 ast_log(LOG_ERROR,
"Unable to register channel class %s\n", channel_type);
3304 ast_log(LOG_ERROR,
"Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3309 ast_log(LOG_ERROR,
"Unable to register PJSIP_PARSE_URI dialplan function\n");
3314 ast_log(LOG_ERROR,
"Unable to register PJSIP_PARSE_URI_FROM dialplan function\n");
3319 ast_log(LOG_WARNING,
"Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3324 ast_log(LOG_WARNING,
"Unable to register PJSIP_DTMF_MODE dialplan function\n");
3329 ast_log(LOG_WARNING,
"Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3334 ast_log(LOG_WARNING,
"Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3339 ast_log(LOG_WARNING,
"Unable to register PJSIPHangup dialplan application\n");
3345 ast_sip_register_service(&refer_callback_module);
3347 ast_sip_session_register_supplement(&chan_pjsip_supplement);
3348 ast_sip_session_register_supplement(&chan_pjsip_supplement_response);
3353 ast_log(LOG_ERROR,
"Unable to create held channels container\n");
3357 ast_sip_session_register_supplement(&call_pickup_supplement);
3358 ast_sip_session_register_supplement(&pbx_start_supplement);
3359 ast_sip_session_register_supplement(&chan_pjsip_ack_supplement);
3360 ast_sip_session_register_supplement(&chan_pjsip_prack_supplement);
3363 ast_log(LOG_ERROR,
"Unable to register PJSIP Channel CLI\n");
3369 if ((endpoints = ast_sip_get_endpoints())) {
3377 ao2_cleanup(pjsip_uids_onhold);
3378 pjsip_uids_onhold = NULL;
3379 ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement);
3380 ast_sip_session_unregister_supplement(&chan_pjsip_prack_supplement);
3381 ast_sip_session_unregister_supplement(&pbx_start_supplement);
3382 ast_sip_session_unregister_supplement(&chan_pjsip_supplement_response);
3383 ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
3384 ast_sip_session_unregister_supplement(&call_pickup_supplement);
3385 ast_sip_unregister_service(&refer_callback_module);
3405 ao2_cleanup(pjsip_uids_onhold);
3406 pjsip_uids_onhold = NULL;
3410 ast_sip_session_unregister_supplement(&chan_pjsip_supplement_response);
3411 ast_sip_session_unregister_supplement(&chan_pjsip_supplement);
3412 ast_sip_session_unregister_supplement(&pbx_start_supplement);
3413 ast_sip_session_unregister_supplement(&chan_pjsip_ack_supplement);
3414 ast_sip_session_unregister_supplement(&chan_pjsip_prack_supplement);
3415 ast_sip_session_unregister_supplement(&call_pickup_supplement);
3417 ast_sip_unregister_service(&refer_callback_module);
3436 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"PJSIP Channel Driver",
3437 .support_level = AST_MODULE_SUPPORT_CORE,
3441 .requires =
"res_pjsip,res_pjsip_session,res_pjsip_pubsub",
static int remote_send_hold(void *data)
Update local hold state to be held.
struct ast_sip_endpoint_pickup_configuration pickup
struct ast_variable * next
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.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Information needed to identify an endpoint in a call.
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.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
enum ast_sip_session_t38state t38state
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
pj_sockaddr local_addr
Our address that received the request.
ast_device_state
Device States.
static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Function called to query options on a channel.
char * str
Subscriber phone number (Malloced)
struct ast_channel_snapshot_base * base
Asterisk locking-related definitions:
Channels have this property if they implement send_text_data.
Asterisk main include file. File version handling, generic pbx functions.
PJSIP dialplan functions header file.
char * str
Subscriber phone number (Malloced)
char chan_name[AST_CHANNEL_NAME]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
static int is_compatible_format(struct ast_sip_session *session, struct ast_frame *f)
Determine if the given frame is in a format we've negotiated.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
struct ast_sip_session_media_state * pending_media_state
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
struct ast_msg_data * ast_msg_data_dup(struct ast_msg_data *msg)
Clone an ast_msg_data structure.
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MOH_PASSTHROUGH function read callback.
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
#define ast_channel_unref(c)
Decrease channel reference count.
The arg parameter is a search key, but is not an object.
Support for translation of data formats. translate.c.
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
unsigned int defer_terminate
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Convenient Signal Processing routines.
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.
const char * ast_endpoint_get_tech(const struct ast_endpoint *endpoint)
Gets the technology of the given endpoint.
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)
Function called to create a new PJSIP Asterisk channel.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct ast_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
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 int unload_module(void)
Unload the PJSIP channel from Asterisk.
static int chan_pjsip_add_hold(const char *chan_uid)
Add a channel ID to the list of PJSIP channels on hold.
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
unsigned int ignore_183_without_sdp
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Structure for variables, used for configurations and for channel variables.
Structure representing a snapshot of channel state.
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
unsigned int asymmetric_rtp_codec
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
const ast_string_field context
enum ast_control_t38 request_response
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)
Asterisk core interaction functions.
Structure to pass both assignedid values to channel drivers.
Structure for a data store type.
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
Structure used to transport a message through the frame core.
ast_channel_state
ast_channel states
char * str
Subscriber name (Malloced)
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
static struct ast_datastore_info transport_info
Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel...
ast_t38_state
Possible T38 states on channels.
static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit)
Function called by core to start a DTMF digit.
const ast_string_field uniqueid
static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_sip_session_media *media, struct ast_sip_session *session)
struct ast_stream_topology * ast_stream_topology_create_from_format_cap(struct ast_format_cap *cap)
A helper function that, given a format capabilities structure, creates a topology and separates the m...
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
struct ast_msg_data * ast_msg_data_alloc(enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
Allocates an ast_msg_data structure.
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
unsigned int early_confirmed
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
char exten[AST_MAX_EXTENSION]
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definitions to aid in the use of thread local storage.
Out-of-call text message support.
struct pjsip_inv_session * inv_session
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Transport information stored in transport_info datastore.
int ast_unregister_application(const char *app)
Unregister an application.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
void ast_free_ptr(void *ptr)
free() wrapper
static int uid_hold_hash_fn(const void *obj, const int flags)
A structure describing a SIP session.
const char * ast_endpoint_get_resource(const struct ast_endpoint *endpoint)
Gets the resource name of the given endpoint.
static void chan_pjsip_session_end(struct ast_sip_session *session)
Function called when the session ends.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int pjsip_action_hangup(struct mansession *s, const struct message *m)
PJSIPHangup Manager Action.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_format_cap * direct_media_cap
struct ast_frame_subclass subclass
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
unsigned int inband_progress
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
static struct ast_frame * chan_pjsip_cng_tone_detected(struct ast_channel *ast, struct ast_sip_session *session, struct ast_frame *f)
Internal helper function called when CNG tone is detected.
static int update_connected_line_information(void *data)
Update connected line information.
int ast_set_read_format_path(struct ast_channel *chan, struct ast_format *raw_format, struct ast_format *core_format)
Set specific read path on channel.
struct ast_sip_session_media_state * active_media_state
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MOH_PASSTHROUGH function write callback.
struct ast_sip_endpoint_media_configuration media
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_party_id id
Caller party ID.
static int chan_pjsip_transfer(struct ast_channel *ast, const char *target)
Function called by core for Asterisk initiated transfer.
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_DTMF_MODE function write callback.
int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
CHANNEL function read callback.
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
Function called by core to send text on PJSIP session.
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
struct ast_namedgroups * named_pickupgroups
General Asterisk PBX channel definitions.
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
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_hangup(struct ast_channel *ast)
Function called by core to hang up a PJSIP session.
static int compatible_formats_exist(struct ast_stream_topology *top, struct ast_format_cap *cap)
Determine if a topology is compatible with format capabilities.
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
A set of tones for a given locale.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int pjsip_acf_dial_contacts_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DIAL_CONTACTS function read callback.
const ast_string_field language
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Data structure associated with a custom dialplan function.
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
void pjsip_channel_cli_unregister(void)
Unregisters the channel cli commands.
static void chan_pjsip_session_begin(struct ast_sip_session *session)
SIP session interaction functions.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
const ast_string_field accountcode
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame's subclass into the provided string.
unsigned int rpid_immediate
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
struct ast_channel * channel
struct ast_namedgroups * named_callgroups
#define ast_malloc(len)
A wrapper for malloc()
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
#define ast_debug(level,...)
Log a DEBUG message.
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling...
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
An entity with which Asterisk communicates.
int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MEDIA_OFFER function write callback.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
enum ast_sip_session_refresh_method refresh_method
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
unsigned int trust_outbound
unsigned int send_connected_line
A snapshot of an endpoint's state.
struct ast_taskprocessor * serializer
const ast_string_field zone
#define ast_test_suite_event_notify(s, f,...)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
struct ast_sip_endpoint_id_configuration id
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Function called by core to stop a DTMF digit.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int pjsip_acf_parse_uri_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
PJSIP_PARSE_URI function read callback.
pj_sockaddr remote_addr
The address that sent the request.
int pjsip_acf_session_refresh_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_SEND_SESSION_REFRESH function write callback.
static void transport_info_destroy(void *obj)
Destructor function for transport_info_data.
static int chan_pjsip_get_hold(const char *chan_uid)
Determine whether a channel ID is in the list of PJSIP channels on hold.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Support for dynamic strings.
static int chan_pjsip_devicestate(const char *data)
Function called to get the device state of an endpoint.
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
static int chan_pjsip_answer(struct ast_channel *ast)
Function called by core when we should answer a PJSIP session.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
static struct ast_channel * chan_pjsip_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, 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.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
Callback function to report status of implicit REFER-NOTIFY subscription.
int ani2
Automatic Number Identification 2 (Info Digits)
enum ast_sip_dtmf_mode dtmf
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Connected Line/Party information.
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
unsigned int faxdetect_timeout
struct ast_format_cap * capabilities
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
int ast_set_write_format_path(struct ast_channel *chan, struct ast_format *core_format, struct ast_format *raw_format)
Set specific write path on channel.
static struct stasis_rest_handlers endpoints
REST handler for /api-docs/endpoints.json.
static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Function called by core to change the underlying owner channel.
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
union ast_frame::@224 data
PJSIP Channel Driver shared data structures.
#define ast_calloc(num, len)
A wrapper for calloc()
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
static void chan_pjsip_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
Function called by RTP engine to get peer capabilities.
Module has failed to load, may be in an inconsistent state.
enum ast_channel_state state
An API for managing task processing threads that can be shared across modules.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
static struct ast_frame * chan_pjsip_read_stream(struct ast_channel *ast)
Function called by core to read any waiting frames.
A supplement to SIP message processing.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
int pjsip_acf_dtmf_mode_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_DTMF_MODE function read callback.
struct ast_frame ast_null_frame
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
struct ast_endpoint * persistent
The arg parameter is an object of the same type.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
#define ast_channel_ref(c)
Increase channel reference count.
static int load_module(void)
Load the module.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
struct ast_party_dialed::@206 number
Dialed/Called number.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
Set standard statistics from an RTP instance on a channel.
int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length)
Get a device name given its channel structure.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
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.
#define AST_RTP_RTCP_PSFB
int pjsip_app_hangup(struct ast_channel *chan, const char *data)
PJSIPHangup Dialplan App.
You shouldn't care about the contents of this struct.
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 void chan_pjsip_incoming_response_update_cause(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Function called when a response is received on the session.
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Reject objects with duplicate keys in container.
enum ast_frame_type frametype
Channels have this property if they can create jitter; i.e. most VoIP channels.
unsigned char valid
TRUE if the name information is valid/present.
Search option field mask.
struct ast_variable * channel_vars
struct ast_format * format
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
const ast_string_field aors
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
#define ASTERISK_GPL_KEY
The text the key() function should return.
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Pluggable RTP Architecture.
Asterisk module definitions.
int pjsip_acf_media_offer_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
PJSIP_MEDIA_OFFER function read callback.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static int rtp_find_rtcp_fd_position(struct ast_sip_session *session, struct ast_rtp_instance *rtp)
Helper function to find the position for RTCP.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
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. ...
unsigned char valid
TRUE if the number information is valid/present.
#define ast_rtp_instance_get_and_cmp_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to, comparing its address to another...
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
#define ast_custom_function_register(acf)
Register a custom function.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
char exten[AST_MAX_EXTENSION]
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
PJSIP CLI functions header file.
static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
unsigned int moh_passthrough
const ast_string_field pickupexten
Configuration relating to call pickup.
#define AST_APP_ARG(name)
Define an application argument.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
struct ast_party_number number
Subscriber phone number.
#define ao2_link(container, obj)
Add an object to a container.