Asterisk - The Open Source Telephony Project GIT-master-57e2743
Loading...
Searching...
No Matches
chan_pjsip.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Joshua Colp <jcolp@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \author Joshua Colp <jcolp@digium.com>
22 *
23 * \brief PSJIP SIP Channel Driver
24 *
25 * \ingroup channel_drivers
26 */
27
28/*** MODULEINFO
29 <depend>pjproject</depend>
30 <depend>res_pjsip</depend>
31 <depend>res_pjsip_pubsub</depend>
32 <depend>res_pjsip_session</depend>
33 <support_level>core</support_level>
34 ***/
35
36#include "asterisk.h"
37
38#include <pjsip.h>
39#include <pjsip_ua.h>
40#include <pjlib.h>
41
42#include "asterisk/lock.h"
43#include "asterisk/channel.h"
44#include "asterisk/module.h"
45#include "asterisk/pbx.h"
46#include "asterisk/rtp_engine.h"
47#include "asterisk/acl.h"
48#include "asterisk/callerid.h"
49#include "asterisk/file.h"
50#include "asterisk/cli.h"
51#include "asterisk/app.h"
53#include "asterisk/causes.h"
55#include "asterisk/dsp.h"
60#include "asterisk/translate.h"
63#include "asterisk/pickup.h"
64#include "asterisk/test.h"
65#include "asterisk/message.h"
66
67#include "asterisk/res_pjsip.h"
69#include "asterisk/stream.h"
70
75
76AST_THREADSTORAGE(uniqueid_threadbuf);
77#define UNIQUEID_BUFSIZE 256
78
79static const char channel_type[] = "PJSIP";
80
81static unsigned int chan_idx;
82
83static void chan_pjsip_pvt_dtor(void *obj)
84{
85}
86
87/*! \brief Asterisk core interaction functions */
88static 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);
90 struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids,
91 const struct ast_channel *requestor, const char *data, int *cause);
92static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg);
93static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text);
94static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit);
95static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
96static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeout);
97static int chan_pjsip_hangup(struct ast_channel *ast);
98static int chan_pjsip_answer(struct ast_channel *ast);
99static struct ast_frame *chan_pjsip_read_stream(struct ast_channel *ast);
100static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *f);
101static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f);
102static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
103static int chan_pjsip_transfer(struct ast_channel *ast, const char *target);
104static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
105static int chan_pjsip_devicestate(const char *data);
106static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
107static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast);
108
109/*! \brief PBX interface structure for channel registration */
112 .description = "PJSIP Channel Driver",
113 .requester = chan_pjsip_request,
114 .requester_with_stream_topology = chan_pjsip_request_with_stream_topology,
115 .send_text = chan_pjsip_sendtext,
116 .send_text_data = chan_pjsip_sendtext_data,
117 .send_digit_begin = chan_pjsip_digit_begin,
118 .send_digit_end = chan_pjsip_digit_end,
119 .call = chan_pjsip_call,
120 .hangup = chan_pjsip_hangup,
121 .answer = chan_pjsip_answer,
122 .read_stream = chan_pjsip_read_stream,
123 .write = chan_pjsip_write,
124 .write_stream = chan_pjsip_write_stream,
125 .exception = chan_pjsip_read_stream,
126 .indicate = chan_pjsip_indicate,
127 .transfer = chan_pjsip_transfer,
128 .fixup = chan_pjsip_fixup,
129 .devicestate = chan_pjsip_devicestate,
130 .queryoption = chan_pjsip_queryoption,
131 .func_channel_read = pjsip_acf_channel_read,
132 .get_pvt_uniqueid = chan_pjsip_get_uniqueid,
134};
135
136/*! \brief SIP session interaction functions */
139static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
140static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
141static void chan_pjsip_incoming_response_update_cause(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
142
143/*! \brief SIP session supplement structure */
145 .method = "INVITE",
147 .session_begin = chan_pjsip_session_begin,
148 .session_end = chan_pjsip_session_end,
149 .incoming_request = chan_pjsip_incoming_request,
150 .incoming_response = chan_pjsip_incoming_response,
151 /* It is important that this supplement runs after media has been negotiated */
152 .response_priority = AST_SIP_SESSION_AFTER_MEDIA,
153};
154
155/*! \brief SIP session supplement structure just for responses */
162
163static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
164
166 .method = "ACK",
168 .incoming_request = chan_pjsip_incoming_ack,
169};
170
171static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
172
174 .method = "PRACK",
176 .incoming_request = chan_pjsip_incoming_prack,
177};
178
179/*! \brief Function called by RTP engine to get local audio RTP peer */
181{
182 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
183 struct ast_sip_endpoint *endpoint;
184 struct ast_datastore *datastore;
185 struct ast_sip_session_media *media;
186
187 if (!channel || !channel->session) {
189 }
190
191 /* XXX Getting the first RTP instance for direct media related stuff seems just
192 * absolutely wrong. But the native RTP bridge knows no other method than single-stream
193 * for direct media. So this is the best we can do.
194 */
196 if (!media || !media->rtp) {
198 }
199
200 datastore = ast_sip_session_get_datastore(channel->session, "t38");
201 if (datastore) {
202 ao2_ref(datastore, -1);
204 }
205
206 endpoint = channel->session->endpoint;
207
208 *instance = media->rtp;
209 ao2_ref(*instance, +1);
210
211 ast_assert(endpoint != NULL);
214 }
215
216 if (endpoint->media.direct_media.enabled) {
218 }
219
221}
222
223/*! \brief Function called by RTP engine to get local video RTP peer */
225{
226 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
227 struct ast_sip_endpoint *endpoint;
228 struct ast_sip_session_media *media;
229
230 if (!channel || !channel->session) {
232 }
233
235 if (!media || !media->rtp) {
237 }
238
239 endpoint = channel->session->endpoint;
240
241 *instance = media->rtp;
242 ao2_ref(*instance, +1);
243
244 ast_assert(endpoint != NULL);
247 }
248
250}
251
252/*! \brief Function called by RTP engine to get peer capabilities */
260
261/*! \brief Destructor function for \ref transport_info_data */
262static void transport_info_destroy(void *obj)
263{
264 struct transport_info_data *data = obj;
265 ast_free(data);
266}
267
268/*! \brief Datastore used to store local/remote addresses for the
269 * INVITE request that created the PJSIP channel */
271 .type = "chan_pjsip_transport_info",
272 .destroy = transport_info_destroy,
273};
274
275
276/*!
277 * \brief Determine the local signaling address used for an outgoing request.
278 *
279 * For unreliable transports, the transport local address may be a wildcard
280 * address. Ask the PJSIP transport manager for the local interface selected
281 * for the request destination, then fall back to the transport local address
282 * if needed.
283 */
284static int set_transport_info_local_addr(struct pjsip_tx_data *tdata, pj_sockaddr *local_addr)
285{
286 if (!(tdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
287 pjsip_tpmgr_fla2_param prm;
288
289 pjsip_tpmgr_fla2_param_default(&prm);
290 prm.tp_type = tdata->tp_info.transport->key.type;
291 pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
292 prm.local_if = PJ_TRUE;
293
294 if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()),
295 tdata->pool, &prm) == PJ_SUCCESS) {
296 int af = prm.tp_type & PJSIP_TRANSPORT_IPV6 ? pj_AF_INET6() : pj_AF_INET();
297
298 if (prm.tp_type == PJSIP_TRANSPORT_UDP || prm.tp_type == PJSIP_TRANSPORT_UDP6) {
299 prm.ret_port = tdata->tp_info.transport->local_name.port;
300 }
301
302 if (pj_sockaddr_init(af, local_addr, &prm.ret_addr, prm.ret_port) == PJ_SUCCESS) {
303 return 0;
304 }
305 }
306 }
307
308 pj_sockaddr_cp(local_addr, &tdata->tp_info.transport->local_addr);
309 return pj_sockaddr_has_addr(local_addr) ? 0 : -1;
310}
311
312/*!
313 * \brief Store transport information for outgoing PJSIP session requests.
314 *
315 * Incoming PJSIP channels get their transport information from the received
316 * request. Outgoing channels may not have this information available through
317 * the channel datastore, so store the selected transport addresses once the
318 * outgoing request has been created and a destination is known.
319 */
320static pj_status_t transport_info_on_tx_request(pjsip_tx_data *tdata)
321{
323 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
324 struct transport_info_data *transport_data;
325 pjsip_dialog *dlg;
326
327 if (!tdata->tp_info.transport
328 || !pj_sockaddr_has_addr(&tdata->tp_info.dst_addr)) {
329 return PJ_SUCCESS;
330 }
331
332 dlg = pjsip_tdata_get_dlg(tdata);
333 if (!dlg) {
334 return PJ_SUCCESS;
335 }
336
338 if (!session
339 || !session->inv_session
340 || session->inv_session->role != PJSIP_ROLE_UAC) {
341 return PJ_SUCCESS;
342 }
343
344 datastore = ast_sip_session_get_datastore(session, "transport_info");
345 if (datastore) {
346 return PJ_SUCCESS;
347 }
348
349 datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
350 if (!datastore) {
351 return PJ_SUCCESS;
352 }
353
354 transport_data = ast_calloc(1, sizeof(*transport_data));
355 if (!transport_data) {
356 return PJ_SUCCESS;
357 }
358
359 if (set_transport_info_local_addr(tdata, &transport_data->local_addr)) {
360 ast_free(transport_data);
361 return PJ_SUCCESS;
362 }
363 pj_sockaddr_cp(&transport_data->remote_addr, &tdata->tp_info.dst_addr);
364
365 datastore->data = transport_data;
367
368 return PJ_SUCCESS;
369}
370
372
374{
375 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
376
377 if (session->endpoint->media.direct_media.glare_mitigation ==
379 return 0;
380 }
381
382 datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
383 if (!datastore) {
384 return 0;
385 }
386
387 /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
388 ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
389
390 if ((session->endpoint->media.direct_media.glare_mitigation ==
392 session->inv_session->role == PJSIP_ROLE_UAC) ||
393 (session->endpoint->media.direct_media.glare_mitigation ==
395 session->inv_session->role == PJSIP_ROLE_UAS)) {
396 return 1;
397 }
398
399 return 0;
400}
401
402/*! \brief Helper function to find the position for RTCP */
404{
405 int index;
406
407 for (index = 0; index < AST_VECTOR_SIZE(&session->active_media_state->read_callbacks); ++index) {
408 struct ast_sip_session_media_read_callback_state *callback_state =
409 AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, index);
410
411 if (callback_state->fd != ast_rtp_instance_fd(rtp, 1)) {
412 continue;
413 }
414
415 return index;
416 }
417
418 return -1;
419}
420
421/*!
422 * \pre chan is locked
423 */
424static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
425 struct ast_sip_session_media *media, struct ast_sip_session *session)
426{
427 int changed = 0, position = -1;
428
429 if (media->rtp) {
430 position = rtp_find_rtcp_fd_position(session, media->rtp);
431 }
432
433 if (rtp) {
435 if (media->rtp) {
436 if (position != -1) {
437 ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, -1);
438 }
440 }
441 } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
443 changed = 1;
444 if (media->rtp) {
446 if (position != -1) {
447 ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1));
448 }
449 }
450 }
451
452 return changed;
453}
454
462
463static void rtp_direct_media_data_destroy(void *data)
464{
465 struct rtp_direct_media_data *cdata = data;
466
467 ao2_cleanup(cdata->session);
468 ao2_cleanup(cdata->cap);
469 ao2_cleanup(cdata->vrtp);
470 ao2_cleanup(cdata->rtp);
471 ao2_cleanup(cdata->chan);
472}
473
475 struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp,
476 const struct ast_format_cap *cap, struct ast_sip_session *session)
477{
479
480 if (!cdata) {
481 return NULL;
482 }
483
484 cdata->chan = ao2_bump(chan);
485 cdata->rtp = ao2_bump(rtp);
486 cdata->vrtp = ao2_bump(vrtp);
487 cdata->cap = ao2_bump((struct ast_format_cap *)cap);
488 cdata->session = ao2_bump(session);
489
490 return cdata;
491}
492
493static int send_direct_media_request(void *data)
494{
495 struct rtp_direct_media_data *cdata = data;
496 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(cdata->chan);
497 struct ast_sip_session *session;
498 int changed = 0;
499 int res = 0;
500
501 /* XXX In an ideal world each media stream would be direct, but for now preserve behavior
502 * and connect only the default media sessions for audio and video.
503 */
504
505 /* The channel needs to be locked when checking for RTP changes.
506 * Otherwise, we could end up destroying an underlying RTCP structure
507 * at the same time that the channel thread is attempting to read RTCP
508 */
509 ast_channel_lock(cdata->chan);
510 session = channel->session;
511 if (session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
512 changed |= check_for_rtp_changes(
513 cdata->chan, cdata->rtp, session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO], session);
514 }
515 if (session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO]) {
516 changed |= check_for_rtp_changes(
517 cdata->chan, cdata->vrtp, session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO], session);
518 }
521
522 if (direct_media_mitigate_glare(cdata->session)) {
523 ast_debug(4, "Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(cdata->chan));
524 ao2_ref(cdata, -1);
525 return 0;
526 }
527
528 if (cdata->cap && ast_format_cap_count(cdata->cap) &&
529 !ast_format_cap_identical(cdata->session->direct_media_cap, cdata->cap)) {
531 ast_format_cap_append_from_cap(cdata->session->direct_media_cap, cdata->cap, AST_MEDIA_TYPE_UNKNOWN);
532 changed = 1;
533 }
534
535 if (changed) {
536 ast_debug(4, "RTP changed on %s; initiating direct media update\n", ast_channel_name(cdata->chan));
537 res = ast_sip_session_refresh(cdata->session, NULL, NULL, NULL,
538 cdata->session->endpoint->media.direct_media.method, 1, NULL);
539 }
540
541 ao2_ref(cdata, -1);
542 return res;
543}
544
545/*! \brief Function called by RTP engine to change where the remote party should send media */
546static int chan_pjsip_set_rtp_peer(struct ast_channel *chan,
547 struct ast_rtp_instance *rtp,
548 struct ast_rtp_instance *vrtp,
549 struct ast_rtp_instance *tpeer,
550 const struct ast_format_cap *cap,
551 int nat_active)
552{
553 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
554 struct ast_sip_session *session = channel->session;
556 SCOPE_ENTER(1, "%s %s\n", ast_channel_name(chan),
558
559 /* Don't try to do any direct media shenanigans on early bridges */
560 if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
561 ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
562 SCOPE_EXIT_RTN_VALUE(0, "Channel not bridged\n");
563 }
564
565 if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
566 ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
567 SCOPE_EXIT_RTN_VALUE(0, "NAT is active\n");
568 }
569
571 if (!cdata) {
573 }
574
576 ast_log(LOG_ERROR, "Unable to send direct media request for channel %s\n", ast_channel_name(chan));
577 ao2_ref(cdata, -1);
578 }
579
581}
582
583/*! \brief Local glue for interacting with the RTP engine core */
585 .type = "PJSIP",
586 .get_rtp_info = chan_pjsip_get_rtp_peer,
587 .get_vrtp_info = chan_pjsip_get_vrtp_peer,
588 .get_codec = chan_pjsip_get_codec,
589 .update_peer = chan_pjsip_set_rtp_peer,
590};
591
593 const char *channel_id)
594{
595 int i;
596
597 for (i = 0; i < AST_VECTOR_SIZE(&session->active_media_state->sessions); ++i) {
598 struct ast_sip_session_media *session_media;
599
600 session_media = AST_VECTOR_GET(&session->active_media_state->sessions, i);
601 if (!session_media || !session_media->rtp) {
602 continue;
603 }
604
605 ast_rtp_instance_set_channel_id(session_media->rtp, channel_id);
606 }
607}
608
609/*!
610 * \brief Determine if a topology is compatible with format capabilities
611 *
612 * This will return true if ANY formats in the topology are compatible with the format
613 * capabilities.
614 *
615 * XXX When supporting true multistream, we will need to be sure to mark which streams from
616 * top1 are compatible with which streams from top2. Then the ones that are not compatible
617 * will need to be marked as "removed" so that they are negotiated as expected.
618 *
619 * \param top Topology
620 * \param cap Format capabilities
621 * \retval 1 The topology has at least one compatible format
622 * \retval 0 The topology has no compatible formats or an error occurred.
623 */
625{
626 struct ast_format_cap *cap_from_top;
627 int res;
628 SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
631
632 cap_from_top = ast_stream_topology_get_formats(top);
633
634 if (!cap_from_top) {
635 SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
636 }
637
638 res = ast_format_cap_iscompatible(cap_from_top, cap);
639 ao2_ref(cap_from_top, -1);
640
641 SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
642}
643
644/*! \brief Function called to create a new PJSIP Asterisk channel */
645static 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)
646{
647 struct ast_channel *chan;
648 struct ast_format_cap *caps;
649 RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
650 struct ast_sip_channel_pvt *channel;
651 struct ast_variable *var;
652 struct ast_stream_topology *topology;
653 struct ast_channel_initializers initializers = {
655 .tenantid = session->endpoint->tenantid,
656 };
658
660 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt\n");
661 }
662
664 S_COR(session->id.number.valid, session->id.number.str, ""),
665 S_COR(session->id.name.valid, session->id.name.str, ""),
666 session->endpoint->accountcode,
667 exten, session->endpoint->context,
668 assignedids, requestor, 0,
669 session->endpoint->persistent, &initializers, "PJSIP/%s-%08x",
671 (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
672 if (!chan) {
673 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
674 }
675
677
678 if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
679 ast_channel_unlock(chan);
680 ast_hangup(chan);
681 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt channel\n");
682 }
683
684 ast_channel_tech_pvt_set(chan, channel);
686 /* Keep technology hangup from accessing the not yet attached session. */
688 ao2_cleanup(channel);
689 ast_channel_unlock(chan);
690 ast_hangup(chan);
691 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create PJSIP channel state\n");
692 }
693
694 if (!ast_stream_topology_get_count(session->pending_media_state->topology) ||
695 !compatible_formats_exist(session->pending_media_state->topology, session->endpoint->media.codecs)) {
697 if (!caps) {
698 ast_channel_unlock(chan);
699 ast_hangup(chan);
700 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
701 }
702 ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
703 topology = ast_stream_topology_clone(session->endpoint->media.topology);
704 } else {
705 caps = ast_stream_topology_get_formats(session->pending_media_state->topology);
706 topology = ast_stream_topology_clone(session->pending_media_state->topology);
707 }
708
709 if (!topology || !caps) {
710 ao2_cleanup(caps);
711 ast_stream_topology_free(topology);
712 ast_channel_unlock(chan);
713 ast_hangup(chan);
714 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't get caps or clone topology\n");
715 }
716
718
720 ast_channel_set_stream_topology(chan, topology);
721
722 if (!ast_format_cap_empty(caps)) {
723 struct ast_format *fmt;
724
726 if (!fmt) {
727 /* Since our capabilities aren't empty, this will succeed */
728 fmt = ast_format_cap_get_format(caps, 0);
729 }
734 ao2_ref(fmt, -1);
735 }
736
737 ao2_ref(caps, -1);
738
739 if (state == AST_STATE_RING) {
740 ast_channel_rings_set(chan, 1);
741 }
742
744
747 ast_channel_caller(chan)->ani2 = session->ani2;
748
749 if (!ast_strlen_zero(exten)) {
750 /* Set provided DNID on the new channel. */
751 ast_channel_dialed(chan)->number.str = ast_strdup(exten);
752 }
753
755
756 ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
757 ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
758
759 ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
760 ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
761
762 if (!ast_strlen_zero(session->endpoint->language)) {
763 ast_channel_language_set(chan, session->endpoint->language);
764 }
765
766 if (!ast_strlen_zero(session->endpoint->zone)) {
767 struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
768 if (!zone) {
769 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
770 }
771 ast_channel_zone_set(chan, zone);
772 }
773
775 ast_channel_unlock(chan);
776
777 for (var = session->endpoint->channel_vars; var; var = var->next) {
778 char buf[512];
780 var->value, buf, sizeof(buf)));
781 }
782
784
786}
787
790 unsigned long indent;
791};
792
793static int answer(void *data)
794{
795 struct answer_data *ans_data = data;
796 pj_status_t status = PJ_SUCCESS;
797 pjsip_tx_data *packet = NULL;
798 struct ast_sip_session *session = ans_data->session;
800
801 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
802 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
803 session->inv_session->cause,
804 pjsip_get_status_text(session->inv_session->cause)->ptr);
805 SCOPE_EXIT_RTN_VALUE(0, "Disconnected\n");
806 }
807
808 pjsip_dlg_inc_lock(session->inv_session->dlg);
809 if (session->inv_session->invite_tsx) {
810 status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet);
811 } else {
812 ast_log(LOG_ERROR,"Cannot answer '%s' because there is no associated SIP transaction\n",
813 ast_channel_name(session->channel));
814 }
815 pjsip_dlg_dec_lock(session->inv_session->dlg);
816
817 if (status == PJ_SUCCESS && packet) {
819 }
820
821 if (status != PJ_SUCCESS) {
822 char err[PJ_ERR_MSG_SIZE];
823
824 pj_strerror(status, err, sizeof(err));
825 ast_log(LOG_WARNING,"Cannot answer '%s': %s\n",
826 ast_channel_name(session->channel), err);
827 /*
828 * Return this value so we can distinguish between this
829 * failure and the taskpool synchronous push failing.
830 */
831 SCOPE_EXIT_RTN_VALUE(-2, "pjproject failure\n");
832 }
834}
835
836/*! \brief Function called by core when we should answer a PJSIP session */
837static int chan_pjsip_answer(struct ast_channel *ast)
838{
839 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
840 struct ast_sip_session *session;
841 struct answer_data ans_data = { 0, };
842 int res;
843 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
844
845 if (ast_channel_state(ast) == AST_STATE_UP) {
846 SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
847 return 0;
848 }
849
851 session = ao2_bump(channel->session);
852
853 /* the answer task needs to be pushed synchronously otherwise a race condition
854 can occur between this thread and bridging (specifically when native bridging
855 attempts to do direct media) */
857 ans_data.session = session;
858 ans_data.indent = ast_trace_get_indent();
859 res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
860 if (res) {
861 if (res == -1) {
862 ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the taskpool.\n",
863 ast_channel_name(session->channel));
864 }
865 ao2_ref(session, -1);
866 ast_channel_lock(ast);
867 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
868 }
869 ao2_ref(session, -1);
870 ast_channel_lock(ast);
871
873}
874
875/*! \brief Internal helper function called when CNG tone is detected */
877 struct ast_frame *f)
878{
879 const char *target_context;
880 int exists;
881 int dsp_features;
882
883 dsp_features = ast_dsp_get_features(session->dsp);
884 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
885 if (dsp_features) {
886 ast_dsp_set_features(session->dsp, dsp_features);
887 } else {
888 ast_dsp_free(session->dsp);
889 session->dsp = NULL;
890 }
891
892 /* If already executing in the fax extension don't do anything */
893 if (!strcmp(ast_channel_exten(ast), "fax")) {
894 return f;
895 }
896
897 target_context = ast_channel_context(ast);
898
899 /*
900 * We need to unlock the channel here because ast_exists_extension has the
901 * potential to start and stop an autoservice on the channel. Such action
902 * is prone to deadlock if the channel is locked.
903 *
904 * ast_async_goto() has its own restriction on not holding the channel lock.
905 */
907 ast_frfree(f);
908 f = &ast_null_frame;
909 exists = ast_exists_extension(ast, target_context, "fax", 1,
910 S_COR(ast_channel_caller(ast)->id.number.valid,
911 ast_channel_caller(ast)->id.number.str, NULL));
912 if (exists) {
913 ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",
914 ast_channel_name(ast));
915 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
916 if (ast_async_goto(ast, target_context, "fax", 1)) {
917 ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",
918 ast_channel_name(ast), target_context);
919 }
920 } else {
921 ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",
922 ast_channel_name(ast), target_context);
923 }
924
925 /* It's possible for a masquerade to have occurred when doing the ast_async_goto resulting in
926 * the channel on the session having changed. Since we need to return with the original channel
927 * locked we lock the channel that was passed in and not session->channel.
928 */
929 ast_channel_lock(ast);
930
931 return f;
932}
933
934/*! \brief Determine if the given frame is in a format we've negotiated */
936{
937 struct ast_stream_topology *topology = session->active_media_state->topology;
938 struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
939 const struct ast_format_cap *cap = ast_stream_get_formats(stream);
940
942}
943
944/*!
945 * \brief Function called by core to read any waiting frames
946 *
947 * \note The channel is already locked.
948 */
950{
951 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
952 struct ast_sip_session *session = channel->session;
953 struct ast_sip_session_media_read_callback_state *callback_state;
954 struct ast_frame *f;
955 int fdno = ast_channel_fdno(ast) - AST_EXTENDED_FDS;
956 struct ast_frame *cur;
957
958 if (fdno >= AST_VECTOR_SIZE(&session->active_media_state->read_callbacks)) {
959 return &ast_null_frame;
960 }
961
962 callback_state = AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, fdno);
963 f = callback_state->read_callback(session, callback_state->session);
964
965 if (!f) {
966 return f;
967 }
968
969 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
970 if (cur->frametype == AST_FRAME_VOICE) {
971 break;
972 }
973 }
974
975 if (!cur || callback_state->session != session->active_media_state->default_session[callback_state->session->type]) {
976 return f;
977 }
978
979 session = channel->session;
980
981 /*
982 * Asymmetric RTP only has one native format set at a time.
983 * Therefore we need to update the native format to the current
984 * raw read format BEFORE the native format check
985 */
986 if (!session->endpoint->asymmetric_rtp_codec &&
989 struct ast_format_cap *caps;
990
991 /* For maximum compatibility we ensure that the formats match that of the received media */
992 ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
995
997 if (caps) {
1000 ast_format_cap_append(caps, cur->subclass.format, 0);
1002 ao2_ref(caps, -1);
1003 }
1004
1007
1008 if (ast_channel_is_bridged(ast)) {
1010 }
1011 }
1012
1015 ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
1017 ast_frfree(f);
1018 return &ast_null_frame;
1019 }
1020
1021 if (session->dsp) {
1022 int dsp_features;
1023
1024 dsp_features = ast_dsp_get_features(session->dsp);
1025 if ((dsp_features & DSP_FEATURE_FAX_DETECT)
1026 && session->endpoint->faxdetect_timeout
1027 && session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
1028 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
1029 if (dsp_features) {
1030 ast_dsp_set_features(session->dsp, dsp_features);
1031 } else {
1032 ast_dsp_free(session->dsp);
1033 session->dsp = NULL;
1034 }
1035 ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
1036 ast_channel_name(ast));
1037 }
1038 }
1039 if (session->dsp) {
1040 f = ast_dsp_process(ast, session->dsp, f);
1041 if (f && (f->frametype == AST_FRAME_DTMF)) {
1042 if (f->subclass.integer == 'f') {
1043 ast_debug(3, "Channel driver fax CNG detected on %s\n",
1044 ast_channel_name(ast));
1046 /* When chan_pjsip_cng_tone_detected returns it is possible for the
1047 * channel pointed to by ast and by session->channel to differ due to a
1048 * masquerade. It's best not to touch things after this.
1049 */
1050 } else {
1051 ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
1052 ast_channel_name(ast));
1053 }
1054 }
1055 }
1056
1057 return f;
1058}
1059
1060static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *frame)
1061{
1062 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1063 struct ast_sip_session *session = channel->session;
1064 struct ast_sip_session_media *media = NULL;
1065 int res = 0;
1066
1067 /* The core provides a guarantee that the stream will exist when we are called if stream_num is provided */
1068 if (stream_num >= 0) {
1069 /* What is not guaranteed is that a media session will exist */
1072 }
1073 }
1074
1075 switch (frame->frametype) {
1076 case AST_FRAME_VOICE:
1077 if (!media) {
1078 return 0;
1079 } else if (media->type != AST_MEDIA_TYPE_AUDIO) {
1080 ast_debug(3, "Channel %s stream %d is of type '%s', not audio!\n",
1082 return 0;
1083 } else if (media == channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO] &&
1086 struct ast_str *write_transpath = ast_str_alloca(256);
1087 struct ast_str *read_transpath = ast_str_alloca(256);
1088
1090 "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
1091 ast_channel_name(ast),
1096 ast_translate_path_to_str(ast_channel_readtrans(ast), &read_transpath),
1099 ast_translate_path_to_str(ast_channel_writetrans(ast), &write_transpath));
1100 return 0;
1101 } else if (media->write_callback) {
1102 res = media->write_callback(session, media, frame);
1103
1104 }
1105 break;
1106 case AST_FRAME_VIDEO:
1107 if (!media) {
1108 return 0;
1109 } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1110 ast_debug(3, "Channel %s stream %d is of type '%s', not video!\n",
1111 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1112 return 0;
1113 } else if (media->write_callback) {
1114 res = media->write_callback(session, media, frame);
1115 }
1116 break;
1117 case AST_FRAME_MODEM:
1118 if (!media) {
1119 return 0;
1120 } else if (media->type != AST_MEDIA_TYPE_IMAGE) {
1121 ast_debug(3, "Channel %s stream %d is of type '%s', not image!\n",
1122 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1123 return 0;
1124 } else if (media->write_callback) {
1125 res = media->write_callback(session, media, frame);
1126 }
1127 break;
1128 case AST_FRAME_CNG:
1129 break;
1130 case AST_FRAME_RTCP:
1131 /* We only support writing out feedback */
1132 if (frame->subclass.integer != AST_RTP_RTCP_PSFB || !media) {
1133 return 0;
1134 } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1135 ast_debug(3, "Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n",
1136 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1137 return 0;
1138 } else if (media->write_callback) {
1139 res = media->write_callback(session, media, frame);
1140 }
1141 break;
1142 default:
1143 ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
1144 break;
1145 }
1146
1147 return res;
1148}
1149
1150static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *frame)
1151{
1152 return chan_pjsip_write_stream(ast, -1, frame);
1153}
1154
1155/*! \brief Function called by core to change the underlying owner channel */
1156static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1157{
1158 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
1159
1160 if (channel->session->channel != oldchan) {
1161 return -1;
1162 }
1163
1164 /*
1165 * The masquerade has suspended the channel's session
1166 * serializer so we can safely change it outside of
1167 * the serializer thread.
1168 */
1169 channel->session->channel = newchan;
1170
1172
1173 return 0;
1174}
1175
1176/*! AO2 hash function for on hold UIDs */
1177static int uid_hold_hash_fn(const void *obj, const int flags)
1178{
1179 const char *key = obj;
1180
1181 switch (flags & OBJ_SEARCH_MASK) {
1182 case OBJ_SEARCH_KEY:
1183 break;
1184 case OBJ_SEARCH_OBJECT:
1185 break;
1186 default:
1187 /* Hash can only work on something with a full key. */
1188 ast_assert(0);
1189 return 0;
1190 }
1191 return ast_str_hash(key);
1192}
1193
1194/*! AO2 sort function for on hold UIDs */
1195static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
1196{
1197 const char *left = obj_left;
1198 const char *right = obj_right;
1199 int cmp;
1200
1201 switch (flags & OBJ_SEARCH_MASK) {
1202 case OBJ_SEARCH_OBJECT:
1203 case OBJ_SEARCH_KEY:
1204 cmp = strcmp(left, right);
1205 break;
1207 cmp = strncmp(left, right, strlen(right));
1208 break;
1209 default:
1210 /* Sort can only work on something with a full or partial key. */
1211 ast_assert(0);
1212 cmp = 0;
1213 break;
1214 }
1215 return cmp;
1216}
1217
1219
1220/*!
1221 * \brief Add a channel ID to the list of PJSIP channels on hold
1222 *
1223 * \param chan_uid - Unique ID of the channel being put into the hold list
1224 *
1225 * \retval 0 Channel has been added to or was already in the hold list
1226 * \retval -1 Failed to add channel to the hold list
1227 */
1228static int chan_pjsip_add_hold(const char *chan_uid)
1229{
1230 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1231
1232 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1233 if (hold_uid) {
1234 /* Device is already on hold. Nothing to do. */
1235 return 0;
1236 }
1237
1238 /* Device wasn't in hold list already. Create a new one. */
1239 hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1241 if (!hold_uid) {
1242 return -1;
1243 }
1244
1245 ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1246
1247 if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1248 return -1;
1249 }
1250
1251 return 0;
1252}
1253
1254/*!
1255 * \brief Remove a channel ID from the list of PJSIP channels on hold
1256 *
1257 * \param chan_uid - Unique ID of the channel being taken out of the hold list
1258 */
1259static void chan_pjsip_remove_hold(const char *chan_uid)
1260{
1262}
1263
1264/*!
1265 * \brief Determine whether a channel ID is in the list of PJSIP channels on hold
1266 *
1267 * \param chan_uid - Channel being checked
1268 *
1269 * \retval 0 The channel is not in the hold list
1270 * \retval 1 The channel is in the hold list
1271 */
1272static int chan_pjsip_get_hold(const char *chan_uid)
1273{
1274 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1275
1276 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1277 if (!hold_uid) {
1278 return 0;
1279 }
1280
1281 return 1;
1282}
1283
1284/*! \brief Function called to get the device state of an endpoint */
1285static int chan_pjsip_devicestate(const char *data)
1286{
1287 RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
1289 RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
1290 struct ast_devstate_aggregate aggregate;
1291 int num, inuse = 0;
1292
1293 if (!endpoint) {
1294 return AST_DEVICE_INVALID;
1295 }
1296
1297 endpoint_snapshot = ast_endpoint_get_snapshot(endpoint->persistent);
1298 if (!endpoint_snapshot) {
1299 return AST_DEVICE_INVALID;
1300 }
1301
1302 if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
1304 } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
1306 }
1307
1308 if (!endpoint_snapshot->num_channels) {
1309 return state;
1310 }
1311
1312 ast_devstate_aggregate_init(&aggregate);
1313
1314 for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1315 struct ast_channel_snapshot *snapshot;
1316
1317 snapshot = ast_channel_snapshot_get_latest(endpoint_snapshot->channel_ids[num]);
1318 if (!snapshot) {
1319 continue;
1320 }
1321
1322 if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
1324 } else {
1325 ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
1326 }
1327
1328 if (snapshot->state != AST_STATE_DOWN && snapshot->state != AST_STATE_RESERVED) {
1329 inuse++;
1330 }
1331
1332 ao2_ref(snapshot, -1);
1333 }
1334
1335 if (endpoint->devicestate_busy_at && (inuse >= endpoint->devicestate_busy_at)) {
1337 } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
1339 }
1340
1341 return state;
1342}
1343
1344/*! \brief Function called to query options on a channel */
1345static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1346{
1347 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1348 int res = -1;
1350
1351 if (!channel) {
1352 return -1;
1353 }
1354
1355 switch (option) {
1357 if (channel->session->endpoint->media.t38.enabled) {
1358 switch (channel->session->t38state) {
1359 case T38_LOCAL_REINVITE:
1360 case T38_PEER_REINVITE:
1362 break;
1363 case T38_ENABLED:
1365 break;
1366 case T38_REJECTED:
1368 break;
1369 default:
1371 break;
1372 }
1373 }
1374
1375 *((enum ast_t38_state *) data) = state;
1376 res = 0;
1377
1378 break;
1379 default:
1380 break;
1381 }
1382
1383 return res;
1384}
1385
1386static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast)
1387{
1388 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1389 char *uniqueid = ast_threadstorage_get(&uniqueid_threadbuf, UNIQUEID_BUFSIZE);
1390
1391 if (!channel || !uniqueid) {
1392 return "";
1393 }
1394
1395 ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1396
1397 return uniqueid;
1398}
1399
1407
1408static void indicate_data_destroy(void *obj)
1409{
1410 struct indicate_data *ind_data = obj;
1411
1412 ast_free(ind_data->frame_data);
1413 ao2_ref(ind_data->session, -1);
1414}
1415
1417 int condition, int response_code, const void *frame_data, size_t datalen)
1418{
1419 struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
1420
1421 if (!ind_data) {
1422 return NULL;
1423 }
1424
1425 ind_data->frame_data = ast_malloc(datalen);
1426 if (!ind_data->frame_data) {
1427 ao2_ref(ind_data, -1);
1428 return NULL;
1429 }
1430
1431 memcpy(ind_data->frame_data, frame_data, datalen);
1432 ind_data->datalen = datalen;
1433 ind_data->condition = condition;
1434 ind_data->response_code = response_code;
1435 ao2_ref(session, +1);
1436 ind_data->session = session;
1437
1438 return ind_data;
1439}
1440
1441static int indicate(void *data)
1442{
1443 pjsip_tx_data *packet = NULL;
1444 struct indicate_data *ind_data = data;
1445 struct ast_sip_session *session = ind_data->session;
1446 int response_code = ind_data->response_code;
1447
1448 if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1449 (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1451 }
1452
1453 ao2_ref(ind_data, -1);
1454
1455 return 0;
1456}
1457
1458/*! \brief Send SIP INFO with video update request */
1459static int transmit_info_with_vidupdate(void *data)
1460{
1461 const char * xml =
1462 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
1463 " <media_control>\r\n"
1464 " <vc_primitive>\r\n"
1465 " <to_encoder>\r\n"
1466 " <picture_fast_update/>\r\n"
1467 " </to_encoder>\r\n"
1468 " </vc_primitive>\r\n"
1469 " </media_control>\r\n";
1470
1471 const struct ast_sip_body body = {
1472 .type = "application",
1473 .subtype = "media_control+xml",
1474 .body_text = xml
1475 };
1476
1477 RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
1478 struct pjsip_tx_data *tdata;
1479
1480 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1481 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1482 session->inv_session->cause,
1483 pjsip_get_status_text(session->inv_session->cause)->ptr);
1484 return -1;
1485 }
1486
1487 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
1488 ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
1489 return -1;
1490 }
1491 if (ast_sip_add_body(tdata, &body)) {
1492 ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
1493 return -1;
1494 }
1496
1497 return 0;
1498}
1499
1500/*!
1501 * \internal
1502 * \brief TRUE if a COLP update can be sent to the peer.
1503 * \since 13.3.0
1504 *
1505 * \param session The session to see if the COLP update is allowed.
1506 *
1507 * \retval 0 Update is not allowed.
1508 * \retval 1 Update is allowed.
1509 */
1511{
1512 struct ast_party_id connected_id;
1513 int update_allowed = 0;
1514
1515 if (!session->endpoint->id.send_connected_line
1516 || (!session->endpoint->id.send_pai && !session->endpoint->id.send_rpid)) {
1517 return 0;
1518 }
1519
1520 /*
1521 * Check if privacy allows the update. Check while the channel
1522 * is locked so we can work with the shallow connected_id copy.
1523 */
1524 ast_channel_lock(session->channel);
1525 connected_id = ast_channel_connected_effective_id(session->channel);
1526 if (connected_id.number.valid
1527 && (session->endpoint->id.trust_outbound
1529 update_allowed = 1;
1530 }
1531 ast_channel_unlock(session->channel);
1532
1533 return update_allowed;
1534}
1535
1536/*! \brief Update connected line information */
1538{
1539 struct ast_sip_session *session = data;
1540
1541 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1542 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1543 session->inv_session->cause,
1544 pjsip_get_status_text(session->inv_session->cause)->ptr);
1545 ao2_ref(session, -1);
1546 return -1;
1547 }
1548
1549 if (ast_channel_state(session->channel) == AST_STATE_UP
1550 || session->inv_session->role == PJSIP_ROLE_UAC) {
1553 int generate_new_sdp;
1554
1555 method = session->endpoint->id.refresh_method;
1556 if (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE) {
1558 }
1559
1560 /* Only the INVITE method actually needs SDP, UPDATE can do without */
1561 generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
1562
1563 ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp, NULL);
1564 }
1565 } else if (session->endpoint->id.rpid_immediate
1566 && session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED
1568 int response_code = 0;
1569
1570 if (ast_channel_state(session->channel) == AST_STATE_RING) {
1571 response_code = !session->endpoint->inband_progress ? 180 : 183;
1572 } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {
1573 response_code = 183;
1574 }
1575
1576 if (response_code) {
1577 struct pjsip_tx_data *packet = NULL;
1578
1579 if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
1581 }
1582 }
1583 }
1584
1585 ao2_ref(session, -1);
1586 return 0;
1587}
1588
1589/*! \brief Update local hold state and send a re-INVITE with the new SDP */
1590static int remote_send_hold_refresh(struct ast_sip_session *session, unsigned int held)
1591{
1592 struct ast_sip_session_media *session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
1593 if (session_media) {
1594 session_media->locally_held = held;
1595 }
1597 ao2_ref(session, -1);
1598
1599 return 0;
1600}
1601
1602/*! \brief Update local hold state to be held */
1603static int remote_send_hold(void *data)
1604{
1605 return remote_send_hold_refresh(data, 1);
1606}
1607
1608/*! \brief Update local hold state to be unheld */
1609static int remote_send_unhold(void *data)
1610{
1611 return remote_send_hold_refresh(data, 0);
1612}
1613
1618
1626
1628 struct ast_sip_session *session, const struct ast_stream_topology *topology)
1629{
1631
1632 refresh_data = ast_calloc(1, sizeof(*refresh_data));
1633 if (!refresh_data) {
1634 return NULL;
1635 }
1636
1639 if (!refresh_data->media_state) {
1641 return NULL;
1642 }
1643 refresh_data->media_state->topology = ast_stream_topology_clone(topology);
1644 if (!refresh_data->media_state->topology) {
1646 return NULL;
1647 }
1648
1649 return refresh_data;
1650}
1651
1652static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
1653{
1654 SCOPE_ENTER(3, "%s: Received response code %d. PT: %s AT: %s\n", ast_sip_session_get_name(session),
1655 rdata->msg_info.msg->line.status.code,
1656 ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP)),
1657 ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP)));
1658
1659
1660 if (PJSIP_IS_STATUS_IN_CLASS(rdata->msg_info.msg->line.status.code, 200)) {
1661 /* The topology was changed to something new so give notice to what requested
1662 * it so it queries the channel and updates accordingly.
1663 */
1664 if (session->channel) {
1666 SCOPE_EXIT_RTN_VALUE(0, "%s: Queued topology change frame\n", ast_sip_session_get_name(session));
1667 }
1668 SCOPE_EXIT_RTN_VALUE(0, "%s: No channel? Can't queue topology change frame\n", ast_sip_session_get_name(session));
1669 } else if (300 <= rdata->msg_info.msg->line.status.code) {
1670 /* The topology change failed, so drop the current pending media state */
1671 ast_sip_session_media_state_reset(session->pending_media_state);
1672 SCOPE_EXIT_RTN_VALUE(0, "%s: response code > 300. Resetting pending media state\n", ast_sip_session_get_name(session));
1673 }
1674
1675 SCOPE_EXIT_RTN_VALUE(0, "%s: Nothing to do\n", ast_sip_session_get_name(session));
1676}
1677
1678static int send_topology_change_refresh(void *data)
1679{
1684 int ret;
1686 ast_str_tmp(256, ast_stream_topology_to_str(refresh_data->media_state->topology, &STR_TMP)));
1687
1688 /* See RFC 6337, especially section 3.2: If the early media SDP was sent reliably, we are allowed
1689 * to send UPDATEs. Only relevant for AST_STATE_RINGING and AST_STATE_RING - if the channel is UP,
1690 * re-INVITES can be sent.
1691 */
1692 if (session->early_confirmed && (state == AST_STATE_RINGING || state == AST_STATE_RING)) {
1694 }
1695
1697 method, 1, refresh_data->media_state);
1698 refresh_data->media_state = NULL;
1700
1702}
1703
1705 const struct ast_stream_topology *proposed)
1706{
1708 int res;
1709 SCOPE_ENTER(1);
1710
1712 if (!refresh_data) {
1713 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1714 }
1715
1717 if (res) {
1719 }
1720 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1721}
1722
1723/* Forward declarations */
1724static int transmit_info_dtmf(void *data);
1725static struct info_dtmf_data *info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration);
1726
1727/*! \brief Function called by core to ask the channel to indicate some sort of condition */
1728static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1729{
1730 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1731 struct ast_sip_session_media *media;
1732 int response_code = 0;
1733 int res = 0;
1734 char *device_buf;
1735 size_t device_buf_size;
1736 int i;
1737 const struct ast_stream_topology *topology;
1738 struct ast_frame f = {
1740 .subclass = {
1741 .integer = condition
1742 },
1743 .datalen = datalen,
1744 .data.ptr = (void *)data,
1745 };
1746 char condition_name[256];
1747 unsigned int duration;
1748 char digit;
1749 struct info_dtmf_data *dtmf_data;
1750
1751 SCOPE_ENTER(3, "%s: Indicated %s\n", ast_channel_name(ast),
1752 ast_frame_subclass2str(&f, condition_name, sizeof(condition_name), NULL, 0));
1753
1754 switch (condition) {
1756 if (ast_channel_state(ast) == AST_STATE_RING) {
1757 if (channel->session->endpoint->inband_progress ||
1758 (channel->session->inv_session && channel->session->inv_session->neg &&
1759 pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1760 res = -1;
1762 response_code = 180;
1763 } else {
1764 response_code = 183;
1765 }
1766 } else {
1767 response_code = 180;
1768 }
1769 } else {
1770 res = -1;
1771 }
1773 break;
1774 case AST_CONTROL_BUSY:
1775 if (ast_channel_state(ast) != AST_STATE_UP) {
1776 response_code = 486;
1777 } else {
1778 res = -1;
1779 }
1780 break;
1782 if (ast_channel_state(ast) != AST_STATE_UP) {
1783 response_code = 503;
1784 } else {
1785 res = -1;
1786 }
1787 break;
1789 if (ast_channel_state(ast) != AST_STATE_UP) {
1790 response_code = 484;
1791 } else {
1792 res = -1;
1793 }
1794 break;
1796 if (ast_channel_state(ast) != AST_STATE_UP) {
1797 response_code = 100;
1798 } else {
1799 res = -1;
1800 }
1801 break;
1803 if (ast_channel_state(ast) != AST_STATE_UP) {
1804 response_code = 183;
1805 } else {
1806 res = -1;
1807 }
1809 break;
1810 case AST_CONTROL_FLASH:
1811 duration = 300;
1812 digit = '!';
1813 dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
1814
1815 if (!dtmf_data) {
1816 res = -1;
1817 break;
1818 }
1819
1820 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
1821 ast_log(LOG_WARNING, "Error sending FLASH via INFO on channel %s\n", ast_channel_name(ast));
1822 ao2_ref(dtmf_data, -1); /* dtmf_data can't be null here */
1823 res = -1;
1824 }
1825 break;
1827 for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1828 media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1829 if (!media || media->type != AST_MEDIA_TYPE_VIDEO) {
1830 continue;
1831 }
1832 if (media->rtp) {
1833 /* FIXME: Only use this for VP8. Additional work would have to be done to
1834 * fully support other video codecs */
1835
1840 /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
1841 * RTP engine would provide a way to externally write/schedule RTCP
1842 * packets */
1843 struct ast_frame fr;
1846 res = ast_rtp_instance_write(media->rtp, &fr);
1847 } else {
1848 ao2_ref(channel->session, +1);
1850 ao2_cleanup(channel->session);
1851 }
1852 }
1853 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1854 } else {
1855 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1856 res = -1;
1857 }
1858 }
1859 /* XXX If there were no video streams, then this should set
1860 * res to -1
1861 */
1862 break;
1864 ao2_ref(channel->session, +1);
1866 ao2_cleanup(channel->session);
1867 }
1868 break;
1870 break;
1872 res = -1;
1873 break;
1875 ast_assert(datalen == sizeof(int));
1876 if (*(int *) data) {
1877 /*
1878 * Masquerade is beginning:
1879 * Wait for session serializer to get suspended.
1880 */
1881 ast_channel_unlock(ast);
1883 ast_channel_lock(ast);
1884 } else {
1885 /*
1886 * Masquerade is complete:
1887 * Unsuspend the session serializer.
1888 */
1890 }
1891 break;
1892 case AST_CONTROL_HOLD:
1894 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1895 device_buf = alloca(device_buf_size);
1896 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1898 if (!channel->session->moh_passthrough) {
1899 ast_moh_start(ast, data, NULL);
1900 } else {
1902 ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1904 ao2_ref(channel->session, -1);
1905 }
1906 }
1907 break;
1908 case AST_CONTROL_UNHOLD:
1910 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1911 device_buf = alloca(device_buf_size);
1912 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1914 if (!channel->session->moh_passthrough) {
1915 ast_moh_stop(ast);
1916 } else {
1918 ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1920 ao2_ref(channel->session, -1);
1921 }
1922 }
1923 break;
1925 break;
1927 if (!channel->session->endpoint->media.bundle) {
1928 /* Generate a new SSRC due to media source change and RTP timestamp reset.
1929 Ensures RFC 3550 compliance and avoids SBC interoperability issues (Sonus/Ribbon)*/
1930 for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1931 media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1932 if (media && media->rtp) {
1934 }
1935 }
1936 }
1937 break;
1939 if (ast_channel_state(ast) != AST_STATE_UP) {
1940 response_code = 181;
1941 } else {
1942 res = -1;
1943 }
1944 break;
1946 res = 0;
1947
1948 if (channel->session->t38state == T38_PEER_REINVITE) {
1949 const struct ast_control_t38_parameters *parameters = data;
1950
1951 if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1953 }
1954 }
1955
1956 break;
1958 topology = data;
1959 ast_trace(-1, "%s: New topology: %s\n", ast_channel_name(ast),
1960 ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
1961 res = handle_topology_request_change(channel->session, topology);
1962 break;
1964 break;
1966 break;
1968 break;
1969 case -1:
1970 res = -1;
1971 break;
1972 default:
1973 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1974 res = -1;
1975 break;
1976 }
1977
1978 if (response_code) {
1979 struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1980
1981 if (!ind_data) {
1982 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1983 }
1984
1985 if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1986 ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1988 ao2_cleanup(ind_data);
1989 res = -1;
1990 }
1991 }
1992
1993 SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_channel_name(ast));
1994}
1995
2000
2001static void transfer_data_destroy(void *obj)
2002{
2003 struct transfer_data *trnf_data = obj;
2004
2005 ast_free(trnf_data->target);
2006 ao2_cleanup(trnf_data->session);
2007}
2008
2010{
2011 struct transfer_data *trnf_data = ao2_alloc(sizeof(*trnf_data), transfer_data_destroy);
2012
2013 if (!trnf_data) {
2014 return NULL;
2015 }
2016
2017 if (!(trnf_data->target = ast_strdup(target))) {
2018 ao2_ref(trnf_data, -1);
2019 return NULL;
2020 }
2021
2022 ao2_ref(session, +1);
2023 trnf_data->session = session;
2024
2025 return trnf_data;
2026}
2027
2028static void transfer_redirect(struct ast_sip_session *session, const char *target)
2029{
2030 pjsip_tx_data *packet;
2032 pjsip_contact_hdr *contact;
2033 pj_str_t tmp;
2034
2035 if (pjsip_inv_end_session(session->inv_session, 302, NULL, &packet) != PJ_SUCCESS
2036 || !packet) {
2037 ast_log(LOG_WARNING, "Failed to redirect PJSIP session for channel %s\n",
2038 ast_channel_name(session->channel));
2041
2042 return;
2043 }
2044
2045 if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
2046 contact = pjsip_contact_hdr_create(packet->pool);
2047 }
2048
2049 pj_strdup2_with_null(packet->pool, &tmp, target);
2050 if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
2051 ast_log(LOG_WARNING, "Failed to parse destination URI '%s' for channel %s\n",
2052 target, ast_channel_name(session->channel));
2055 pjsip_tx_data_dec_ref(packet);
2056
2057 return;
2058 }
2059 pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
2060
2063}
2064
2065/*! \brief General PJSIP module for chan_pjsip, currently used for REFER subscription data and outgoing request callbacks */
2066static pjsip_module chan_pjsip_module = {
2067 .name = { "chan_pjsip", 10 },
2068 .id = -1,
2069 .on_tx_request = transport_info_on_tx_request,
2070};
2071
2072/*!
2073 * \brief Callback function to report status of implicit REFER-NOTIFY subscription.
2074 *
2075 * This function will be called on any state change in the REFER-NOTIFY subscription.
2076 * Its primary purpose is to report SUCCESS/FAILURE of a transfer initiated via
2077 * \ref transfer_refer as well as to terminate the subscription, if necessary.
2078 */
2079static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
2080{
2081 struct ast_channel *chan;
2083 int res = 0;
2084
2085 if (!event) {
2086 return;
2087 }
2088
2089 chan = pjsip_evsub_get_mod_data(sub, chan_pjsip_module.id);
2090 if (!chan) {
2091 return;
2092 }
2093
2094 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
2095 /* Check if subscription is suppressed and terminate and send completion code, if so. */
2096 pjsip_rx_data *rdata;
2097 pjsip_generic_string_hdr *refer_sub;
2098 const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
2099
2100 ast_debug(3, "Transfer accepted on channel %s\n", ast_channel_name(chan));
2101
2102 /* Check if response message */
2103 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
2104 rdata = event->body.tsx_state.src.rdata;
2105
2106 /* Find Refer-Sub header */
2107 refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB, NULL);
2108
2109 /* Check if subscription is suppressed. If it is, the far end will not terminate it,
2110 * and the subscription will remain active until it times out. Terminating it here
2111 * eliminates the unnecessary timeout.
2112 */
2113 if (refer_sub && !pj_stricmp2(&refer_sub->hvalue, "false")) {
2114 /* Since no subscription is desired, assume that call has been transferred successfully. */
2115 /* Channel reference will be released at end of function */
2116 /* Terminate subscription. */
2117 pjsip_evsub_set_mod_data(sub, chan_pjsip_module.id, NULL);
2118 pjsip_evsub_terminate(sub, PJ_TRUE);
2119 res = -1;
2120 }
2121 }
2122 } else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
2123 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
2124 /* Check for NOTIFY complete or error. */
2125 pjsip_msg *msg;
2126 pjsip_msg_body *body;
2127 pjsip_status_line status_line = { .code = 0 };
2128 pj_bool_t is_last;
2129 pj_status_t status;
2130
2131 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
2132 pjsip_rx_data *rdata;
2133
2134 rdata = event->body.tsx_state.src.rdata;
2135 msg = rdata->msg_info.msg;
2136
2137 if (msg->type == PJSIP_REQUEST_MSG) {
2138 if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
2139 body = msg->body;
2140 if (body && !pj_stricmp2(&body->content_type.type, "message")
2141 && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
2142 pjsip_parse_status_line((char *)body->data, body->len, &status_line);
2143 }
2144 }
2145 } else {
2146 status_line.code = msg->line.status.code;
2147 status_line.reason = msg->line.status.reason;
2148 }
2149 } else {
2150 status_line.code = 500;
2151 status_line.reason = *pjsip_get_status_text(500);
2152 }
2153
2154 is_last = (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED);
2155 /* If the status code is >= 200, the subscription is finished. */
2156 if (status_line.code >= 200 || is_last) {
2157 res = -1;
2158
2159 /* If the subscription has terminated, return AST_TRANSFER_SUCCESS for 2XX.
2160 * Return AST_TRANSFER_FAILED for any code < 200.
2161 * Otherwise, return the status code.
2162 * The subscription should not terminate for any code < 200,
2163 * but if it does, that constitutes a failure. */
2164 if (status_line.code < 200) {
2166 } else if (status_line.code >= 300) {
2167 message = status_line.code;
2168 }
2169
2170 /* If subscription not terminated and subscription is finished (status code >= 200)
2171 * terminate it */
2172 if (!is_last) {
2173 pjsip_tx_data *tdata;
2174
2175 status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(), 0, &tdata);
2176 if (status == PJ_SUCCESS) {
2177 pjsip_evsub_send_request(sub, tdata);
2178 }
2179 }
2180 /* Finished. Remove session from subscription */
2181 pjsip_evsub_set_mod_data(sub, chan_pjsip_module.id, NULL);
2182 ast_debug(3, "Transfer channel %s completed: %d %.*s (%s)\n",
2183 ast_channel_name(chan),
2184 status_line.code,
2185 (int)status_line.reason.slen, status_line.reason.ptr,
2186 (message == AST_TRANSFER_SUCCESS) ? "Success" : "Failure");
2187 }
2188 }
2189
2190 if (res) {
2192 ao2_ref(chan, -1);
2193 }
2194}
2195
2196static void transfer_refer(struct ast_sip_session *session, const char *target)
2197{
2198 pjsip_evsub *sub;
2200 pj_str_t tmp;
2201 pjsip_tx_data *packet;
2202 const char *ref_by_val;
2203 char local_info[pj_strlen(&session->inv_session->dlg->local.info_str) + 1];
2204 struct pjsip_evsub_user xfer_cb;
2205 struct ast_channel *chan = session->channel;
2206
2207 pj_bzero(&xfer_cb, sizeof(xfer_cb));
2208 xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
2209
2210 if (pjsip_xfer_create_uac(session->inv_session->dlg, &xfer_cb, &sub) != PJ_SUCCESS) {
2213
2214 return;
2215 }
2216
2217 /* chan_pjsip_module requires a reference to chan
2218 * which will be released in xfer_client_on_evsub_state()
2219 * when the implicit REFER subscription terminates */
2220 pjsip_evsub_set_mod_data(sub, chan_pjsip_module.id, chan);
2221 ao2_ref(chan, +1);
2222
2223 if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
2224 goto failure;
2225 }
2226
2227 ref_by_val = pbx_builtin_getvar_helper(chan, "SIPREFERREDBYHDR");
2228 if (!ast_strlen_zero(ref_by_val)) {
2229 ast_sip_add_header(packet, "Referred-By", ref_by_val);
2230 } else {
2231 ast_copy_pj_str(local_info, &session->inv_session->dlg->local.info_str, sizeof(local_info));
2232 ast_sip_add_header(packet, "Referred-By", local_info);
2233 }
2234
2235 if (pjsip_xfer_send_request(sub, packet) == PJ_SUCCESS) {
2236 return;
2237 }
2238
2239failure:
2242 pjsip_evsub_set_mod_data(sub, chan_pjsip_module.id, NULL);
2243 pjsip_evsub_terminate(sub, PJ_FALSE);
2244
2245 ao2_ref(chan, -1);
2246}
2247
2248static int transfer(void *data)
2249{
2250 struct transfer_data *trnf_data = data;
2251 struct ast_sip_endpoint *endpoint = NULL;
2252 struct ast_sip_contact *contact = NULL;
2253 const char *target = trnf_data->target;
2254
2255 if (trnf_data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2256 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2257 trnf_data->session->inv_session->cause,
2258 pjsip_get_status_text(trnf_data->session->inv_session->cause)->ptr);
2259 } else {
2260 /* See if we have an endpoint; if so, use its contact */
2262 if (endpoint) {
2264 if (contact && !ast_strlen_zero(contact->uri)) {
2265 target = contact->uri;
2266 }
2267 }
2268
2269 if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
2270 transfer_redirect(trnf_data->session, target);
2271 } else {
2272 transfer_refer(trnf_data->session, target);
2273 }
2274 }
2275
2276 ao2_ref(trnf_data, -1);
2278 ao2_cleanup(contact);
2279 return 0;
2280}
2281
2282/*! \brief Function called by core for Asterisk initiated transfer */
2283static int chan_pjsip_transfer(struct ast_channel *chan, const char *target)
2284{
2285 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2286 struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2287
2288 if (!trnf_data) {
2289 return -1;
2290 }
2291
2292 if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2293 ast_log(LOG_WARNING, "Error requesting transfer\n");
2294 ao2_cleanup(trnf_data);
2295 return -1;
2296 }
2297
2298 return 0;
2299}
2300
2301/*! \brief Function called by core to start a DTMF digit */
2302static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit)
2303{
2304 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2305 struct ast_sip_session_media *media;
2306
2308
2309 switch (channel->session->dtmf) {
2311 if (!media || !media->rtp) {
2312 return 0;
2313 }
2314
2316 break;
2317 case AST_SIP_DTMF_AUTO:
2318 if (!media || !media->rtp) {
2319 return 0;
2320 }
2321
2323 return -1;
2324 }
2325
2327 break;
2329 if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2330 return 0;
2331 }
2333 break;
2334 case AST_SIP_DTMF_NONE:
2335 break;
2337 return -1;
2338 default:
2339 break;
2340 }
2341
2342 return 0;
2343}
2344
2347 char digit;
2348 unsigned int duration;
2349};
2350
2351static void info_dtmf_data_destroy(void *obj)
2352{
2353 struct info_dtmf_data *dtmf_data = obj;
2354 ao2_ref(dtmf_data->session, -1);
2355}
2356
2358{
2359 struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
2360 if (!dtmf_data) {
2361 return NULL;
2362 }
2363 ao2_ref(session, +1);
2364 dtmf_data->session = session;
2365 dtmf_data->digit = digit;
2366 dtmf_data->duration = duration;
2367 return dtmf_data;
2368}
2369
2370static int transmit_info_dtmf(void *data)
2371{
2372 RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
2373
2374 struct ast_sip_session *session = dtmf_data->session;
2375 struct pjsip_tx_data *tdata;
2376
2377 RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
2378
2379 struct ast_sip_body body = {
2380 .type = "application",
2381 .subtype = "dtmf-relay",
2382 };
2383
2384 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2385 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2386 session->inv_session->cause,
2387 pjsip_get_status_text(session->inv_session->cause)->ptr);
2388 return -1;
2389 }
2390
2391 if (!(body_text = ast_str_create(32))) {
2392 ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
2393 return -1;
2394 }
2395 ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
2396
2398
2399 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
2400 ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
2401 return -1;
2402 }
2403 if (ast_sip_add_body(tdata, &body)) {
2404 ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
2405 pjsip_tx_data_dec_ref(tdata);
2406 return -1;
2407 }
2409
2410 return 0;
2411}
2412
2413/*! \brief Function called by core to stop a DTMF digit */
2414static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
2415{
2416 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2417 struct ast_sip_session_media *media;
2418
2419 if (!channel || !channel->session) {
2420 /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2421 ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2422 return -1;
2423 }
2424
2426
2427 switch (channel->session->dtmf) {
2429 {
2430 if (!media || !media->rtp) {
2431 return 0;
2432 }
2433
2435 ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2437 break;
2438 }
2439 /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2440 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));
2441 }
2442
2443 case AST_SIP_DTMF_INFO:
2444 {
2445 struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2446
2447 if (!dtmf_data) {
2448 return -1;
2449 }
2450
2451 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2452 ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2453 ao2_cleanup(dtmf_data);
2454 return -1;
2455 }
2456 break;
2457 }
2459 if (!media || !media->rtp) {
2460 return 0;
2461 }
2462
2464 break;
2465 case AST_SIP_DTMF_AUTO:
2466 if (!media || !media->rtp) {
2467 return 0;
2468 }
2469
2471 return -1;
2472 }
2473
2475 break;
2476 case AST_SIP_DTMF_NONE:
2477 break;
2479 return -1;
2480 }
2481
2482 return 0;
2483}
2484
2486{
2488
2489 /*
2490 * Use the channel CALLERID() as the initial connected line data.
2491 * The core or a predial handler may have supplied missing values
2492 * from the session->endpoint->id.self about who we are calling.
2493 */
2494 ast_channel_lock(session->channel);
2496 ast_channel_unlock(session->channel);
2497
2498 /* Supply initial connected line information if available. */
2499 if (!session->id.number.valid && !session->id.name.valid) {
2500 return;
2501 }
2502
2504 connected.id = session->id;
2506
2508}
2509
2510static int call(void *data)
2511{
2512 struct ast_sip_session *session = data;
2513 pjsip_tx_data *tdata;
2514 int res = 0;
2515 SCOPE_ENTER(1, "%s Topology: %s\n",
2517 ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP))
2518 );
2519
2520
2522
2523 if (res) {
2524 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2525 ast_queue_hangup(session->channel);
2526 } else {
2530 }
2531 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2532}
2533
2534/*! \brief Function called by core to actually start calling a remote party */
2535static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeout)
2536{
2537 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2538 struct ast_sip_session *session = ao2_bump(channel->session);
2539
2540 SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(session),
2541 ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP)));
2542
2543 ast_channel_unlock(ast);
2544
2545 /* The creation of the INVITE needs to be pushed synchronously to prevent a race condition
2546 with bridging on attended transfers that can result in a loss of set Caller ID. */
2548 ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2549 ao2_ref(session, -1);
2550 ast_channel_lock(ast);
2551 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2552 }
2553
2554 ao2_ref(session, -1);
2555 ast_channel_lock(ast);
2556 SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2557}
2558
2559/*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */
2560static int hangup_cause2sip(int cause)
2561{
2562 switch (cause) {
2564 return 302;
2565 case AST_CAUSE_UNALLOCATED: /* 1 */
2566 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
2567 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
2568 return 404;
2569 case AST_CAUSE_CONGESTION: /* 34 */
2570 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
2571 return 503;
2572 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
2573 return 408;
2574 case AST_CAUSE_NO_ANSWER: /* 19 */
2575 case AST_CAUSE_UNREGISTERED: /* 20 */
2576 return 480;
2577 case AST_CAUSE_CALL_REJECTED: /* 21 */
2578 return 403;
2579 case AST_CAUSE_NUMBER_CHANGED: /* 22 */
2580 return 410;
2581 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
2582 return 480;
2584 return 484;
2586 return 486;
2587 case AST_CAUSE_FAILURE:
2588 return 500;
2589 case AST_CAUSE_FACILITY_REJECTED: /* 29 */
2590 return 501;
2592 return 503;
2594 return 502;
2595 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
2596 return 488;
2597 case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
2598 return 500;
2600 default:
2601 ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
2602 return 0;
2603 }
2604
2605 /* Never reached */
2606 return 0;
2607}
2608
2609struct hangup_data {
2612};
2613
2614static void hangup_data_destroy(void *obj)
2615{
2616 struct hangup_data *h_data = obj;
2617
2618 h_data->chan = ast_channel_unref(h_data->chan);
2619}
2620
2622{
2623 struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2624
2625 if (!h_data) {
2626 return NULL;
2627 }
2628
2629 h_data->cause = cause;
2630 h_data->chan = ast_channel_ref(chan);
2631
2632 return h_data;
2633}
2634
2635/*! \brief Clear a channel from a session along with its PVT (channel lock held) */
2637 struct ast_channel *ast)
2638{
2639 session->channel = NULL;
2642}
2643
2644/*! \brief Clear a channel from a session along with its PVT */
2646{
2647 /* Serialize detachment with channel-locked readers of the session. */
2648 ast_channel_lock(ast);
2650 ast_channel_unlock(ast);
2651}
2652
2653static int hangup(void *data)
2654{
2655 struct hangup_data *h_data = data;
2656 struct ast_channel *ast = h_data->chan;
2657 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2658 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2659
2660 /*
2661 * Before cleaning we have to ensure that channel or its session is not NULL
2662 * we have seen rare case when taskprocessor calls hangup but channel is NULL
2663 * due to SIP session timeout and answer happening at the same time
2664 */
2665 if (channel) {
2666 struct ast_sip_session *session = channel->session;
2667 if (session) {
2668 int cause = h_data->cause;
2669
2670 if (channel->session->active_media_state &&
2671 channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
2672 struct ast_sip_session_media *media =
2674 if (media->rtp) {
2676 }
2677 }
2678
2679 /*
2680 * It's possible that session_terminate might cause the session to be destroyed
2681 * immediately so we need to keep a reference to it so we can NULL session->channel
2682 * afterwards.
2683 */
2687 }
2688 ao2_cleanup(channel);
2689 }
2690 ao2_cleanup(h_data);
2692}
2693
2694/*! \brief Function called by core to hang up a PJSIP session */
2695static int chan_pjsip_hangup(struct ast_channel *ast)
2696{
2697 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2698 int cause;
2699 int tech_cause;
2700 int original_tech_cause;
2701 struct hangup_data *h_data;
2702 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2703
2704 if (!channel || !channel->session) {
2705 SCOPE_EXIT_RTN_VALUE(-1, "%s: No channel or session\n", ast_channel_name(ast));
2706 }
2707
2709 tech_cause = hangup_cause2sip(cause);
2710 original_tech_cause = ast_channel_tech_hangupcause(channel->session->channel);
2711 if (!original_tech_cause) {
2712 ast_channel_tech_hangupcause_set(channel->session->channel, tech_cause);
2713 }
2714
2715 h_data = hangup_data_alloc(tech_cause, ast);
2716 if (!h_data) {
2717 goto failure;
2718 }
2719
2720 if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2721 ast_log(LOG_WARNING, "Unable to push hangup task to the taskpool. Expect bad things\n");
2722 goto failure;
2723 }
2724
2725 SCOPE_EXIT_RTN_VALUE(0, "%s: Cause: %d Tech Cause: %d\n", ast_channel_name(ast),
2726 cause, tech_cause);
2727
2728failure:
2729 /* Go ahead and do our cleanup of the session and channel even if we're not going
2730 * to be able to send our SIP request/response
2731 */
2733 ao2_cleanup(channel);
2734 ao2_cleanup(h_data);
2735
2736 SCOPE_EXIT_RTN_VALUE(-1, "%s: Cause: %d\n", ast_channel_name(ast), cause);
2737}
2738
2745
2746static int request(void *obj)
2747{
2748 struct request_data *req_data = obj;
2749 struct ast_sip_session *session = NULL;
2750 char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
2751 struct ast_sip_endpoint *endpoint;
2752
2754 AST_APP_ARG(endpoint);
2755 AST_APP_ARG(aor);
2756 );
2757 SCOPE_ENTER(1, "%s\n",tmp);
2758
2759 if (ast_strlen_zero(tmp)) {
2760 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty destination\n");
2762 SCOPE_EXIT_RTN_VALUE(-1, "Empty destination\n");
2763 }
2764
2765 AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
2766
2768 /* If a request user has been specified extract it from the endpoint name portion */
2769 if ((endpoint_name = strchr(args.endpoint, '@'))) {
2770 request_user = args.endpoint;
2771 *endpoint_name++ = '\0';
2772 } else {
2773 endpoint_name = args.endpoint;
2774 }
2775
2776 if (ast_strlen_zero(endpoint_name)) {
2777 if (request_user) {
2778 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2779 request_user);
2780 } else {
2781 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2782 }
2784 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2785 }
2786 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2787 endpoint_name);
2788 if (!endpoint) {
2789 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2791 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2792 }
2793 } else {
2794 /* First try to find an exact endpoint match, for single (user) or multi-domain (user@domain) */
2795 endpoint_name = args.endpoint;
2796 if (ast_strlen_zero(endpoint_name)) {
2797 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2799 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2800 }
2801 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2802 endpoint_name);
2803 if (!endpoint) {
2804 /* It seems it's not a multi-domain endpoint or single endpoint exact match,
2805 * it's possible that it's a SIP trunk with a specified user (user@trunkname),
2806 * so extract the user before @ sign.
2807 */
2808 endpoint_name = strchr(args.endpoint, '@');
2809 if (!endpoint_name) {
2810 /*
2811 * Couldn't find an '@' so it had to be an endpoint
2812 * name that doesn't exist.
2813 */
2814 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n",
2815 args.endpoint);
2817 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2818 }
2819 request_user = args.endpoint;
2820 *endpoint_name++ = '\0';
2821
2822 if (ast_strlen_zero(endpoint_name)) {
2823 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2824 request_user);
2826 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2827 }
2828
2829 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2830 endpoint_name);
2831 if (!endpoint) {
2832 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2834 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2835 }
2836 }
2837 }
2838
2839 session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user,
2840 req_data->topology);
2841 ao2_ref(endpoint, -1);
2842 if (!session) {
2843 ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
2845 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create session\n");
2846 }
2847
2848 req_data->session = session;
2849
2851}
2852
2853/*! \brief Function called by core to create a new outgoing PJSIP session */
2854static 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)
2855{
2856 struct request_data req_data;
2858 SCOPE_ENTER(1, "%s Topology: %s\n", data,
2860
2861 req_data.topology = topology;
2862 req_data.dest = data;
2863 /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2864 req_data.cause = AST_CAUSE_FAILURE;
2865
2866 if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2867 *cause = req_data.cause;
2868 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2869 }
2870
2871 session = req_data.session;
2872
2873 if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2874 /* Session needs to be terminated prematurely */
2875 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2876 }
2877
2878 SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2879}
2880
2881static 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)
2882{
2883 struct ast_stream_topology *topology;
2884 struct ast_channel *chan;
2885
2887 if (!topology) {
2888 return NULL;
2889 }
2890
2891 chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2892
2893 ast_stream_topology_free(topology);
2894
2895 return chan;
2896}
2897
2902
2903static void sendtext_data_destroy(void *obj)
2904{
2905 struct sendtext_data *data = obj;
2906 ao2_cleanup(data->session);
2907 ast_free(data->msg);
2908}
2909
2911 struct ast_msg_data *msg)
2912{
2913 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2914 struct sendtext_data *data = ao2_alloc(sizeof(*data), sendtext_data_destroy);
2915
2916 if (!data) {
2917 return NULL;
2918 }
2919
2920 data->msg = ast_msg_data_dup(msg);
2921 if (!data->msg) {
2922 ao2_cleanup(data);
2923 return NULL;
2924 }
2925 data->session = channel->session;
2926 ao2_ref(data->session, +1);
2927
2928 return data;
2929}
2930
2931static int sendtext(void *obj)
2932{
2933 struct sendtext_data *data = obj;
2934 pjsip_tx_data *tdata;
2935 const char *body_text = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_BODY);
2936 const char *content_type = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_CONTENT_TYPE);
2937 char *sep;
2938 struct ast_sip_body body = {
2939 .type = "text",
2940 .subtype = "plain",
2941 .body_text = body_text,
2942 };
2943
2944 if (!ast_strlen_zero(content_type)) {
2945 char *content_type_copy = ast_strdupa(content_type);
2946 sep = strchr(content_type_copy, '/');
2947 if (sep) {
2948 *sep = '\0';
2949 body.type = content_type_copy;
2950 body.subtype = ++sep;
2951 }
2952 }
2953
2954 if (data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2955 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2956 data->session->inv_session->cause,
2957 pjsip_get_status_text(data->session->inv_session->cause)->ptr);
2958 } else {
2959 pjsip_from_hdr *hdr;
2960 pjsip_name_addr *name_addr;
2961 const char *from = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_FROM);
2962 const char *to = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_TO);
2963 int invalidate_tdata = 0;
2964
2965 ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
2966 ast_sip_add_body(tdata, &body);
2967
2968 /*
2969 * If we have a 'from' in the msg, set the display name in the From
2970 * header to it.
2971 */
2972 if (!ast_strlen_zero(from)) {
2973 hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
2974 name_addr = (pjsip_name_addr *) hdr->uri;
2975 pj_strdup2(tdata->pool, &name_addr->display, from);
2976 invalidate_tdata = 1;
2977 }
2978
2979 /*
2980 * If we have a 'to' in the msg, set the display name in the To
2981 * header to it.
2982 */
2983 if (!ast_strlen_zero(to)) {
2984 hdr = PJSIP_MSG_TO_HDR(tdata->msg);
2985 name_addr = (pjsip_name_addr *) hdr->uri;
2986 pj_strdup2(tdata->pool, &name_addr->display, to);
2987 invalidate_tdata = 1;
2988 }
2989
2990 if (invalidate_tdata) {
2991 pjsip_tx_data_invalidate_msg(tdata);
2992 }
2993
2994 ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
2995 }
2996
2997 ao2_cleanup(data);
2998
2999 return 0;
3000}
3001
3002/*! \brief Function called by core to send text on PJSIP session */
3003static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
3004{
3005 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
3006 struct sendtext_data *data = sendtext_data_create(ast, msg);
3007
3008 ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
3011 ast_channel_name(ast),
3013
3014 if (!data) {
3015 return -1;
3016 }
3017
3018 if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
3019 ao2_ref(data, -1);
3020 return -1;
3021 }
3022 return 0;
3023}
3024
3025static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
3026{
3027 struct ast_msg_data *msg;
3028 int rc;
3029 struct ast_msg_data_attribute attrs[] =
3030 {
3031 {
3033 .value = (char *)text,
3034 }
3035 };
3036
3038 if (!msg) {
3039 return -1;
3040 }
3041 rc = chan_pjsip_sendtext_data(ast, msg);
3042 ast_free(msg);
3043
3044 return rc;
3045}
3046
3048{
3049 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3051
3052 if (session->endpoint->media.direct_media.glare_mitigation ==
3054 SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
3055 }
3056
3058 "direct_media_glare_mitigation");
3059
3060 if (!datastore) {
3061 SCOPE_EXIT_RTN("Couldn't create datastore\n");
3062 }
3063
3066}
3067
3068/*! \brief Function called when the session ends */
3070{
3071 int existing_cause = 0;
3072 int existing_tech_cause = 0;
3073 int new_cause = 0;
3074 int new_tech_cause = 0;
3076
3077 if (session->inv_session) {
3078 ast_trace(-1, "%s: inv_session->cause: %d\n", ast_sip_session_get_name(session),
3079 session->inv_session->cause);
3080 }
3081
3082 if (!session->channel) {
3083 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3084 }
3085
3086 if (session->active_media_state &&
3087 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
3088 struct ast_sip_session_media *media =
3089 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
3090 if (media->rtp) {
3092 }
3093 }
3094
3096 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
3097
3098 existing_cause = ast_channel_hangupcause(session->channel);
3099 new_cause = existing_cause;
3100 existing_tech_cause = ast_channel_tech_hangupcause(session->channel);
3101 new_tech_cause = existing_tech_cause;
3102
3103 ast_trace(-1, "%s: existing ast_cause: %d tech_cause: %d\n", ast_sip_session_get_name(session),
3104 existing_cause, existing_tech_cause);
3105
3106 if (session->inv_session) {
3107 struct ao2_iterator dialed_causes_iterator = ast_channel_dialed_causes_iterator(session->channel);
3108 struct ast_control_pvt_cause_code *pvt_cause;
3109 int tech_cause = 0;
3110
3111 /*
3112 * The dialed causes represent the results of each channel dialed but we are only
3113 * interested in the cause codes for _this_ channel. For example, in a redirect
3114 * scenario, if this channel is the redirecting channel (it responded with a 302),
3115 * then chan_pjsip_incoming_response_update_cause() will have been called with the
3116 * 302 and it would have been added to the dialed causes for this channel. When this
3117 * session ends however, the inv_session->cause will probably be something like
3118 * "487 Request terminated" which is just a generic "the session ended" code and
3119 * not really informative.
3120 *
3121 * We'll iterate over the dialed causes to find the one for this channel and if we
3122 * find one with a non-2xx SIP response code, we'll use that cause code for the
3123 * channel hangup cause instead of the generic 487 cause code that results from
3124 * the session termination.
3125 */
3126 while ((pvt_cause = ao2_iterator_next(&dialed_causes_iterator))) {
3127 if (ast_strings_equal(pvt_cause->chan_name, ast_channel_name(session->channel))) {
3128 /*
3129 * The "SIP <code> <reason>" format for pvt_cause->code is set in
3130 * chan_pjsip_incoming_response_update_cause but only for PJSIP channels.
3131 * However, since we've just checked that the chan_name matches our channel,
3132 * we can be confident that this format is correct and attempt to parse out the
3133 * tech cause from it. If for some reason it doesn't match this format,
3134 * we'll just log a trace/debug and skip using this cause code.
3135 */
3136 int count = sscanf(pvt_cause->code, "SIP %d ", &tech_cause);
3137 if (count != 1) {
3138 ast_trace(-1, "%s: Unable to parse tech_cause from code '%s'\n",
3140 continue;
3141 }
3142 /* We only want to use non-2XX SIP response codes */
3143 if (tech_cause / 100 > 2) {
3144 new_tech_cause = tech_cause;
3145 if (!existing_cause) {
3146 new_cause = pvt_cause->ast_cause;
3147 }
3148 ast_trace(-1, "%s: %s dialed ast_cause: %d tech_cause: %d used\n", ast_sip_session_get_name(session),
3149 pvt_cause->chan_name, new_cause, new_tech_cause);
3150 } else {
3151 ast_trace(-1, "%s: %s dialed ast_cause: %d tech_cause: %s. Skipped 2XX code.\n",
3153 pvt_cause->ast_cause, pvt_cause->code);
3154 }
3155 } else {
3156 ast_trace(-1, "%s: %s dialed ast_cause: %d tech_cause: %s. Skipped other channel.\n",
3158 pvt_cause->ast_cause, pvt_cause->code);
3159 }
3160 ao2_cleanup(pvt_cause);
3161 }
3162 ao2_iterator_destroy(&dialed_causes_iterator);
3163
3164 /*
3165 * We have a chicken and egg thing going here. We can derive the tech_cause
3166 * from the ast cause but we can also derive the ast cause from the tech cause.
3167 */
3168
3169 /* We only want to use non 2XX response codes for tech cause. */
3170 if (new_tech_cause == 0 && session->inv_session->cause / 100 > 2) {
3171 new_tech_cause = session->inv_session->cause;
3172 ast_trace(-1, "%s: Using tech_cause %d from invite session\n",
3173 ast_sip_session_get_name(session), session->inv_session->cause);
3174 }
3175
3176 if (new_cause == 0 && new_tech_cause > 0) {
3177 new_cause = ast_sip_hangup_sip2cause(new_tech_cause);
3178 ast_trace(-1, "%s: Using ast_cause %d derived from tech_cause %d\n",
3179 ast_sip_session_get_name(session), new_cause, new_tech_cause);
3180 }
3181
3182 if (new_cause != existing_cause) {
3183 ast_trace(-1, "%s: Setting ast_cause %d\n",
3184 ast_sip_session_get_name(session), new_cause);
3185 ast_channel_hangupcause_set(session->channel, new_cause);
3186 }
3187
3188 if (new_tech_cause == 0) {
3189 new_tech_cause = hangup_cause2sip(new_cause);
3190 ast_trace(-1, "%s: Using tech_cause cause %d derived from ast_cause %d\n",
3191 ast_sip_session_get_name(session), new_tech_cause, new_cause);
3192 }
3193
3194 if (new_tech_cause != existing_tech_cause && new_tech_cause / 100 > 2) {
3195 ast_trace(-1, "%s: Setting tech_cause %d\n",
3196 ast_sip_session_get_name(session), new_tech_cause);
3197 ast_channel_tech_hangupcause_set(session->channel, new_tech_cause);
3198 }
3199 }
3200
3201 ast_queue_hangup(session->channel);
3202
3203 SCOPE_EXIT_RTN("%s: ast_cause: %d tech_cause: %d\n", ast_sip_session_get_name(session),
3204 new_cause, new_tech_cause);
3205}
3206
3208{
3209 const pj_str_t *host = ast_sip_pjsip_uri_get_hostname(session->request_uri);
3210 size_t size = pj_strlen(host) + 1;
3211 char *domain = ast_alloca(size);
3212
3213 ast_copy_pj_str(domain, host, size);
3214
3215 pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
3216 return;
3217}
3218
3219/*! \brief Function called when a request is received on the session */
3220static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3221{
3222 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
3223 struct transport_info_data *transport_data;
3224 pjsip_tx_data *packet = NULL;
3226
3227 if (session->channel) {
3228 SCOPE_EXIT_RTN_VALUE(0, "%s: No channel\n", ast_sip_session_get_name(session));
3229 }
3230
3231 /* Check for a to-tag to determine if this is a reinvite */
3232 if (rdata->msg_info.to->tag.slen) {
3233 /* Weird case. We've received a reinvite but we don't have a channel. The most
3234 * typical case for this happening is that a blind transfer fails, and so the
3235 * transferer attempts to reinvite himself back into the call. We already got
3236 * rid of that channel, and the other side of the call is unrecoverable.
3237 *
3238 * We treat this as a failure, so our best bet is to just hang this call
3239 * up and not create a new channel. Clearing defer_terminate here ensures that
3240 * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
3241 */
3242 session->defer_terminate = 0;
3244 SCOPE_EXIT_RTN_VALUE(-1, "%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
3245 }
3246
3247 datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
3248 if (!datastore) {
3249 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
3250 }
3251
3252 transport_data = ast_calloc(1, sizeof(*transport_data));
3253 if (!transport_data) {
3254 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3255 }
3256 pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3257 pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3258 datastore->data = transport_data;
3260
3261 if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3262 if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3263 && packet) {
3265 }
3266
3267 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3269 }
3270
3272
3273 /* channel gets created on incoming request, but we wait to call start
3274 so other supplements have a chance to run */
3276}
3277
3278static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
3279{
3280 struct ast_features_pickup_config *pickup_cfg;
3281 struct ast_channel *chan;
3282
3283 /* Check for a to-tag to determine if this is a reinvite */
3284 if (rdata->msg_info.to->tag.slen) {
3285 /* We don't care about reinvites */
3286 return 0;
3287 }
3288
3289 pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3290 if (!pickup_cfg) {
3291 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3292 return 0;
3293 }
3294
3295 if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3296 ao2_ref(pickup_cfg, -1);
3297 return 0;
3298 }
3299 ao2_ref(pickup_cfg, -1);
3300
3301 /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3302 * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3303 * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3304 */
3305 chan = ast_channel_ref(session->channel);
3306 if (ast_pickup_call(chan)) {
3308 } else {
3310 }
3311 /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3312 * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3313 * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3314 * to anything at all.
3315 */
3316 ast_hangup(chan);
3317 ast_channel_unref(chan);
3318
3319 return 1;
3320}
3321
3323 .method = "INVITE",
3324 .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
3325 .incoming_request = call_pickup_incoming_request,
3326};
3327
3328static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
3329{
3330 int res;
3332
3333 /* Check for a to-tag to determine if this is a reinvite */
3334 if (rdata->msg_info.to->tag.slen) {
3335 /* We don't care about reinvites */
3336 SCOPE_EXIT_RTN_VALUE(0, "Reinvite\n");
3337 }
3338
3339 res = ast_pbx_start(session->channel);
3340
3341 switch (res) {
3342 case AST_PBX_FAILED:
3343 ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
3345 ast_hangup(session->channel);
3346 break;
3347 case AST_PBX_CALL_LIMIT:
3348 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
3350 ast_hangup(session->channel);
3351 break;
3352 case AST_PBX_SUCCESS:
3353 default:
3354 break;
3355 }
3356
3357 ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
3358
3359 SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1, "RC: %d\n", res);
3360}
3361
3363 .method = "INVITE",
3365 .incoming_request = pbx_start_incoming_request,
3366};
3367
3368/*! \brief Function called when a response is received on the session */
3369static void chan_pjsip_incoming_response_update_cause(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3370{
3371 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3372 struct ast_control_pvt_cause_code *cause_code;
3373 int data_size = sizeof(*cause_code);
3374 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3375
3376 if (!session->channel) {
3377 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3378 }
3379
3380 /* Build and send the tech-specific cause information */
3381 /* size of the string making up the cause code is "SIP " number + " " + reason length */
3382 data_size += 4 + 4 + pj_strlen(&status.reason);
3383 cause_code = ast_alloca(data_size);
3384 memset(cause_code, 0, data_size);
3385
3387
3388 /*
3389 * The cause code string is built in the format "SIP <status code> <reason phrase>".
3390 * Unfortunately, the ast_control_pvt_cause_code structure doesn't have a separate
3391 * field for the numeric code and adding it would break ABI so we'll have to parse
3392 * this string in chan_pjsip_session_end() later. If the string needs to be
3393 * changed, make sure the parsing in chan_pjsip_session_end() is adjusted as well.
3394 */
3395 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3396 (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3397
3398 cause_code->ast_cause = ast_sip_hangup_sip2cause(status.code);
3399 ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3400 ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3401
3402 SCOPE_EXIT_RTN("%s: ast_cause: %d tech_cause: %s\n", ast_sip_session_get_name(session),
3403 cause_code->ast_cause, cause_code->code);
3404}
3405
3406/*! \brief Function called when a response is received on the session */
3407static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3408{
3409 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3410 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3411
3412 if (!session->channel) {
3413 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3414 }
3415
3416 switch (status.code) {
3417 case 180: {
3418 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3419 if (sdp && sdp->body.ptr) {
3420 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3421 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3423 } else {
3424 ast_trace(-1, "%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3426 }
3427
3428 ast_channel_lock(session->channel);
3429 if (ast_channel_state(session->channel) != AST_STATE_UP) {
3431 }
3432 ast_channel_unlock(session->channel);
3433 break;
3434 }
3435 case 183:
3436 if (session->endpoint->ignore_183_without_sdp) {
3437 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3438 if (sdp && sdp->body.ptr) {
3439 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3440 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3441 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3442 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3444 }
3445 } else {
3446 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3447 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3448 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3450 }
3451 break;
3452 case 200:
3453 ast_trace(-1, "%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3455 break;
3456 default:
3457 ast_trace(-1, "%s: Not queueing anything\n", ast_sip_session_get_name(session));
3458 break;
3459 }
3460
3462}
3463
3464static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3465{
3467
3468 if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3469 if (session->endpoint->media.direct_media.enabled && session->channel) {
3470 ast_trace(-1, "%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3472 }
3473 }
3475}
3476
3477static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3478{
3480
3481 if (pj_strcmp2(&rdata->msg_info.msg->line.req.method.name, "PRACK") == 0 &&
3482 pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE) {
3483
3484 session->early_confirmed = 1;
3485 }
3487}
3488
3489static int update_devstate(void *obj, void *arg, int flags)
3490{
3492 "PJSIP/%s", ast_sorcery_object_get_id(obj));
3493 return 0;
3494}
3495
3497 .name = "PJSIP_DIAL_CONTACTS",
3499};
3500
3502 .name = "PJSIP_PARSE_URI",
3504};
3505
3507 .name = "PJSIP_PARSE_URI_FROM",
3509};
3510
3512 .name = "PJSIP_MEDIA_OFFER",
3515};
3516
3518 .name = "PJSIP_DTMF_MODE",
3521};
3522
3524 .name = "PJSIP_MOH_PASSTHROUGH",
3527};
3528
3530 .name = "PJSIP_SEND_SESSION_REFRESH",
3532};
3533
3535 .name = "PJSIP_TRANSFER_HANDLING",
3537};
3538
3539static char *app_pjsip_hangup = "PJSIPHangup";
3540
3541/*!
3542 * \brief Load the module
3543 *
3544 * Module loading including tests for configuration or dependencies.
3545 * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
3546 * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
3547 * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
3548 * configuration file or other non-critical problem return
3549 * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
3550 */
3551static int load_module(void)
3552{
3553 struct ao2_container *endpoints;
3554
3557 }
3558
3560
3563
3565 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3566 goto end;
3567 }
3568
3570 ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3571 goto end;
3572 }
3573
3575 ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3576 goto end;
3577 }
3578
3580 ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI_FROM dialplan function\n");
3581 goto end;
3582 }
3583
3585 ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3586 goto end;
3587 }
3588
3590 ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3591 goto end;
3592 }
3593
3595 ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3596 goto end;
3597 }
3598
3600 ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3601 goto end;
3602 }
3603
3605 ast_log(LOG_WARNING, "Unable to register PJSIP_TRANSFER_HANDLING dialplan function\n");
3606 goto end;
3607 }
3608
3610 ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
3611 goto end;
3612 }
3614
3615
3617
3620
3624 ast_log(LOG_ERROR, "Unable to create held channels container\n");
3625 goto end;
3626 }
3627
3632
3634 ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3635 goto end;
3636 }
3637
3638 /* since endpoints are loaded before the channel driver their device
3639 states get set to 'invalid', so they need to be updated */
3640 if ((endpoints = ast_sip_get_endpoints())) {
3642 ao2_ref(endpoints, -1);
3643 }
3644
3645 return 0;
3646
3647end:
3668
3671
3673}
3674
3675/*! \brief Unload the PJSIP channel from Asterisk */
3710
3712 .support_level = AST_MODULE_SUPPORT_CORE,
3713 .load = load_module,
3714 .unload = unload_module,
3715 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
3716 .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub",
Access Control of various sorts.
char digit
jack_status_t status
Definition app_jack.c:149
char * text
Definition app_queue.c:1791
#define var
Definition ast_expr2f.c:605
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
void ast_free_ptr(void *ptr)
free() wrapper
Definition astmm.c:1739
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ast_log
Definition astobj2.c:42
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition astobj2.h:365
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition astobj2.h:1087
@ OBJ_NODATA
Definition astobj2.h:1044
@ OBJ_SEARCH_MASK
Search option field mask.
Definition astobj2.h:1072
@ OBJ_UNLINK
Definition astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#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.
Definition astobj2.h:1303
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition astobj2.h:1188
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define AST_PRES_ALLOWED
Definition callerid.h:432
@ AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER
Definition callerid.h:554
#define AST_PRES_RESTRICTION
Definition callerid.h:431
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
Definition causes.h:123
#define AST_CAUSE_CONGESTION
Definition causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition causes.h:98
#define AST_CAUSE_INTERWORKING
Definition causes.h:146
#define AST_CAUSE_NUMBER_CHANGED
Definition causes.h:112
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition causes.h:130
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition causes.h:116
#define AST_CAUSE_CHAN_NOT_IMPLEMENTED
Definition causes.h:132
#define AST_CAUSE_FAILURE
Definition causes.h:150
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition causes.h:115
#define AST_CAUSE_NO_USER_RESPONSE
Definition causes.h:108
#define AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION
Definition causes.h:113
#define AST_CAUSE_CHANNEL_UNACCEPTABLE
Definition causes.h:102
#define AST_CAUSE_NOTDEFINED
Definition causes.h:155
#define AST_CAUSE_CALL_REJECTED
Definition causes.h:111
#define AST_CAUSE_FACILITY_REJECTED
Definition causes.h:117
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition causes.h:119
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition causes.h:99
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition causes.h:100
#define AST_CAUSE_UNREGISTERED
Definition causes.h:154
#define AST_CAUSE_NO_ANSWER
Definition causes.h:109
#define AST_CAUSE_NORMAL_CLEARING
Definition causes.h:106
#define AST_CAUSE_USER_BUSY
Definition causes.h:107
static int connected
Definition cdr_pgsql.c:73
static PGresult * result
Definition cel_pgsql.c:84
static const char type[]
#define T38_ENABLED
static void transfer_data_destroy(void *obj)
static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static struct ast_datastore_info direct_media_mitigation_info
Definition chan_pjsip.c:371
static int set_transport_info_local_addr(struct pjsip_tx_data *tdata, pj_sockaddr *local_addr)
Determine the local signaling address used for an outgoing request.
Definition chan_pjsip.c:284
static void chan_pjsip_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
Function called by RTP engine to get peer capabilities.
Definition chan_pjsip.c:253
static struct ast_datastore_info transport_info
Datastore used to store local/remote addresses for the INVITE request that created the PJSIP channel.
Definition chan_pjsip.c:270
static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
Callback function to report status of implicit REFER-NOTIFY subscription.
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
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 check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_sip_session_media *media, struct ast_sip_session *session)
Definition chan_pjsip.c:424
static int chan_pjsip_devicestate(const char *data)
Function called to get the device state of an endpoint.
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
static int chan_pjsip_transfer(struct ast_channel *ast, const char *target)
Function called by core for Asterisk initiated transfer.
static int update_connected_line_information(void *data)
Update connected line information.
static pjsip_module chan_pjsip_module
General PJSIP module for chan_pjsip, currently used for REFER subscription data and outgoing request ...
static void transfer_redirect(struct ast_sip_session *session, const char *target)
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.
static char * app_pjsip_hangup
static void chan_pjsip_session_end(struct ast_sip_session *session)
Function called when the session ends.
static int sendtext(void *obj)
static void update_initial_connected_line(struct ast_sip_session *session)
static int update_devstate(void *obj, void *arg, int flags)
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition chan_pjsip.c:144
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
static void rtp_direct_media_data_destroy(void *data)
Definition chan_pjsip.c:463
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 direct_media_mitigate_glare(struct ast_sip_session *session)
Definition chan_pjsip.c:373
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.
Definition chan_pjsip.c:546
static int request(void *obj)
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 int chan_pjsip_hangup(struct ast_channel *ast)
Function called by core to hang up a PJSIP session.
static void chan_pjsip_pvt_dtor(void *obj)
Definition chan_pjsip.c:83
static struct topology_change_refresh_data * topology_change_refresh_data_alloc(struct ast_sip_session *session, const struct ast_stream_topology *topology)
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
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.
Definition chan_pjsip.c:180
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.
static struct ast_custom_function chan_pjsip_dial_contacts_function
static int send_topology_change_refresh(void *data)
static void clear_session_and_channel_locked(struct ast_sip_session *session, struct ast_channel *ast)
Clear a channel from a session along with its PVT (channel lock held)
static int indicate(void *data)
static int remote_send_hold(void *data)
Update local hold state to be held.
static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
static struct ao2_container * pjsip_uids_onhold
static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Function called to query options on a channel.
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.
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition chan_pjsip.c:110
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition chan_pjsip.c:592
static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
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.
static int uid_hold_hash_fn(const void *obj, const int flags)
static struct ast_sip_session_supplement pbx_start_supplement
static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit)
Function called by core to start a DTMF digit.
static struct ast_custom_function chan_pjsip_parse_uri_from_function
static struct ast_sip_session_supplement chan_pjsip_prack_supplement
Definition chan_pjsip.c:173
static void chan_pjsip_session_begin(struct ast_sip_session *session)
SIP session interaction functions.
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
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 struct rtp_direct_media_data * rtp_direct_media_data_create(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, const struct ast_format_cap *cap, struct ast_sip_session *session)
Definition chan_pjsip.c:474
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
static void transport_info_destroy(void *obj)
Destructor function for transport_info_data.
Definition chan_pjsip.c:262
static int send_direct_media_request(void *data)
Definition chan_pjsip.c:493
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.
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition chan_pjsip.c:584
static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
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.
Definition chan_pjsip.c:224
static pj_status_t transport_info_on_tx_request(pjsip_tx_data *tdata)
Store transport information for outgoing PJSIP session requests.
Definition chan_pjsip.c:320
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.
Definition chan_pjsip.c:403
static int transfer(void *data)
static const char channel_type[]
Definition chan_pjsip.c:79
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
static int hangup(void *data)
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
static void sendtext_data_destroy(void *obj)
static struct ast_custom_function moh_passthrough_function
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.
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
static int answer(void *data)
Definition chan_pjsip.c:793
static int transmit_info_dtmf(void *data)
static struct ast_custom_function media_offer_function
static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *f)
static int compatible_formats_exist(struct ast_stream_topology *top, struct ast_format_cap *cap)
Determine if a topology is compatible with format capabilities.
Definition chan_pjsip.c:624
static void hangup_data_destroy(void *obj)
static int load_module(void)
Load the module.
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition chan_pjsip.c:165
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 struct ast_custom_function transfer_handling_function
#define UNIQUEID_BUFSIZE
Definition chan_pjsip.c:77
static int call(void *data)
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
static struct ast_custom_function chan_pjsip_parse_uri_function
static void transfer_refer(struct ast_sip_session *session, const char *target)
static int unload_module(void)
Unload the PJSIP channel from Asterisk.
static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
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.
Definition chan_pjsip.c:935
static unsigned int chan_idx
Definition chan_pjsip.c:81
static void indicate_data_destroy(void *obj)
static struct ast_custom_function session_refresh_function
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.
Definition chan_pjsip.c:876
static const char * chan_pjsip_get_uniqueid(struct ast_channel *ast)
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
static int chan_pjsip_answer(struct ast_channel *ast)
Function called by core when we should answer a PJSIP session.
Definition chan_pjsip.c:837
static void info_dtmf_data_destroy(void *obj)
static int chan_pjsip_add_hold(const char *chan_uid)
Add a channel ID to the list of PJSIP channels on hold.
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
static int is_colp_update_allowed(struct ast_sip_session *session)
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 struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition chan_pjsip.c:156
static struct ast_frame * chan_pjsip_read_stream(struct ast_channel *ast)
Function called by core to read any waiting frames.
Definition chan_pjsip.c:949
static void set_sipdomain_variable(struct ast_sip_session *session)
static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Function called by core to change the underlying owner channel.
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.
Definition chan_pjsip.c:645
static struct ast_sip_session_supplement call_pickup_supplement
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 struct ast_custom_function dtmf_mode_function
PJSIP Channel Driver shared data structures.
General Asterisk PBX channel definitions.
struct ao2_iterator ast_channel_dialed_causes_iterator(const struct ast_channel *chan)
Retrieve an iterator for dialed cause information.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_tech_hangupcause(const struct ast_channel *chan)
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
#define AST_EXTENDED_FDS
Definition channel.h:197
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.
Definition channel.c:10676
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.
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.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
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.
Definition channel.c:5511
void ast_channel_tech_hangupcause_set(struct ast_channel *chan, int value)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2540
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition channel.c:1182
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition channel.c:1808
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
int ast_channel_fdno(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition channel.h:2983
struct ast_trans_pvt * ast_channel_readtrans(const struct ast_channel *chan)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
ast_t38_state
Possible T38 states on channels.
Definition channel.h:898
@ T38_STATE_UNAVAILABLE
Definition channel.h:899
@ T38_STATE_UNKNOWN
Definition channel.h:900
@ T38_STATE_REJECTED
Definition channel.h:902
@ T38_STATE_NEGOTIATED
Definition channel.h:903
@ T38_STATE_NEGOTIATING
Definition channel.h:901
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition channel.c:571
struct ast_trans_pvt * ast_channel_writetrans(const struct ast_channel *chan)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition channel.c:1289
#define ast_channel_ref(c)
Increase channel reference count.
Definition channel.h:3008
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
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.
Definition channel.c:1296
@ AST_ADSI_UNAVAILABLE
Definition channel.h:891
#define AST_CHANNEL_INITIALIZERS_VERSION
struct ABI version
Definition channel.h:620
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition channel.c:10725
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
#define ast_channel_alloc_with_initializers(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, endpoint, initializers,...)
Definition channel.h:1307
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.
Definition channel.c:2498
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
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.
Definition channel.c:4368
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define AST_CHANNEL_NAME
Definition channel.h:173
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 ...
Definition channel.c:540
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3019
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
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.
Definition channel.c:1752
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition channel.c:2009
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition channel.c:2845
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition channel.c:2417
@ AST_CHAN_TP_SEND_TEXT_DATA
Channels have this property if they implement send_text_data.
Definition channel.h:995
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition channel.h:980
@ AST_CHAN_TP_CREATESJITTER
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition channel.h:985
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.
Definition channel.c:5547
void ast_channel_zone_set(struct ast_channel *chan, struct ast_tone_zone *value)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
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.
Definition channel.c:9282
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition channel.h:2984
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
void pjsip_channel_info_register(void)
Register the channel information session supplement.
void pjsip_channel_info_unregister(void)
Unregister the channel information session supplement.
void pjsip_channel_info_update(struct ast_sip_session *session)
Refresh channel information under the channel lock.
int pjsip_channel_info_create(struct ast_channel *chan, struct ast_sip_session *session)
Create channel-owned PJSIP information before channel publication.
Channel-locked PJSIP information interface.
ast_channel_state
ast_channel states
@ AST_STATE_RING
@ AST_STATE_RINGING
@ AST_STATE_DOWN
@ AST_STATE_UP
@ AST_STATE_RESERVED
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition channel.c:7422
Standard Command Line Interface.
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
void pjsip_channel_cli_unregister(void)
Unregisters the channel cli commands.
PJSIP CLI functions header file.
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
@ AST_MEDIA_TYPE_UNKNOWN
Definition codec.h:31
@ AST_MEDIA_TYPE_VIDEO
Definition codec.h:33
@ AST_MEDIA_TYPE_IMAGE
Definition codec.h:34
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition codec.c:348
@ AST_DEVSTATE_CACHABLE
Definition devicestate.h:70
void ast_devstate_aggregate_add(struct ast_devstate_aggregate *agg, enum ast_device_state state)
Add a device state to the aggregate device state.
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.
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
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.
ast_device_state
Device States.
Definition devicestate.h:52
@ AST_DEVICE_UNKNOWN
Definition devicestate.h:53
@ AST_DEVICE_ONHOLD
Definition devicestate.h:61
@ AST_DEVICE_INVALID
Definition devicestate.h:57
@ AST_DEVICE_BUSY
Definition devicestate.h:56
@ AST_DEVICE_NOT_INUSE
Definition devicestate.h:54
@ AST_DEVICE_UNAVAILABLE
Definition devicestate.h:58
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.
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.
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 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_transfer_handling_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_TRANSFER_HANDLING function write callback.
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.
int pjsip_app_hangup(struct ast_channel *chan, const char *data)
PJSIPHangup Dialplan App.
int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
PJSIP_MOH_PASSTHROUGH function write callback.
int pjsip_action_hangup(struct mansession *s, const struct message *m)
PJSIPHangup Manager Action.
int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
CHANNEL function read callback.
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.
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.
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.
PJSIP dialplan functions header file.
Convenient Signal Processing routines.
void ast_dsp_free(struct ast_dsp *dsp)
Definition dsp.c:1968
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,...
Definition dsp.c:1683
#define DSP_FEATURE_FAX_DETECT
Definition dsp.h:29
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition dsp.c:1962
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition dsp.c:1953
char * end
Definition eagi_proxy.c:73
char buf[BUFSIZE]
Definition eagi_proxy.c:66
@ AST_ENDPOINT_OFFLINE
Definition endpoints.h:55
@ AST_ENDPOINT_ONLINE
Definition endpoints.h:57
struct ast_endpoint_snapshot * ast_endpoint_get_snapshot(struct ast_endpoint *endpoint)
Gets the latest snapshot of the given endpoint.
Generic File Format Support. Should be included by clients of the file handling routines....
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition format.c:201
@ AST_FORMAT_CMP_NOT_EQUAL
Definition format.h:38
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
Media Format Cache API.
struct ast_format * ast_format_h264
Built-in cached h264 format.
struct ast_format * ast_format_h265
Built-in cached h265 format.
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition format_cap.c:752
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition format_cap.c:216
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:408
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition format_cap.c:425
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition format_cap.c:531
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition format_cap.c:589
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition format_cap.c:269
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:742
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition format_cap.c:695
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition format_cap.c:661
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:403
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_logic.c:185
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition manager.c:7782
#define SCOPE_EXIT_RTN(...)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define SCOPE_ENTER_TASK(level, indent,...)
#define ast_trace(level,...)
#define ast_trace_get_indent()
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,...
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
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.
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.
struct ast_msg_data * ast_msg_data_dup(struct ast_msg_data *msg)
Clone an ast_msg_data structure.
@ AST_MSG_DATA_ATTR_BODY
Definition message.h:458
@ AST_MSG_DATA_ATTR_TO
Definition message.h:455
@ AST_MSG_DATA_ATTR_FROM
Definition message.h:456
@ AST_MSG_DATA_ATTR_CONTENT_TYPE
Definition message.h:457
@ AST_MSG_DATA_SOURCE_TYPE_UNKNOWN
Definition message.h:447
#define ast_sip_push_task(serializer, sip_task, task_data)
Definition res_pjsip.h:2126
#define ast_sip_push_task_wait_serializer(serializer, sip_task, task_data)
Definition res_pjsip.h:2221
#define ast_sip_push_task_wait_servant(serializer, sip_task, task_data)
Definition res_pjsip.h:2165
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
Definition main/app.c:3163
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
@ AST_T38_REQUEST_PARMS
#define AST_FRAME_DTMF
@ AST_TRANSFER_FAILED
@ AST_TRANSFER_SUCCESS
#define ast_frfree(fr)
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.
Definition main/frame.c:406
#define AST_OPTION_T38_STATE
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_T38_PARAMETERS
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_STREAM_TOPOLOGY_CHANGED
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_TRANSFER
@ AST_CONTROL_FLASH
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_MASQUERADE_NOTIFY
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
struct ast_frame ast_null_frame
Definition main/frame.c:79
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_NOTICE
#define LOG_WARNING
Tone Indication Support.
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Asterisk locking-related definitions:
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition lock.h:764
static struct ao2_container * endpoints
#define EVENT_FLAG_SYSTEM
Definition manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition manager.h:193
#define EVENT_FLAG_CALL
Definition manager.h:76
Out-of-call text message support.
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition module.h:331
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition module.h:557
@ AST_MODPRI_CHANNEL_DRIVER
Definition module.h:341
@ AST_MODULE_SUPPORT_CORE
Definition module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition pbx_app.c:404
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition module.h:640
Music on hold handling.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition channel.c:7802
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition channel.c:7812
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition netsock2.h:127
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition netsock2.h:138
Core PBX routines and definitions.
@ AST_PBX_FAILED
Definition pbx.h:374
@ AST_PBX_CALL_LIMIT
Definition pbx.h:375
@ AST_PBX_SUCCESS
Definition pbx.h:373
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition pbx.c:2735
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.
#define ast_custom_function_register(acf)
Register a custom function.
Definition pbx.h:1563
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition pbx.c:3268
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.
Definition pbx.c:5251
Call Pickup API.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition pickup.c:202
static int cdata(void *userdata, int state, const char *cdata, size_t len)
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
const char * method
Definition res_pjsip.c:1277
void ast_sip_unregister_service(pjsip_module *module)
Definition res_pjsip.c:127
unsigned int ast_sip_get_allow_sending_180_after_183(void)
Retrieve the global setting 'allow_sending_180_after_183'.
struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
Retrieve the first bound contact from a list of AORs.
Definition location.c:304
struct ao2_container * ast_sip_get_endpoints(void)
Retrieve any endpoints available to sorcery.
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition res_pjsip.c:111
const int ast_sip_hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition res_pjsip.c:3570
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition res_pjsip.h:739
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition res_pjsip.c:518
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition res_pjsip.h:3413
@ AST_SIP_SUPPLEMENT_PRIORITY_LAST
Definition res_pjsip.h:3415
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition res_pjsip.c:2221
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
Definition res_pjsip.c:2022
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition res_pjsip.c:2095
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting 'disable multi domain'.
@ AST_SIP_DTMF_NONE
Definition res_pjsip.h:549
@ AST_SIP_DTMF_AUTO_INFO
Definition res_pjsip.h:560
@ AST_SIP_DTMF_AUTO
Definition res_pjsip.h:558
@ AST_SIP_DTMF_INBAND
Definition res_pjsip.h:554
@ AST_SIP_DTMF_INFO
Definition res_pjsip.h:556
@ AST_SIP_DTMF_RFC_4733
Definition res_pjsip.h:552
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition res_pjsip.c:1433
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition res_pjsip.c:2051
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition res_pjsip.c:3516
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE
Definition res_pjsip.h:724
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING
Definition res_pjsip.h:732
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING
Definition res_pjsip.h:728
ast_sip_session_refresh_method
Definition res_pjsip.h:715
@ AST_SIP_SESSION_REFRESH_METHOD_UPDATE
Definition res_pjsip.h:719
@ AST_SIP_SESSION_REFRESH_METHOD_INVITE
Definition res_pjsip.h:717
struct ast_sip_session * ast_sip_dialog_get_session(pjsip_dialog *dlg)
Retrieves a session from a dialog.
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
@ T38_PEER_REINVITE
@ T38_LOCAL_REINVITE
@ T38_REJECTED
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
@ AST_SIP_SESSION_AFTER_MEDIA
@ AST_SIP_SESSION_BEFORE_MEDIA
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
#define ast_sip_session_register_supplement(supplement)
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)
Reset a media state to a clean state.
int ast_sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
Send a reinvite or UPDATE on a session.
struct ast_sip_session * ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
Create a new outgoing SIP session.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
static struct @523 args
#define NULL
Definition resample.c:96
Pluggable RTP Architecture.
#define AST_RTP_RTCP_PSFB
Definition rtp_engine.h:329
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.
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
@ AST_RTP_DTMF_MODE_INBAND
Definition rtp_engine.h:157
@ AST_RTP_DTMF_MODE_NONE
Definition rtp_engine.h:153
ast_rtp_glue_result
Definition rtp_engine.h:161
@ AST_RTP_GLUE_RESULT_LOCAL
Definition rtp_engine.h:167
@ AST_RTP_GLUE_RESULT_REMOTE
Definition rtp_engine.h:165
@ AST_RTP_GLUE_RESULT_FORBID
Definition rtp_engine.h:163
#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.
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
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.
Definition rtp_engine.c:756
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition rtp_engine.c:619
@ AST_RTP_PROPERTY_RTCP
Definition rtp_engine.h:126
void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
Set the channel that owns this RTP instance.
Definition rtp_engine.c:604
#define ast_rtp_glue_register(glue)
Definition rtp_engine.h:905
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition rtp_engine.c:418
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917
Endpoint abstractions.
Media Stream API.
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.
Definition stream.c:939
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition stream.c:791
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition stream.c:768
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition stream.c:746
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...
Definition stream.c:851
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition stream.c:933
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition stream.c:330
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition stream.c:670
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition strings.c:238
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition strings.h:1259
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition strings.h:87
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition strings.h:1189
#define ast_str_alloca(init_len)
Definition strings.h:848
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
struct ast_sip_session * session
Definition chan_pjsip.c:789
unsigned long indent
Definition chan_pjsip.c:790
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
Structure to pass both assignedid values to channel drivers.
Definition channel.h:606
Helper struct for initializing additional channel information on channel creation.
Definition channel.h:615
uint32_t version
struct ABI version
Definition channel.h:625
const ast_string_field uniqueid
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
enum ast_channel_state state
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
struct ast_format_cap * capabilities
Definition channel.h:652
const char *const type
Definition channel.h:649
Main Channel structure associated with a channel.
char exten[AST_MAX_EXTENSION]
const char * data
enum ast_control_t38 request_response
Data structure associated with a custom dialplan function.
Definition pbx.h:118
const char * name
Definition pbx.h:119
Structure for a data store type.
Definition datastore.h:31
const char * type
Definition datastore.h:32
Structure for a data store object.
Definition datastore.h:64
You shouldn't care about the contents of this struct.
enum ast_device_state state
A snapshot of an endpoint's state.
Configuration relating to call pickup.
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
Definition of a media format.
Definition format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@237 data
enum ast_msg_data_attribute_type type
Definition message.h:463
Structure used to transport a message through the frame core.
struct ast_party_id id
Caller party ID.
Definition channel.h:422
int ani2
Automatic Number Identification 2 (Info Digits)
Definition channel.h:435
Connected Line/Party information.
Definition channel.h:458
struct ast_party_dialed::@218 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition channel.h:388
Information needed to identify an endpoint in a call.
Definition channel.h:340
struct ast_party_number number
Subscriber phone number.
Definition channel.h:344
unsigned char valid
TRUE if the number information is valid/present.
Definition channel.h:299
const char * type
Definition rtp_engine.h:780
SIP body description.
Definition res_pjsip.h:2501
const char * type
Definition res_pjsip.h:2503
const char * body_text
Definition res_pjsip.h:2507
const char * subtype
Definition res_pjsip.h:2505
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
Contact associated with an address of record.
Definition res_pjsip.h:392
const ast_string_field uri
Definition res_pjsip.h:414
struct ast_sip_endpoint * endpoint
Definition res_pjsip.h:424
struct ast_sip_media_rtp_configuration rtp
Definition res_pjsip.h:1019
struct ast_sip_direct_media_configuration direct_media
Definition res_pjsip.h:1021
struct ast_sip_t38_configuration t38
Definition res_pjsip.h:1023
An entity with which Asterisk communicates.
Definition res_pjsip.h:1067
const ast_string_field aors
Definition res_pjsip.h:1096
struct ast_sip_endpoint_media_configuration media
Definition res_pjsip.h:1100
unsigned int inband_progress
Definition res_pjsip.h:1122
enum ast_sip_session_media_encryption encryption
Definition res_pjsip.h:958
Structure which contains read callback information.
ast_sip_session_media_read_cb read_callback
The callback to invoke.
struct ast_sip_session_media * session
The media session.
Structure which contains media state information (streams, sessions)
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
struct ast_sip_session_media_state::@280 sessions
Mapping of stream to media sessions.
A structure containing SIP session media information.
ast_sip_session_media_write_cb write_callback
The write callback when writing frames.
enum ast_media_type type
Media type of this session media.
unsigned int locally_held
Stream is on hold by local side.
int stream_num
The stream number to place into any resulting frames.
struct ast_rtp_instance * rtp
RTP instance itself.
struct ast_sockaddr direct_media_addr
Direct media address.
A supplement to SIP message processing.
struct ast_module *const char * method
A structure describing a SIP session.
struct ast_sip_endpoint * endpoint
enum ast_sip_session_t38state t38state
struct ast_channel * channel
unsigned int moh_passthrough
struct ast_sip_session_media_state * active_media_state
struct pjsip_inv_session * inv_session
enum ast_sip_dtmf_mode dtmf
struct ast_taskprocessor * serializer
Support for dynamic strings.
Definition strings.h:623
A set of tones for a given locale.
Definition indications.h:74
Structure for variables, used for configurations and for channel variables.
The PJSIP channel driver pvt, stored in the ast_sip_channel_pvt data structure.
Definition chan_pjsip.h:42
struct ast_channel * chan
void * frame_data
struct ast_sip_session * session
unsigned int duration
struct ast_sip_session * session
Number structure.
struct ast_sip_session * session
struct ast_stream_topology * topology
struct ast_sip_session * session
const char * dest
struct ast_sip_session * session
Definition chan_pjsip.c:460
struct ast_rtp_instance * vrtp
Definition chan_pjsip.c:458
struct ast_channel * chan
Definition chan_pjsip.c:456
struct ast_rtp_instance * rtp
Definition chan_pjsip.c:457
struct ast_format_cap * cap
Definition chan_pjsip.c:459
struct ast_msg_data * msg
struct ast_sip_session * session
struct ast_sip_session * session
struct ast_sip_session_media_state * media_state
struct ast_sip_session * session
Transport information stored in transport_info datastore.
Definition chan_pjsip.h:30
pj_sockaddr local_addr
Our address that received the request.
Definition chan_pjsip.h:34
pj_sockaddr remote_addr
The address that sent the request.
Definition chan_pjsip.h:32
An API for managing task processing threads that can be shared across modules.
Test Framework API.
#define ast_test_suite_event_notify(s, f,...)
Definition test.h:189
Definitions to aid in the use of thread local storage.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Support for translation of data formats. translate.c.
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.
Definition translate.c:1145
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981
#define ast_assert(a)
Definition utils.h:779
#define ARRAY_LEN(a)
Definition utils.h:706
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:637
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:708
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition vector.h:696