Asterisk - The Open Source Telephony Project GIT-master-97770a9
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
74
76#define UNIQUEID_BUFSIZE 256
77
78static const char channel_type[] = "PJSIP";
79
80static unsigned int chan_idx;
81
82static void chan_pjsip_pvt_dtor(void *obj)
83{
84}
85
86/*! \brief Asterisk core interaction functions */
87static 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);
89 struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids,
90 const struct ast_channel *requestor, const char *data, int *cause);
91static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg);
92static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text);
93static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit);
94static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
95static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeout);
96static int chan_pjsip_hangup(struct ast_channel *ast);
97static int chan_pjsip_answer(struct ast_channel *ast);
98static struct ast_frame *chan_pjsip_read_stream(struct ast_channel *ast);
99static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *f);
100static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f);
101static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
102static int chan_pjsip_transfer(struct ast_channel *ast, const char *target);
103static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
104static int chan_pjsip_devicestate(const char *data);
105static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
106static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast);
107
108/*! \brief PBX interface structure for channel registration */
111 .description = "PJSIP Channel Driver",
112 .requester = chan_pjsip_request,
113 .requester_with_stream_topology = chan_pjsip_request_with_stream_topology,
114 .send_text = chan_pjsip_sendtext,
115 .send_text_data = chan_pjsip_sendtext_data,
116 .send_digit_begin = chan_pjsip_digit_begin,
117 .send_digit_end = chan_pjsip_digit_end,
118 .call = chan_pjsip_call,
119 .hangup = chan_pjsip_hangup,
120 .answer = chan_pjsip_answer,
121 .read_stream = chan_pjsip_read_stream,
122 .write = chan_pjsip_write,
123 .write_stream = chan_pjsip_write_stream,
124 .exception = chan_pjsip_read_stream,
125 .indicate = chan_pjsip_indicate,
126 .transfer = chan_pjsip_transfer,
127 .fixup = chan_pjsip_fixup,
128 .devicestate = chan_pjsip_devicestate,
129 .queryoption = chan_pjsip_queryoption,
130 .func_channel_read = pjsip_acf_channel_read,
131 .get_pvt_uniqueid = chan_pjsip_get_uniqueid,
133};
134
135/*! \brief SIP session interaction functions */
138static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
139static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
140static void chan_pjsip_incoming_response_update_cause(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
141
142/*! \brief SIP session supplement structure */
144 .method = "INVITE",
146 .session_begin = chan_pjsip_session_begin,
147 .session_end = chan_pjsip_session_end,
148 .incoming_request = chan_pjsip_incoming_request,
149 .incoming_response = chan_pjsip_incoming_response,
150 /* It is important that this supplement runs after media has been negotiated */
151 .response_priority = AST_SIP_SESSION_AFTER_MEDIA,
152};
153
154/*! \brief SIP session supplement structure just for responses */
156 .method = "INVITE",
160};
161
162static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
163
165 .method = "ACK",
167 .incoming_request = chan_pjsip_incoming_ack,
168};
169
170static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
171
173 .method = "PRACK",
175 .incoming_request = chan_pjsip_incoming_prack,
176};
177
178/*! \brief Function called by RTP engine to get local audio RTP peer */
180{
181 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
182 struct ast_sip_endpoint *endpoint;
183 struct ast_datastore *datastore;
184 struct ast_sip_session_media *media;
185
186 if (!channel || !channel->session) {
188 }
189
190 /* XXX Getting the first RTP instance for direct media related stuff seems just
191 * absolutely wrong. But the native RTP bridge knows no other method than single-stream
192 * for direct media. So this is the best we can do.
193 */
195 if (!media || !media->rtp) {
197 }
198
199 datastore = ast_sip_session_get_datastore(channel->session, "t38");
200 if (datastore) {
201 ao2_ref(datastore, -1);
203 }
204
205 endpoint = channel->session->endpoint;
206
207 *instance = media->rtp;
208 ao2_ref(*instance, +1);
209
210 ast_assert(endpoint != NULL);
213 }
214
215 if (endpoint->media.direct_media.enabled) {
217 }
218
220}
221
222/*! \brief Function called by RTP engine to get local video RTP peer */
224{
225 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
226 struct ast_sip_endpoint *endpoint;
227 struct ast_sip_session_media *media;
228
229 if (!channel || !channel->session) {
231 }
232
234 if (!media || !media->rtp) {
236 }
237
238 endpoint = channel->session->endpoint;
239
240 *instance = media->rtp;
241 ao2_ref(*instance, +1);
242
243 ast_assert(endpoint != NULL);
246 }
247
249}
250
251/*! \brief Function called by RTP engine to get peer capabilities */
252static void chan_pjsip_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
253{
254 SCOPE_ENTER(1, "%s Native formats %s\n", ast_channel_name(chan),
258}
259
260/*! \brief Destructor function for \ref transport_info_data */
261static void transport_info_destroy(void *obj)
262{
263 struct transport_info_data *data = obj;
264 ast_free(data);
265}
266
267/*! \brief Datastore used to store local/remote addresses for the
268 * INVITE request that created the PJSIP channel */
270 .type = "chan_pjsip_transport_info",
271 .destroy = transport_info_destroy,
272};
273
275
277{
278 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
279
280 if (session->endpoint->media.direct_media.glare_mitigation ==
282 return 0;
283 }
284
285 datastore = ast_sip_session_get_datastore(session, "direct_media_glare_mitigation");
286 if (!datastore) {
287 return 0;
288 }
289
290 /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
291 ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation");
292
293 if ((session->endpoint->media.direct_media.glare_mitigation ==
295 session->inv_session->role == PJSIP_ROLE_UAC) ||
296 (session->endpoint->media.direct_media.glare_mitigation ==
298 session->inv_session->role == PJSIP_ROLE_UAS)) {
299 return 1;
300 }
301
302 return 0;
303}
304
305/*! \brief Helper function to find the position for RTCP */
307{
308 int index;
309
310 for (index = 0; index < AST_VECTOR_SIZE(&session->active_media_state->read_callbacks); ++index) {
311 struct ast_sip_session_media_read_callback_state *callback_state =
312 AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, index);
313
314 if (callback_state->fd != ast_rtp_instance_fd(rtp, 1)) {
315 continue;
316 }
317
318 return index;
319 }
320
321 return -1;
322}
323
324/*!
325 * \pre chan is locked
326 */
327static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
328 struct ast_sip_session_media *media, struct ast_sip_session *session)
329{
330 int changed = 0, position = -1;
331
332 if (media->rtp) {
333 position = rtp_find_rtcp_fd_position(session, media->rtp);
334 }
335
336 if (rtp) {
338 if (media->rtp) {
339 if (position != -1) {
340 ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, -1);
341 }
343 }
344 } else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
346 changed = 1;
347 if (media->rtp) {
349 if (position != -1) {
350 ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1));
351 }
352 }
353 }
354
355 return changed;
356}
357
364};
365
366static void rtp_direct_media_data_destroy(void *data)
367{
368 struct rtp_direct_media_data *cdata = data;
369
370 ao2_cleanup(cdata->session);
371 ao2_cleanup(cdata->cap);
372 ao2_cleanup(cdata->vrtp);
373 ao2_cleanup(cdata->rtp);
374 ao2_cleanup(cdata->chan);
375}
376
378 struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp,
379 const struct ast_format_cap *cap, struct ast_sip_session *session)
380{
382
383 if (!cdata) {
384 return NULL;
385 }
386
387 cdata->chan = ao2_bump(chan);
388 cdata->rtp = ao2_bump(rtp);
389 cdata->vrtp = ao2_bump(vrtp);
390 cdata->cap = ao2_bump((struct ast_format_cap *)cap);
391 cdata->session = ao2_bump(session);
392
393 return cdata;
394}
395
396static int send_direct_media_request(void *data)
397{
398 struct rtp_direct_media_data *cdata = data;
399 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(cdata->chan);
400 struct ast_sip_session *session;
401 int changed = 0;
402 int res = 0;
403
404 /* XXX In an ideal world each media stream would be direct, but for now preserve behavior
405 * and connect only the default media sessions for audio and video.
406 */
407
408 /* The channel needs to be locked when checking for RTP changes.
409 * Otherwise, we could end up destroying an underlying RTCP structure
410 * at the same time that the channel thread is attempting to read RTCP
411 */
412 ast_channel_lock(cdata->chan);
413 session = channel->session;
414 if (session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
415 changed |= check_for_rtp_changes(
416 cdata->chan, cdata->rtp, session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO], session);
417 }
418 if (session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO]) {
419 changed |= check_for_rtp_changes(
420 cdata->chan, cdata->vrtp, session->active_media_state->default_session[AST_MEDIA_TYPE_VIDEO], session);
421 }
423
424 if (direct_media_mitigate_glare(cdata->session)) {
425 ast_debug(4, "Disregarding setting RTP on %s: mitigating re-INVITE glare\n", ast_channel_name(cdata->chan));
426 ao2_ref(cdata, -1);
427 return 0;
428 }
429
430 if (cdata->cap && ast_format_cap_count(cdata->cap) &&
431 !ast_format_cap_identical(cdata->session->direct_media_cap, cdata->cap)) {
433 ast_format_cap_append_from_cap(cdata->session->direct_media_cap, cdata->cap, AST_MEDIA_TYPE_UNKNOWN);
434 changed = 1;
435 }
436
437 if (changed) {
438 ast_debug(4, "RTP changed on %s; initiating direct media update\n", ast_channel_name(cdata->chan));
439 res = ast_sip_session_refresh(cdata->session, NULL, NULL, NULL,
440 cdata->session->endpoint->media.direct_media.method, 1, NULL);
441 }
442
443 ao2_ref(cdata, -1);
444 return res;
445}
446
447/*! \brief Function called by RTP engine to change where the remote party should send media */
448static int chan_pjsip_set_rtp_peer(struct ast_channel *chan,
449 struct ast_rtp_instance *rtp,
450 struct ast_rtp_instance *vrtp,
451 struct ast_rtp_instance *tpeer,
452 const struct ast_format_cap *cap,
453 int nat_active)
454{
455 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
456 struct ast_sip_session *session = channel->session;
458 SCOPE_ENTER(1, "%s %s\n", ast_channel_name(chan),
460
461 /* Don't try to do any direct media shenanigans on early bridges */
462 if ((rtp || vrtp || tpeer) && !ast_channel_is_bridged(chan)) {
463 ast_debug(4, "Disregarding setting RTP on %s: channel is not bridged\n", ast_channel_name(chan));
464 SCOPE_EXIT_RTN_VALUE(0, "Channel not bridged\n");
465 }
466
467 if (nat_active && session->endpoint->media.direct_media.disable_on_nat) {
468 ast_debug(4, "Disregarding setting RTP on %s: NAT is active\n", ast_channel_name(chan));
469 SCOPE_EXIT_RTN_VALUE(0, "NAT is active\n");
470 }
471
473 if (!cdata) {
475 }
476
478 ast_log(LOG_ERROR, "Unable to send direct media request for channel %s\n", ast_channel_name(chan));
479 ao2_ref(cdata, -1);
480 }
481
483}
484
485/*! \brief Local glue for interacting with the RTP engine core */
487 .type = "PJSIP",
488 .get_rtp_info = chan_pjsip_get_rtp_peer,
489 .get_vrtp_info = chan_pjsip_get_vrtp_peer,
490 .get_codec = chan_pjsip_get_codec,
491 .update_peer = chan_pjsip_set_rtp_peer,
492};
493
495 const char *channel_id)
496{
497 int i;
498
499 for (i = 0; i < AST_VECTOR_SIZE(&session->active_media_state->sessions); ++i) {
500 struct ast_sip_session_media *session_media;
501
502 session_media = AST_VECTOR_GET(&session->active_media_state->sessions, i);
503 if (!session_media || !session_media->rtp) {
504 continue;
505 }
506
507 ast_rtp_instance_set_channel_id(session_media->rtp, channel_id);
508 }
509}
510
511/*!
512 * \brief Determine if a topology is compatible with format capabilities
513 *
514 * This will return true if ANY formats in the topology are compatible with the format
515 * capabilities.
516 *
517 * XXX When supporting true multistream, we will need to be sure to mark which streams from
518 * top1 are compatible with which streams from top2. Then the ones that are not compatible
519 * will need to be marked as "removed" so that they are negotiated as expected.
520 *
521 * \param top Topology
522 * \param cap Format capabilities
523 * \retval 1 The topology has at least one compatible format
524 * \retval 0 The topology has no compatible formats or an error occurred.
525 */
527{
528 struct ast_format_cap *cap_from_top;
529 int res;
530 SCOPE_ENTER(1, "Topology: %s Formats: %s\n",
533
534 cap_from_top = ast_stream_topology_get_formats(top);
535
536 if (!cap_from_top) {
537 SCOPE_EXIT_RTN_VALUE(0, "Topology had no formats\n");
538 }
539
540 res = ast_format_cap_iscompatible(cap_from_top, cap);
541 ao2_ref(cap_from_top, -1);
542
543 SCOPE_EXIT_RTN_VALUE(res, "Compatible? %s\n", res ? "yes" : "no");
544}
545
546/*! \brief Function called to create a new PJSIP Asterisk channel */
547static 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)
548{
549 struct ast_channel *chan;
550 struct ast_format_cap *caps;
551 RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup);
552 struct ast_sip_channel_pvt *channel;
553 struct ast_variable *var;
554 struct ast_stream_topology *topology;
555 struct ast_channel_initializers initializers = {
557 .tenantid = session->endpoint->tenantid,
558 };
560
562 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt\n");
563 }
564
566 S_COR(session->id.number.valid, session->id.number.str, ""),
567 S_COR(session->id.name.valid, session->id.name.str, ""),
568 session->endpoint->accountcode,
569 exten, session->endpoint->context,
570 assignedids, requestor, 0,
571 session->endpoint->persistent, &initializers, "PJSIP/%s-%08x",
573 (unsigned) ast_atomic_fetchadd_int((int *) &chan_idx, +1));
574 if (!chan) {
575 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
576 }
577
579
580 if (!(channel = ast_sip_channel_pvt_alloc(pvt, session))) {
581 ast_channel_unlock(chan);
582 ast_hangup(chan);
583 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create pvt channel\n");
584 }
585
586 ast_channel_tech_pvt_set(chan, channel);
587
588 if (!ast_stream_topology_get_count(session->pending_media_state->topology) ||
589 !compatible_formats_exist(session->pending_media_state->topology, session->endpoint->media.codecs)) {
591 if (!caps) {
592 ast_channel_unlock(chan);
593 ast_hangup(chan);
594 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create caps\n");
595 }
596 ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, AST_MEDIA_TYPE_UNKNOWN);
597 topology = ast_stream_topology_clone(session->endpoint->media.topology);
598 } else {
599 caps = ast_stream_topology_get_formats(session->pending_media_state->topology);
600 topology = ast_stream_topology_clone(session->pending_media_state->topology);
601 }
602
603 if (!topology || !caps) {
604 ao2_cleanup(caps);
605 ast_stream_topology_free(topology);
606 ast_channel_unlock(chan);
607 ast_hangup(chan);
608 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't get caps or clone topology\n");
609 }
610
612
614 ast_channel_set_stream_topology(chan, topology);
615
616 if (!ast_format_cap_empty(caps)) {
617 struct ast_format *fmt;
618
620 if (!fmt) {
621 /* Since our capabilities aren't empty, this will succeed */
622 fmt = ast_format_cap_get_format(caps, 0);
623 }
628 ao2_ref(fmt, -1);
629 }
630
631 ao2_ref(caps, -1);
632
633 if (state == AST_STATE_RING) {
634 ast_channel_rings_set(chan, 1);
635 }
636
638
641 ast_channel_caller(chan)->ani2 = session->ani2;
642
643 if (!ast_strlen_zero(exten)) {
644 /* Set provided DNID on the new channel. */
645 ast_channel_dialed(chan)->number.str = ast_strdup(exten);
646 }
647
649
650 ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
651 ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup);
652
653 ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups);
654 ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups);
655
656 if (!ast_strlen_zero(session->endpoint->language)) {
657 ast_channel_language_set(chan, session->endpoint->language);
658 }
659
660 if (!ast_strlen_zero(session->endpoint->zone)) {
661 struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
662 if (!zone) {
663 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
664 }
665 ast_channel_zone_set(chan, zone);
666 }
667
668 for (var = session->endpoint->channel_vars; var; var = var->next) {
669 char buf[512];
671 var->value, buf, sizeof(buf)));
672 }
673
675 ast_channel_unlock(chan);
676
678
680}
681
684 unsigned long indent;
685};
686
687static int answer(void *data)
688{
689 struct answer_data *ans_data = data;
690 pj_status_t status = PJ_SUCCESS;
691 pjsip_tx_data *packet = NULL;
692 struct ast_sip_session *session = ans_data->session;
694
695 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
696 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
697 session->inv_session->cause,
698 pjsip_get_status_text(session->inv_session->cause)->ptr);
699 SCOPE_EXIT_RTN_VALUE(0, "Disconnected\n");
700 }
701
702 pjsip_dlg_inc_lock(session->inv_session->dlg);
703 if (session->inv_session->invite_tsx) {
704 status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet);
705 } else {
706 ast_log(LOG_ERROR,"Cannot answer '%s' because there is no associated SIP transaction\n",
707 ast_channel_name(session->channel));
708 }
709 pjsip_dlg_dec_lock(session->inv_session->dlg);
710
711 if (status == PJ_SUCCESS && packet) {
713 }
714
715 if (status != PJ_SUCCESS) {
716 char err[PJ_ERR_MSG_SIZE];
717
718 pj_strerror(status, err, sizeof(err));
719 ast_log(LOG_WARNING,"Cannot answer '%s': %s\n",
720 ast_channel_name(session->channel), err);
721 /*
722 * Return this value so we can distinguish between this
723 * failure and the threadpool synchronous push failing.
724 */
725 SCOPE_EXIT_RTN_VALUE(-2, "pjproject failure\n");
726 }
728}
729
730/*! \brief Function called by core when we should answer a PJSIP session */
731static int chan_pjsip_answer(struct ast_channel *ast)
732{
733 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
734 struct ast_sip_session *session;
735 struct answer_data ans_data = { 0, };
736 int res;
737 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
738
739 if (ast_channel_state(ast) == AST_STATE_UP) {
740 SCOPE_EXIT_RTN_VALUE(0, "Already up\n");
741 return 0;
742 }
743
745 session = ao2_bump(channel->session);
746
747 /* the answer task needs to be pushed synchronously otherwise a race condition
748 can occur between this thread and bridging (specifically when native bridging
749 attempts to do direct media) */
751 ans_data.session = session;
752 ans_data.indent = ast_trace_get_indent();
753 res = ast_sip_push_task_wait_serializer(session->serializer, answer, &ans_data);
754 if (res) {
755 if (res == -1) {
756 ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
757 ast_channel_name(session->channel));
758 }
759 ao2_ref(session, -1);
760 ast_channel_lock(ast);
761 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
762 }
763 ao2_ref(session, -1);
764 ast_channel_lock(ast);
765
767}
768
769/*! \brief Internal helper function called when CNG tone is detected */
771 struct ast_frame *f)
772{
773 const char *target_context;
774 int exists;
775 int dsp_features;
776
777 dsp_features = ast_dsp_get_features(session->dsp);
778 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
779 if (dsp_features) {
780 ast_dsp_set_features(session->dsp, dsp_features);
781 } else {
782 ast_dsp_free(session->dsp);
783 session->dsp = NULL;
784 }
785
786 /* If already executing in the fax extension don't do anything */
787 if (!strcmp(ast_channel_exten(ast), "fax")) {
788 return f;
789 }
790
791 target_context = ast_channel_context(ast);
792
793 /*
794 * We need to unlock the channel here because ast_exists_extension has the
795 * potential to start and stop an autoservice on the channel. Such action
796 * is prone to deadlock if the channel is locked.
797 *
798 * ast_async_goto() has its own restriction on not holding the channel lock.
799 */
801 ast_frfree(f);
802 f = &ast_null_frame;
803 exists = ast_exists_extension(ast, target_context, "fax", 1,
804 S_COR(ast_channel_caller(ast)->id.number.valid,
805 ast_channel_caller(ast)->id.number.str, NULL));
806 if (exists) {
807 ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",
808 ast_channel_name(ast));
809 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
810 if (ast_async_goto(ast, target_context, "fax", 1)) {
811 ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",
812 ast_channel_name(ast), target_context);
813 }
814 } else {
815 ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",
816 ast_channel_name(ast), target_context);
817 }
818
819 /* It's possible for a masquerade to have occurred when doing the ast_async_goto resulting in
820 * the channel on the session having changed. Since we need to return with the original channel
821 * locked we lock the channel that was passed in and not session->channel.
822 */
823 ast_channel_lock(ast);
824
825 return f;
826}
827
828/*! \brief Determine if the given frame is in a format we've negotiated */
830{
831 struct ast_stream_topology *topology = session->active_media_state->topology;
832 struct ast_stream *stream = ast_stream_topology_get_stream(topology, f->stream_num);
833 const struct ast_format_cap *cap = ast_stream_get_formats(stream);
834
836}
837
838/*!
839 * \brief Function called by core to read any waiting frames
840 *
841 * \note The channel is already locked.
842 */
844{
845 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
846 struct ast_sip_session *session = channel->session;
847 struct ast_sip_session_media_read_callback_state *callback_state;
848 struct ast_frame *f;
849 int fdno = ast_channel_fdno(ast) - AST_EXTENDED_FDS;
850 struct ast_frame *cur;
851
852 if (fdno >= AST_VECTOR_SIZE(&session->active_media_state->read_callbacks)) {
853 return &ast_null_frame;
854 }
855
856 callback_state = AST_VECTOR_GET_ADDR(&session->active_media_state->read_callbacks, fdno);
857 f = callback_state->read_callback(session, callback_state->session);
858
859 if (!f) {
860 return f;
861 }
862
863 for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
864 if (cur->frametype == AST_FRAME_VOICE) {
865 break;
866 }
867 }
868
869 if (!cur || callback_state->session != session->active_media_state->default_session[callback_state->session->type]) {
870 return f;
871 }
872
873 session = channel->session;
874
875 /*
876 * Asymmetric RTP only has one native format set at a time.
877 * Therefore we need to update the native format to the current
878 * raw read format BEFORE the native format check
879 */
880 if (!session->endpoint->asymmetric_rtp_codec &&
883 struct ast_format_cap *caps;
884
885 /* For maximum compatibility we ensure that the formats match that of the received media */
886 ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
889
891 if (caps) {
896 ao2_ref(caps, -1);
897 }
898
901
902 if (ast_channel_is_bridged(ast)) {
904 }
905 }
906
909 ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when it has not been negotiated\n",
911 ast_frfree(f);
912 return &ast_null_frame;
913 }
914
915 if (session->dsp) {
916 int dsp_features;
917
918 dsp_features = ast_dsp_get_features(session->dsp);
919 if ((dsp_features & DSP_FEATURE_FAX_DETECT)
920 && session->endpoint->faxdetect_timeout
921 && session->endpoint->faxdetect_timeout <= ast_channel_get_up_time(ast)) {
922 dsp_features &= ~DSP_FEATURE_FAX_DETECT;
923 if (dsp_features) {
924 ast_dsp_set_features(session->dsp, dsp_features);
925 } else {
926 ast_dsp_free(session->dsp);
927 session->dsp = NULL;
928 }
929 ast_debug(3, "Channel driver fax CNG detection timeout on %s\n",
930 ast_channel_name(ast));
931 }
932 }
933 if (session->dsp) {
934 f = ast_dsp_process(ast, session->dsp, f);
935 if (f && (f->frametype == AST_FRAME_DTMF)) {
936 if (f->subclass.integer == 'f') {
937 ast_debug(3, "Channel driver fax CNG detected on %s\n",
938 ast_channel_name(ast));
940 /* When chan_pjsip_cng_tone_detected returns it is possible for the
941 * channel pointed to by ast and by session->channel to differ due to a
942 * masquerade. It's best not to touch things after this.
943 */
944 } else {
945 ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,
946 ast_channel_name(ast));
947 }
948 }
949 }
950
951 return f;
952}
953
954static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *frame)
955{
956 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
957 struct ast_sip_session *session = channel->session;
958 struct ast_sip_session_media *media = NULL;
959 int res = 0;
960
961 /* The core provides a guarantee that the stream will exist when we are called if stream_num is provided */
962 if (stream_num >= 0) {
963 /* What is not guaranteed is that a media session will exist */
966 }
967 }
968
969 switch (frame->frametype) {
970 case AST_FRAME_VOICE:
971 if (!media) {
972 return 0;
973 } else if (media->type != AST_MEDIA_TYPE_AUDIO) {
974 ast_debug(3, "Channel %s stream %d is of type '%s', not audio!\n",
976 return 0;
977 } else if (media == channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO] &&
980 struct ast_str *write_transpath = ast_str_alloca(256);
981 struct ast_str *read_transpath = ast_str_alloca(256);
982
984 "Channel %s asked to send %s frame when native formats are %s (rd:%s->%s;%s wr:%s->%s;%s)\n",
985 ast_channel_name(ast),
993 ast_translate_path_to_str(ast_channel_writetrans(ast), &write_transpath));
994 return 0;
995 } else if (media->write_callback) {
996 res = media->write_callback(session, media, frame);
997
998 }
999 break;
1000 case AST_FRAME_VIDEO:
1001 if (!media) {
1002 return 0;
1003 } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1004 ast_debug(3, "Channel %s stream %d is of type '%s', not video!\n",
1005 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1006 return 0;
1007 } else if (media->write_callback) {
1008 res = media->write_callback(session, media, frame);
1009 }
1010 break;
1011 case AST_FRAME_MODEM:
1012 if (!media) {
1013 return 0;
1014 } else if (media->type != AST_MEDIA_TYPE_IMAGE) {
1015 ast_debug(3, "Channel %s stream %d is of type '%s', not image!\n",
1016 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1017 return 0;
1018 } else if (media->write_callback) {
1019 res = media->write_callback(session, media, frame);
1020 }
1021 break;
1022 case AST_FRAME_CNG:
1023 break;
1024 case AST_FRAME_RTCP:
1025 /* We only support writing out feedback */
1026 if (frame->subclass.integer != AST_RTP_RTCP_PSFB || !media) {
1027 return 0;
1028 } else if (media->type != AST_MEDIA_TYPE_VIDEO) {
1029 ast_debug(3, "Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n",
1030 ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type));
1031 return 0;
1032 } else if (media->write_callback) {
1033 res = media->write_callback(session, media, frame);
1034 }
1035 break;
1036 default:
1037 ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
1038 break;
1039 }
1040
1041 return res;
1042}
1043
1044static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *frame)
1045{
1046 return chan_pjsip_write_stream(ast, -1, frame);
1047}
1048
1049/*! \brief Function called by core to change the underlying owner channel */
1050static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1051{
1052 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(newchan);
1053
1054 if (channel->session->channel != oldchan) {
1055 return -1;
1056 }
1057
1058 /*
1059 * The masquerade has suspended the channel's session
1060 * serializer so we can safely change it outside of
1061 * the serializer thread.
1062 */
1063 channel->session->channel = newchan;
1064
1066
1067 return 0;
1068}
1069
1070/*! AO2 hash function for on hold UIDs */
1071static int uid_hold_hash_fn(const void *obj, const int flags)
1072{
1073 const char *key = obj;
1074
1075 switch (flags & OBJ_SEARCH_MASK) {
1076 case OBJ_SEARCH_KEY:
1077 break;
1078 case OBJ_SEARCH_OBJECT:
1079 break;
1080 default:
1081 /* Hash can only work on something with a full key. */
1082 ast_assert(0);
1083 return 0;
1084 }
1085 return ast_str_hash(key);
1086}
1087
1088/*! AO2 sort function for on hold UIDs */
1089static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
1090{
1091 const char *left = obj_left;
1092 const char *right = obj_right;
1093 int cmp;
1094
1095 switch (flags & OBJ_SEARCH_MASK) {
1096 case OBJ_SEARCH_OBJECT:
1097 case OBJ_SEARCH_KEY:
1098 cmp = strcmp(left, right);
1099 break;
1101 cmp = strncmp(left, right, strlen(right));
1102 break;
1103 default:
1104 /* Sort can only work on something with a full or partial key. */
1105 ast_assert(0);
1106 cmp = 0;
1107 break;
1108 }
1109 return cmp;
1110}
1111
1113
1114/*!
1115 * \brief Add a channel ID to the list of PJSIP channels on hold
1116 *
1117 * \param chan_uid - Unique ID of the channel being put into the hold list
1118 *
1119 * \retval 0 Channel has been added to or was already in the hold list
1120 * \retval -1 Failed to add channel to the hold list
1121 */
1122static int chan_pjsip_add_hold(const char *chan_uid)
1123{
1124 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1125
1126 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1127 if (hold_uid) {
1128 /* Device is already on hold. Nothing to do. */
1129 return 0;
1130 }
1131
1132 /* Device wasn't in hold list already. Create a new one. */
1133 hold_uid = ao2_alloc_options(strlen(chan_uid) + 1, NULL,
1135 if (!hold_uid) {
1136 return -1;
1137 }
1138
1139 ast_copy_string(hold_uid, chan_uid, strlen(chan_uid) + 1);
1140
1141 if (ao2_link(pjsip_uids_onhold, hold_uid) == 0) {
1142 return -1;
1143 }
1144
1145 return 0;
1146}
1147
1148/*!
1149 * \brief Remove a channel ID from the list of PJSIP channels on hold
1150 *
1151 * \param chan_uid - Unique ID of the channel being taken out of the hold list
1152 */
1153static void chan_pjsip_remove_hold(const char *chan_uid)
1154{
1156}
1157
1158/*!
1159 * \brief Determine whether a channel ID is in the list of PJSIP channels on hold
1160 *
1161 * \param chan_uid - Channel being checked
1162 *
1163 * \retval 0 The channel is not in the hold list
1164 * \retval 1 The channel is in the hold list
1165 */
1166static int chan_pjsip_get_hold(const char *chan_uid)
1167{
1168 RAII_VAR(char *, hold_uid, NULL, ao2_cleanup);
1169
1170 hold_uid = ao2_find(pjsip_uids_onhold, chan_uid, OBJ_SEARCH_KEY);
1171 if (!hold_uid) {
1172 return 0;
1173 }
1174
1175 return 1;
1176}
1177
1178/*! \brief Function called to get the device state of an endpoint */
1179static int chan_pjsip_devicestate(const char *data)
1180{
1181 RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
1183 RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
1184 struct ast_devstate_aggregate aggregate;
1185 int num, inuse = 0;
1186
1187 if (!endpoint) {
1188 return AST_DEVICE_INVALID;
1189 }
1190
1191 endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
1192 ast_endpoint_get_resource(endpoint->persistent));
1193
1194 if (!endpoint_snapshot) {
1195 return AST_DEVICE_INVALID;
1196 }
1197
1198 if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
1200 } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
1202 }
1203
1204 if (!endpoint_snapshot->num_channels) {
1205 return state;
1206 }
1207
1208 ast_devstate_aggregate_init(&aggregate);
1209
1210 for (num = 0; num < endpoint_snapshot->num_channels; num++) {
1211 struct ast_channel_snapshot *snapshot;
1212
1213 snapshot = ast_channel_snapshot_get_latest(endpoint_snapshot->channel_ids[num]);
1214 if (!snapshot) {
1215 continue;
1216 }
1217
1218 if (chan_pjsip_get_hold(snapshot->base->uniqueid)) {
1220 } else {
1221 ast_devstate_aggregate_add(&aggregate, ast_state_chan2dev(snapshot->state));
1222 }
1223
1224 if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
1225 (snapshot->state == AST_STATE_BUSY)) {
1226 inuse++;
1227 }
1228
1229 ao2_ref(snapshot, -1);
1230 }
1231
1232 if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
1234 } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
1236 }
1237
1238 return state;
1239}
1240
1241/*! \brief Function called to query options on a channel */
1242static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
1243{
1244 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1245 int res = -1;
1247
1248 if (!channel) {
1249 return -1;
1250 }
1251
1252 switch (option) {
1254 if (channel->session->endpoint->media.t38.enabled) {
1255 switch (channel->session->t38state) {
1256 case T38_LOCAL_REINVITE:
1257 case T38_PEER_REINVITE:
1259 break;
1260 case T38_ENABLED:
1262 break;
1263 case T38_REJECTED:
1265 break;
1266 default:
1268 break;
1269 }
1270 }
1271
1272 *((enum ast_t38_state *) data) = state;
1273 res = 0;
1274
1275 break;
1276 default:
1277 break;
1278 }
1279
1280 return res;
1281}
1282
1283static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast)
1284{
1285 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1287
1288 if (!channel || !uniqueid) {
1289 return "";
1290 }
1291
1292 ast_copy_pj_str(uniqueid, &channel->session->inv_session->dlg->call_id->id, UNIQUEID_BUFSIZE);
1293
1294 return uniqueid;
1295}
1296
1302 size_t datalen;
1303};
1304
1305static void indicate_data_destroy(void *obj)
1306{
1307 struct indicate_data *ind_data = obj;
1308
1309 ast_free(ind_data->frame_data);
1310 ao2_ref(ind_data->session, -1);
1311}
1312
1314 int condition, int response_code, const void *frame_data, size_t datalen)
1315{
1316 struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
1317
1318 if (!ind_data) {
1319 return NULL;
1320 }
1321
1322 ind_data->frame_data = ast_malloc(datalen);
1323 if (!ind_data->frame_data) {
1324 ao2_ref(ind_data, -1);
1325 return NULL;
1326 }
1327
1328 memcpy(ind_data->frame_data, frame_data, datalen);
1329 ind_data->datalen = datalen;
1330 ind_data->condition = condition;
1331 ind_data->response_code = response_code;
1332 ao2_ref(session, +1);
1333 ind_data->session = session;
1334
1335 return ind_data;
1336}
1337
1338static int indicate(void *data)
1339{
1340 pjsip_tx_data *packet = NULL;
1341 struct indicate_data *ind_data = data;
1342 struct ast_sip_session *session = ind_data->session;
1343 int response_code = ind_data->response_code;
1344
1345 if ((session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED) &&
1346 (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS)) {
1348 }
1349
1350 ao2_ref(ind_data, -1);
1351
1352 return 0;
1353}
1354
1355/*! \brief Send SIP INFO with video update request */
1356static int transmit_info_with_vidupdate(void *data)
1357{
1358 const char * xml =
1359 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
1360 " <media_control>\r\n"
1361 " <vc_primitive>\r\n"
1362 " <to_encoder>\r\n"
1363 " <picture_fast_update/>\r\n"
1364 " </to_encoder>\r\n"
1365 " </vc_primitive>\r\n"
1366 " </media_control>\r\n";
1367
1368 const struct ast_sip_body body = {
1369 .type = "application",
1370 .subtype = "media_control+xml",
1371 .body_text = xml
1372 };
1373
1374 RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
1375 struct pjsip_tx_data *tdata;
1376
1377 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1378 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1379 session->inv_session->cause,
1380 pjsip_get_status_text(session->inv_session->cause)->ptr);
1381 return -1;
1382 }
1383
1384 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
1385 ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
1386 return -1;
1387 }
1388 if (ast_sip_add_body(tdata, &body)) {
1389 ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
1390 return -1;
1391 }
1393
1394 return 0;
1395}
1396
1397/*!
1398 * \internal
1399 * \brief TRUE if a COLP update can be sent to the peer.
1400 * \since 13.3.0
1401 *
1402 * \param session The session to see if the COLP update is allowed.
1403 *
1404 * \retval 0 Update is not allowed.
1405 * \retval 1 Update is allowed.
1406 */
1408{
1409 struct ast_party_id connected_id;
1410 int update_allowed = 0;
1411
1412 if (!session->endpoint->id.send_connected_line
1413 || (!session->endpoint->id.send_pai && !session->endpoint->id.send_rpid)) {
1414 return 0;
1415 }
1416
1417 /*
1418 * Check if privacy allows the update. Check while the channel
1419 * is locked so we can work with the shallow connected_id copy.
1420 */
1421 ast_channel_lock(session->channel);
1422 connected_id = ast_channel_connected_effective_id(session->channel);
1423 if (connected_id.number.valid
1424 && (session->endpoint->id.trust_outbound
1426 update_allowed = 1;
1427 }
1428 ast_channel_unlock(session->channel);
1429
1430 return update_allowed;
1431}
1432
1433/*! \brief Update connected line information */
1435{
1436 struct ast_sip_session *session = data;
1437
1438 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
1439 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
1440 session->inv_session->cause,
1441 pjsip_get_status_text(session->inv_session->cause)->ptr);
1442 ao2_ref(session, -1);
1443 return -1;
1444 }
1445
1446 if (ast_channel_state(session->channel) == AST_STATE_UP
1447 || session->inv_session->role == PJSIP_ROLE_UAC) {
1450 int generate_new_sdp;
1451
1452 method = session->endpoint->id.refresh_method;
1453 if (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE) {
1455 }
1456
1457 /* Only the INVITE method actually needs SDP, UPDATE can do without */
1458 generate_new_sdp = (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE);
1459
1460 ast_sip_session_refresh(session, NULL, NULL, NULL, method, generate_new_sdp, NULL);
1461 }
1462 } else if (session->endpoint->id.rpid_immediate
1463 && session->inv_session->state != PJSIP_INV_STATE_DISCONNECTED
1465 int response_code = 0;
1466
1467 if (ast_channel_state(session->channel) == AST_STATE_RING) {
1468 response_code = !session->endpoint->inband_progress ? 180 : 183;
1469 } else if (ast_channel_state(session->channel) == AST_STATE_RINGING) {
1470 response_code = 183;
1471 }
1472
1473 if (response_code) {
1474 struct pjsip_tx_data *packet = NULL;
1475
1476 if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
1478 }
1479 }
1480 }
1481
1482 ao2_ref(session, -1);
1483 return 0;
1484}
1485
1486/*! \brief Update local hold state and send a re-INVITE with the new SDP */
1487static int remote_send_hold_refresh(struct ast_sip_session *session, unsigned int held)
1488{
1489 struct ast_sip_session_media *session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
1490 if (session_media) {
1491 session_media->locally_held = held;
1492 }
1494 ao2_ref(session, -1);
1495
1496 return 0;
1497}
1498
1499/*! \brief Update local hold state to be held */
1500static int remote_send_hold(void *data)
1501{
1502 return remote_send_hold_refresh(data, 1);
1503}
1504
1505/*! \brief Update local hold state to be unheld */
1506static int remote_send_unhold(void *data)
1507{
1508 return remote_send_hold_refresh(data, 0);
1509}
1510
1514};
1515
1517{
1519
1522}
1523
1525 struct ast_sip_session *session, const struct ast_stream_topology *topology)
1526{
1528
1529 refresh_data = ast_calloc(1, sizeof(*refresh_data));
1530 if (!refresh_data) {
1531 return NULL;
1532 }
1533
1536 if (!refresh_data->media_state) {
1538 return NULL;
1539 }
1540 refresh_data->media_state->topology = ast_stream_topology_clone(topology);
1541 if (!refresh_data->media_state->topology) {
1543 return NULL;
1544 }
1545
1546 return refresh_data;
1547}
1548
1549static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
1550{
1551 SCOPE_ENTER(3, "%s: Received response code %d. PT: %s AT: %s\n", ast_sip_session_get_name(session),
1552 rdata->msg_info.msg->line.status.code,
1553 ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP)),
1554 ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP)));
1555
1556
1557 if (PJSIP_IS_STATUS_IN_CLASS(rdata->msg_info.msg->line.status.code, 200)) {
1558 /* The topology was changed to something new so give notice to what requested
1559 * it so it queries the channel and updates accordingly.
1560 */
1561 if (session->channel) {
1563 SCOPE_EXIT_RTN_VALUE(0, "%s: Queued topology change frame\n", ast_sip_session_get_name(session));
1564 }
1565 SCOPE_EXIT_RTN_VALUE(0, "%s: No channel? Can't queue topology change frame\n", ast_sip_session_get_name(session));
1566 } else if (300 <= rdata->msg_info.msg->line.status.code) {
1567 /* The topology change failed, so drop the current pending media state */
1568 ast_sip_session_media_state_reset(session->pending_media_state);
1569 SCOPE_EXIT_RTN_VALUE(0, "%s: response code > 300. Resetting pending media state\n", ast_sip_session_get_name(session));
1570 }
1571
1572 SCOPE_EXIT_RTN_VALUE(0, "%s: Nothing to do\n", ast_sip_session_get_name(session));
1573}
1574
1575static int send_topology_change_refresh(void *data)
1576{
1581 int ret;
1583 ast_str_tmp(256, ast_stream_topology_to_str(refresh_data->media_state->topology, &STR_TMP)));
1584
1585 /* See RFC 6337, especially section 3.2: If the early media SDP was sent reliably, we are allowed
1586 * to send UPDATEs. Only relevant for AST_STATE_RINGING and AST_STATE_RING - if the channel is UP,
1587 * re-INVITES can be sent.
1588 */
1589 if (session->early_confirmed && (state == AST_STATE_RINGING || state == AST_STATE_RING)) {
1591 }
1592
1594 method, 1, refresh_data->media_state);
1595 refresh_data->media_state = NULL;
1597
1599}
1600
1602 const struct ast_stream_topology *proposed)
1603{
1605 int res;
1606 SCOPE_ENTER(1);
1607
1609 if (!refresh_data) {
1610 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create refresh_data\n");
1611 }
1612
1614 if (res) {
1616 }
1617 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
1618}
1619
1620/* Forward declarations */
1621static int transmit_info_dtmf(void *data);
1622static struct info_dtmf_data *info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration);
1623
1624/*! \brief Function called by core to ask the channel to indicate some sort of condition */
1625static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
1626{
1627 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
1628 struct ast_sip_session_media *media;
1629 int response_code = 0;
1630 int res = 0;
1631 char *device_buf;
1632 size_t device_buf_size;
1633 int i;
1634 const struct ast_stream_topology *topology;
1635 struct ast_frame f = {
1637 .subclass = {
1638 .integer = condition
1639 },
1640 .datalen = datalen,
1641 .data.ptr = (void *)data,
1642 };
1643 char condition_name[256];
1644 unsigned int duration;
1645 char digit;
1646 struct info_dtmf_data *dtmf_data;
1647
1648 SCOPE_ENTER(3, "%s: Indicated %s\n", ast_channel_name(ast),
1649 ast_frame_subclass2str(&f, condition_name, sizeof(condition_name), NULL, 0));
1650
1651 switch (condition) {
1653 if (ast_channel_state(ast) == AST_STATE_RING) {
1654 if (channel->session->endpoint->inband_progress ||
1655 (channel->session->inv_session && channel->session->inv_session->neg &&
1656 pjmedia_sdp_neg_get_state(channel->session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE)) {
1657 res = -1;
1659 response_code = 180;
1660 } else {
1661 response_code = 183;
1662 }
1663 } else {
1664 response_code = 180;
1665 }
1666 } else {
1667 res = -1;
1668 }
1670 break;
1671 case AST_CONTROL_BUSY:
1672 if (ast_channel_state(ast) != AST_STATE_UP) {
1673 response_code = 486;
1674 } else {
1675 res = -1;
1676 }
1677 break;
1679 if (ast_channel_state(ast) != AST_STATE_UP) {
1680 response_code = 503;
1681 } else {
1682 res = -1;
1683 }
1684 break;
1686 if (ast_channel_state(ast) != AST_STATE_UP) {
1687 response_code = 484;
1688 } else {
1689 res = -1;
1690 }
1691 break;
1693 if (ast_channel_state(ast) != AST_STATE_UP) {
1694 response_code = 100;
1695 } else {
1696 res = -1;
1697 }
1698 break;
1700 if (ast_channel_state(ast) != AST_STATE_UP) {
1701 response_code = 183;
1702 } else {
1703 res = -1;
1704 }
1706 break;
1707 case AST_CONTROL_FLASH:
1708 duration = 300;
1709 digit = '!';
1710 dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
1711
1712 if (!dtmf_data) {
1713 res = -1;
1714 break;
1715 }
1716
1717 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
1718 ast_log(LOG_WARNING, "Error sending FLASH via INFO on channel %s\n", ast_channel_name(ast));
1719 ao2_ref(dtmf_data, -1); /* dtmf_data can't be null here */
1720 res = -1;
1721 }
1722 break;
1724 for (i = 0; i < AST_VECTOR_SIZE(&channel->session->active_media_state->sessions); ++i) {
1725 media = AST_VECTOR_GET(&channel->session->active_media_state->sessions, i);
1726 if (!media || media->type != AST_MEDIA_TYPE_VIDEO) {
1727 continue;
1728 }
1729 if (media->rtp) {
1730 /* FIXME: Only use this for VP8. Additional work would have to be done to
1731 * fully support other video codecs */
1732
1736 (channel->session->endpoint->media.webrtc &&
1738 /* FIXME Fake RTP write, this will be sent as an RTCP packet. Ideally the
1739 * RTP engine would provide a way to externally write/schedule RTCP
1740 * packets */
1741 struct ast_frame fr;
1744 res = ast_rtp_instance_write(media->rtp, &fr);
1745 } else {
1746 ao2_ref(channel->session, +1);
1748 ao2_cleanup(channel->session);
1749 }
1750 }
1751 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
1752 } else {
1753 ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
1754 res = -1;
1755 }
1756 }
1757 /* XXX If there were no video streams, then this should set
1758 * res to -1
1759 */
1760 break;
1762 ao2_ref(channel->session, +1);
1764 ao2_cleanup(channel->session);
1765 }
1766 break;
1768 break;
1770 res = -1;
1771 break;
1773 ast_assert(datalen == sizeof(int));
1774 if (*(int *) data) {
1775 /*
1776 * Masquerade is beginning:
1777 * Wait for session serializer to get suspended.
1778 */
1779 ast_channel_unlock(ast);
1781 ast_channel_lock(ast);
1782 } else {
1783 /*
1784 * Masquerade is complete:
1785 * Unsuspend the session serializer.
1786 */
1788 }
1789 break;
1790 case AST_CONTROL_HOLD:
1792 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1793 device_buf = alloca(device_buf_size);
1794 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1796 if (!channel->session->moh_passthrough) {
1797 ast_moh_start(ast, data, NULL);
1798 } else {
1800 ast_log(LOG_WARNING, "Could not queue task to remotely put session '%s' on hold with endpoint '%s'\n",
1802 ao2_ref(channel->session, -1);
1803 }
1804 }
1805 break;
1806 case AST_CONTROL_UNHOLD:
1808 device_buf_size = strlen(ast_channel_name(ast)) + 1;
1809 device_buf = alloca(device_buf_size);
1810 ast_channel_get_device_name(ast, device_buf, device_buf_size);
1812 if (!channel->session->moh_passthrough) {
1813 ast_moh_stop(ast);
1814 } else {
1816 ast_log(LOG_WARNING, "Could not queue task to remotely take session '%s' off hold with endpoint '%s'\n",
1818 ao2_ref(channel->session, -1);
1819 }
1820 }
1821 break;
1823 break;
1825 break;
1827 if (ast_channel_state(ast) != AST_STATE_UP) {
1828 response_code = 181;
1829 } else {
1830 res = -1;
1831 }
1832 break;
1834 res = 0;
1835
1836 if (channel->session->t38state == T38_PEER_REINVITE) {
1837 const struct ast_control_t38_parameters *parameters = data;
1838
1839 if (parameters->request_response == AST_T38_REQUEST_PARMS) {
1841 }
1842 }
1843
1844 break;
1846 topology = data;
1847 ast_trace(-1, "%s: New topology: %s\n", ast_channel_name(ast),
1848 ast_str_tmp(256, ast_stream_topology_to_str(topology, &STR_TMP)));
1849 res = handle_topology_request_change(channel->session, topology);
1850 break;
1852 break;
1854 break;
1855 case -1:
1856 res = -1;
1857 break;
1858 default:
1859 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
1860 res = -1;
1861 break;
1862 }
1863
1864 if (response_code) {
1865 struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
1866
1867 if (!ind_data) {
1868 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
1869 }
1870
1871 if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
1872 ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
1874 ao2_cleanup(ind_data);
1875 res = -1;
1876 }
1877 }
1878
1879 SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_channel_name(ast));
1880}
1881
1884 char *target;
1885};
1886
1887static void transfer_data_destroy(void *obj)
1888{
1889 struct transfer_data *trnf_data = obj;
1890
1891 ast_free(trnf_data->target);
1892 ao2_cleanup(trnf_data->session);
1893}
1894
1896{
1897 struct transfer_data *trnf_data = ao2_alloc(sizeof(*trnf_data), transfer_data_destroy);
1898
1899 if (!trnf_data) {
1900 return NULL;
1901 }
1902
1903 if (!(trnf_data->target = ast_strdup(target))) {
1904 ao2_ref(trnf_data, -1);
1905 return NULL;
1906 }
1907
1908 ao2_ref(session, +1);
1909 trnf_data->session = session;
1910
1911 return trnf_data;
1912}
1913
1914static void transfer_redirect(struct ast_sip_session *session, const char *target)
1915{
1916 pjsip_tx_data *packet;
1918 pjsip_contact_hdr *contact;
1919 pj_str_t tmp;
1920
1921 if (pjsip_inv_end_session(session->inv_session, 302, NULL, &packet) != PJ_SUCCESS
1922 || !packet) {
1923 ast_log(LOG_WARNING, "Failed to redirect PJSIP session for channel %s\n",
1924 ast_channel_name(session->channel));
1927
1928 return;
1929 }
1930
1931 if (!(contact = pjsip_msg_find_hdr(packet->msg, PJSIP_H_CONTACT, NULL))) {
1932 contact = pjsip_contact_hdr_create(packet->pool);
1933 }
1934
1935 pj_strdup2_with_null(packet->pool, &tmp, target);
1936 if (!(contact->uri = pjsip_parse_uri(packet->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR))) {
1937 ast_log(LOG_WARNING, "Failed to parse destination URI '%s' for channel %s\n",
1938 target, ast_channel_name(session->channel));
1941 pjsip_tx_data_dec_ref(packet);
1942
1943 return;
1944 }
1945 pjsip_msg_add_hdr(packet->msg, (pjsip_hdr *) contact);
1946
1949}
1950
1951/*! \brief REFER Callback module, used to attach session data structure to subscription */
1952static pjsip_module refer_callback_module = {
1953 .name = { "REFER Callback", 14 },
1954 .id = -1,
1955};
1956
1957/*!
1958 * \brief Callback function to report status of implicit REFER-NOTIFY subscription.
1959 *
1960 * This function will be called on any state change in the REFER-NOTIFY subscription.
1961 * Its primary purpose is to report SUCCESS/FAILURE of a transfer initiated via
1962 * \ref transfer_refer as well as to terminate the subscription, if necessary.
1963 */
1964static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
1965{
1966 struct ast_channel *chan;
1968 int res = 0;
1969
1970 if (!event) {
1971 return;
1972 }
1973
1974 chan = pjsip_evsub_get_mod_data(sub, refer_callback_module.id);
1975 if (!chan) {
1976 return;
1977 }
1978
1979 if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACCEPTED) {
1980 /* Check if subscription is suppressed and terminate and send completion code, if so. */
1981 pjsip_rx_data *rdata;
1982 pjsip_generic_string_hdr *refer_sub;
1983 const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
1984
1985 ast_debug(3, "Transfer accepted on channel %s\n", ast_channel_name(chan));
1986
1987 /* Check if response message */
1988 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1989 rdata = event->body.tsx_state.src.rdata;
1990
1991 /* Find Refer-Sub header */
1992 refer_sub = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &REFER_SUB, NULL);
1993
1994 /* Check if subscription is suppressed. If it is, the far end will not terminate it,
1995 * and the subscription will remain active until it times out. Terminating it here
1996 * eliminates the unnecessary timeout.
1997 */
1998 if (refer_sub && !pj_stricmp2(&refer_sub->hvalue, "false")) {
1999 /* Since no subscription is desired, assume that call has been transferred successfully. */
2000 /* Channel reference will be released at end of function */
2001 /* Terminate subscription. */
2002 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2003 pjsip_evsub_terminate(sub, PJ_TRUE);
2004 res = -1;
2005 }
2006 }
2007 } else if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE ||
2008 pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
2009 /* Check for NOTIFY complete or error. */
2010 pjsip_msg *msg;
2011 pjsip_msg_body *body;
2012 pjsip_status_line status_line = { .code = 0 };
2013 pj_bool_t is_last;
2014 pj_status_t status;
2015
2016 if (event->type == PJSIP_EVENT_TSX_STATE && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
2017 pjsip_rx_data *rdata;
2018
2019 rdata = event->body.tsx_state.src.rdata;
2020 msg = rdata->msg_info.msg;
2021
2022 if (msg->type == PJSIP_REQUEST_MSG) {
2023 if (!pjsip_method_cmp(&msg->line.req.method, pjsip_get_notify_method())) {
2024 body = msg->body;
2025 if (body && !pj_stricmp2(&body->content_type.type, "message")
2026 && !pj_stricmp2(&body->content_type.subtype, "sipfrag")) {
2027 pjsip_parse_status_line((char *)body->data, body->len, &status_line);
2028 }
2029 }
2030 } else {
2031 status_line.code = msg->line.status.code;
2032 status_line.reason = msg->line.status.reason;
2033 }
2034 } else {
2035 status_line.code = 500;
2036 status_line.reason = *pjsip_get_status_text(500);
2037 }
2038
2039 is_last = (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED);
2040 /* If the status code is >= 200, the subscription is finished. */
2041 if (status_line.code >= 200 || is_last) {
2042 res = -1;
2043
2044 /* If the subscription has terminated, return AST_TRANSFER_SUCCESS for 2XX.
2045 * Return AST_TRANSFER_FAILED for any code < 200.
2046 * Otherwise, return the status code.
2047 * The subscription should not terminate for any code < 200,
2048 * but if it does, that constitutes a failure. */
2049 if (status_line.code < 200) {
2051 } else if (status_line.code >= 300) {
2052 message = status_line.code;
2053 }
2054
2055 /* If subscription not terminated and subscription is finished (status code >= 200)
2056 * terminate it */
2057 if (!is_last) {
2058 pjsip_tx_data *tdata;
2059
2060 status = pjsip_evsub_initiate(sub, pjsip_get_subscribe_method(), 0, &tdata);
2061 if (status == PJ_SUCCESS) {
2062 pjsip_evsub_send_request(sub, tdata);
2063 }
2064 }
2065 /* Finished. Remove session from subscription */
2066 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2067 ast_debug(3, "Transfer channel %s completed: %d %.*s (%s)\n",
2068 ast_channel_name(chan),
2069 status_line.code,
2070 (int)status_line.reason.slen, status_line.reason.ptr,
2071 (message == AST_TRANSFER_SUCCESS) ? "Success" : "Failure");
2072 }
2073 }
2074
2075 if (res) {
2077 ao2_ref(chan, -1);
2078 }
2079}
2080
2081static void transfer_refer(struct ast_sip_session *session, const char *target)
2082{
2083 pjsip_evsub *sub;
2085 pj_str_t tmp;
2086 pjsip_tx_data *packet;
2087 const char *ref_by_val;
2088 char local_info[pj_strlen(&session->inv_session->dlg->local.info_str) + 1];
2089 struct pjsip_evsub_user xfer_cb;
2090 struct ast_channel *chan = session->channel;
2091
2092 pj_bzero(&xfer_cb, sizeof(xfer_cb));
2093 xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
2094
2095 if (pjsip_xfer_create_uac(session->inv_session->dlg, &xfer_cb, &sub) != PJ_SUCCESS) {
2098
2099 return;
2100 }
2101
2102 /* refer_callback_module requires a reference to chan
2103 * which will be released in xfer_client_on_evsub_state()
2104 * when the implicit REFER subscription terminates */
2105 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, chan);
2106 ao2_ref(chan, +1);
2107
2108 if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
2109 goto failure;
2110 }
2111
2112 ref_by_val = pbx_builtin_getvar_helper(chan, "SIPREFERREDBYHDR");
2113 if (!ast_strlen_zero(ref_by_val)) {
2114 ast_sip_add_header(packet, "Referred-By", ref_by_val);
2115 } else {
2116 ast_copy_pj_str(local_info, &session->inv_session->dlg->local.info_str, sizeof(local_info));
2117 ast_sip_add_header(packet, "Referred-By", local_info);
2118 }
2119
2120 if (pjsip_xfer_send_request(sub, packet) == PJ_SUCCESS) {
2121 return;
2122 }
2123
2124failure:
2127 pjsip_evsub_set_mod_data(sub, refer_callback_module.id, NULL);
2128 pjsip_evsub_terminate(sub, PJ_FALSE);
2129
2130 ao2_ref(chan, -1);
2131}
2132
2133static int transfer(void *data)
2134{
2135 struct transfer_data *trnf_data = data;
2136 struct ast_sip_endpoint *endpoint = NULL;
2137 struct ast_sip_contact *contact = NULL;
2138 const char *target = trnf_data->target;
2139
2140 if (trnf_data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2141 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2142 trnf_data->session->inv_session->cause,
2143 pjsip_get_status_text(trnf_data->session->inv_session->cause)->ptr);
2144 } else {
2145 /* See if we have an endpoint; if so, use its contact */
2147 if (endpoint) {
2149 if (contact && !ast_strlen_zero(contact->uri)) {
2150 target = contact->uri;
2151 }
2152 }
2153
2154 if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
2155 transfer_redirect(trnf_data->session, target);
2156 } else {
2157 transfer_refer(trnf_data->session, target);
2158 }
2159 }
2160
2161 ao2_ref(trnf_data, -1);
2163 ao2_cleanup(contact);
2164 return 0;
2165}
2166
2167/*! \brief Function called by core for Asterisk initiated transfer */
2168static int chan_pjsip_transfer(struct ast_channel *chan, const char *target)
2169{
2170 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2171 struct transfer_data *trnf_data = transfer_data_alloc(channel->session, target);
2172
2173 if (!trnf_data) {
2174 return -1;
2175 }
2176
2177 if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
2178 ast_log(LOG_WARNING, "Error requesting transfer\n");
2179 ao2_cleanup(trnf_data);
2180 return -1;
2181 }
2182
2183 return 0;
2184}
2185
2186/*! \brief Function called by core to start a DTMF digit */
2187static int chan_pjsip_digit_begin(struct ast_channel *chan, char digit)
2188{
2189 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2190 struct ast_sip_session_media *media;
2191
2193
2194 switch (channel->session->dtmf) {
2196 if (!media || !media->rtp) {
2197 return 0;
2198 }
2199
2201 break;
2202 case AST_SIP_DTMF_AUTO:
2203 if (!media || !media->rtp) {
2204 return 0;
2205 }
2206
2208 return -1;
2209 }
2210
2212 break;
2214 if (!media || !media->rtp || (ast_rtp_instance_dtmf_mode_get(media->rtp) == AST_RTP_DTMF_MODE_NONE)) {
2215 return 0;
2216 }
2218 break;
2219 case AST_SIP_DTMF_NONE:
2220 break;
2222 return -1;
2223 default:
2224 break;
2225 }
2226
2227 return 0;
2228}
2229
2232 char digit;
2233 unsigned int duration;
2234};
2235
2236static void info_dtmf_data_destroy(void *obj)
2237{
2238 struct info_dtmf_data *dtmf_data = obj;
2239 ao2_ref(dtmf_data->session, -1);
2240}
2241
2243{
2244 struct info_dtmf_data *dtmf_data = ao2_alloc(sizeof(*dtmf_data), info_dtmf_data_destroy);
2245 if (!dtmf_data) {
2246 return NULL;
2247 }
2248 ao2_ref(session, +1);
2249 dtmf_data->session = session;
2250 dtmf_data->digit = digit;
2251 dtmf_data->duration = duration;
2252 return dtmf_data;
2253}
2254
2255static int transmit_info_dtmf(void *data)
2256{
2257 RAII_VAR(struct info_dtmf_data *, dtmf_data, data, ao2_cleanup);
2258
2259 struct ast_sip_session *session = dtmf_data->session;
2260 struct pjsip_tx_data *tdata;
2261
2262 RAII_VAR(struct ast_str *, body_text, NULL, ast_free_ptr);
2263
2264 struct ast_sip_body body = {
2265 .type = "application",
2266 .subtype = "dtmf-relay",
2267 };
2268
2269 if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2270 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2271 session->inv_session->cause,
2272 pjsip_get_status_text(session->inv_session->cause)->ptr);
2273 return -1;
2274 }
2275
2276 if (!(body_text = ast_str_create(32))) {
2277 ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
2278 return -1;
2279 }
2280 ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
2281
2283
2284 if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
2285 ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
2286 return -1;
2287 }
2288 if (ast_sip_add_body(tdata, &body)) {
2289 ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
2290 pjsip_tx_data_dec_ref(tdata);
2291 return -1;
2292 }
2294
2295 return 0;
2296}
2297
2298/*! \brief Function called by core to stop a DTMF digit */
2299static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
2300{
2301 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2302 struct ast_sip_session_media *media;
2303
2304 if (!channel || !channel->session) {
2305 /* This happens when the channel is hungup while a DTMF digit is playing. See ASTERISK-28086 */
2306 ast_debug(3, "Channel %s disappeared while calling digit_end\n", ast_channel_name(ast));
2307 return -1;
2308 }
2309
2311
2312 switch (channel->session->dtmf) {
2314 {
2315 if (!media || !media->rtp) {
2316 return 0;
2317 }
2318
2320 ast_debug(3, "Told to send end of digit on Auto-Info channel %s RFC4733 negotiated so using it.\n", ast_channel_name(ast));
2322 break;
2323 }
2324 /* If RFC_4733 was not negotiated, fail through to the DTMF_INFO processing */
2325 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));
2326 }
2327
2328 case AST_SIP_DTMF_INFO:
2329 {
2330 struct info_dtmf_data *dtmf_data = info_dtmf_data_alloc(channel->session, digit, duration);
2331
2332 if (!dtmf_data) {
2333 return -1;
2334 }
2335
2336 if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
2337 ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
2338 ao2_cleanup(dtmf_data);
2339 return -1;
2340 }
2341 break;
2342 }
2344 if (!media || !media->rtp) {
2345 return 0;
2346 }
2347
2349 break;
2350 case AST_SIP_DTMF_AUTO:
2351 if (!media || !media->rtp) {
2352 return 0;
2353 }
2354
2356 return -1;
2357 }
2358
2360 break;
2361 case AST_SIP_DTMF_NONE:
2362 break;
2364 return -1;
2365 }
2366
2367 return 0;
2368}
2369
2371{
2373
2374 /*
2375 * Use the channel CALLERID() as the initial connected line data.
2376 * The core or a predial handler may have supplied missing values
2377 * from the session->endpoint->id.self about who we are calling.
2378 */
2379 ast_channel_lock(session->channel);
2381 ast_channel_unlock(session->channel);
2382
2383 /* Supply initial connected line information if available. */
2384 if (!session->id.number.valid && !session->id.name.valid) {
2385 return;
2386 }
2387
2389 connected.id = session->id;
2391
2393}
2394
2395static int call(void *data)
2396{
2397 struct ast_sip_channel_pvt *channel = data;
2398 struct ast_sip_session *session = channel->session;
2399 pjsip_tx_data *tdata;
2400 int res = 0;
2401 SCOPE_ENTER(1, "%s Topology: %s\n",
2403 ast_str_tmp(256, ast_stream_topology_to_str(channel->session->pending_media_state->topology, &STR_TMP))
2404 );
2405
2406
2408
2409 if (res) {
2410 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2411 ast_queue_hangup(session->channel);
2412 } else {
2416 }
2417 ao2_ref(channel, -1);
2418 SCOPE_EXIT_RTN_VALUE(res, "RC: %d\n", res);
2419}
2420
2421/*! \brief Function called by core to actually start calling a remote party */
2422static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeout)
2423{
2424 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2425 SCOPE_ENTER(1, "%s Topology: %s\n", ast_sip_session_get_name(channel->session),
2427
2428 ao2_ref(channel, +1);
2429 if (ast_sip_push_task(channel->session->serializer, call, channel)) {
2430 ast_log(LOG_WARNING, "Error attempting to place outbound call to '%s'\n", dest);
2431 ao2_cleanup(channel);
2432 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't push task\n");
2433 }
2434
2435 SCOPE_EXIT_RTN_VALUE(0, "'call' task pushed\n");
2436}
2437
2438/*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */
2439static int hangup_cause2sip(int cause)
2440{
2441 switch (cause) {
2442 case AST_CAUSE_UNALLOCATED: /* 1 */
2443 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */
2444 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */
2445 return 404;
2446 case AST_CAUSE_CONGESTION: /* 34 */
2447 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */
2448 return 503;
2449 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
2450 return 408;
2451 case AST_CAUSE_NO_ANSWER: /* 19 */
2452 case AST_CAUSE_UNREGISTERED: /* 20 */
2453 return 480;
2454 case AST_CAUSE_CALL_REJECTED: /* 21 */
2455 return 403;
2456 case AST_CAUSE_NUMBER_CHANGED: /* 22 */
2457 return 410;
2458 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */
2459 return 480;
2461 return 484;
2463 return 486;
2464 case AST_CAUSE_FAILURE:
2465 return 500;
2466 case AST_CAUSE_FACILITY_REJECTED: /* 29 */
2467 return 501;
2469 return 503;
2471 return 502;
2472 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
2473 return 488;
2474 case AST_CAUSE_INTERWORKING: /* Unspecified Interworking issues */
2475 return 500;
2477 default:
2478 ast_debug(1, "AST hangup cause %d (no match found in PJSIP)\n", cause);
2479 return 0;
2480 }
2481
2482 /* Never reached */
2483 return 0;
2484}
2485
2486struct hangup_data {
2489};
2490
2491static void hangup_data_destroy(void *obj)
2492{
2493 struct hangup_data *h_data = obj;
2494
2495 h_data->chan = ast_channel_unref(h_data->chan);
2496}
2497
2499{
2500 struct hangup_data *h_data = ao2_alloc(sizeof(*h_data), hangup_data_destroy);
2501
2502 if (!h_data) {
2503 return NULL;
2504 }
2505
2506 h_data->cause = cause;
2507 h_data->chan = ast_channel_ref(chan);
2508
2509 return h_data;
2510}
2511
2512/*! \brief Clear a channel from a session along with its PVT */
2514{
2515 session->channel = NULL;
2518}
2519
2520static int hangup(void *data)
2521{
2522 struct hangup_data *h_data = data;
2523 struct ast_channel *ast = h_data->chan;
2524 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2525 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2526
2527 /*
2528 * Before cleaning we have to ensure that channel or its session is not NULL
2529 * we have seen rare case when taskprocessor calls hangup but channel is NULL
2530 * due to SIP session timeout and answer happening at the same time
2531 */
2532 if (channel) {
2533 struct ast_sip_session *session = channel->session;
2534 if (session) {
2535 int cause = h_data->cause;
2536
2537 if (channel->session->active_media_state &&
2538 channel->session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
2539 struct ast_sip_session_media *media =
2541 if (media->rtp) {
2543 }
2544 }
2545
2546 /*
2547 * It's possible that session_terminate might cause the session to be destroyed
2548 * immediately so we need to keep a reference to it so we can NULL session->channel
2549 * afterwards.
2550 */
2554 }
2555 ao2_cleanup(channel);
2556 }
2557 ao2_cleanup(h_data);
2559}
2560
2561/*! \brief Function called by core to hang up a PJSIP session */
2562static int chan_pjsip_hangup(struct ast_channel *ast)
2563{
2564 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2565 int cause;
2566 struct hangup_data *h_data;
2567 SCOPE_ENTER(1, "%s\n", ast_channel_name(ast));
2568
2569 if (!channel || !channel->session) {
2570 SCOPE_EXIT_RTN_VALUE(-1, "No channel or session\n");
2571 }
2572
2574 h_data = hangup_data_alloc(cause, ast);
2575
2576 if (!h_data) {
2577 goto failure;
2578 }
2579
2580 if (ast_sip_push_task(channel->session->serializer, hangup, h_data)) {
2581 ast_log(LOG_WARNING, "Unable to push hangup task to the threadpool. Expect bad things\n");
2582 goto failure;
2583 }
2584
2585 SCOPE_EXIT_RTN_VALUE(0, "Cause: %d\n", cause);
2586
2587failure:
2588 /* Go ahead and do our cleanup of the session and channel even if we're not going
2589 * to be able to send our SIP request/response
2590 */
2591 clear_session_and_channel(channel->session, ast);
2592 ao2_cleanup(channel);
2593 ao2_cleanup(h_data);
2594
2595 SCOPE_EXIT_RTN_VALUE(-1, "Cause: %d\n", cause);
2596}
2597
2601 const char *dest;
2603};
2604
2605static int request(void *obj)
2606{
2607 struct request_data *req_data = obj;
2608 struct ast_sip_session *session = NULL;
2609 char *tmp = ast_strdupa(req_data->dest), *endpoint_name = NULL, *request_user = NULL;
2610 struct ast_sip_endpoint *endpoint;
2611
2613 AST_APP_ARG(endpoint);
2614 AST_APP_ARG(aor);
2615 );
2616 SCOPE_ENTER(1, "%s\n",tmp);
2617
2618 if (ast_strlen_zero(tmp)) {
2619 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty destination\n");
2621 SCOPE_EXIT_RTN_VALUE(-1, "Empty destination\n");
2622 }
2623
2625
2627 /* If a request user has been specified extract it from the endpoint name portion */
2628 if ((endpoint_name = strchr(args.endpoint, '@'))) {
2629 request_user = args.endpoint;
2630 *endpoint_name++ = '\0';
2631 } else {
2632 endpoint_name = args.endpoint;
2633 }
2634
2635 if (ast_strlen_zero(endpoint_name)) {
2636 if (request_user) {
2637 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2638 request_user);
2639 } else {
2640 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2641 }
2643 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2644 }
2645 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2646 endpoint_name);
2647 if (!endpoint) {
2648 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2650 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2651 }
2652 } else {
2653 /* First try to find an exact endpoint match, for single (user) or multi-domain (user@domain) */
2654 endpoint_name = args.endpoint;
2655 if (ast_strlen_zero(endpoint_name)) {
2656 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name\n");
2658 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2659 }
2660 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2661 endpoint_name);
2662 if (!endpoint) {
2663 /* It seems it's not a multi-domain endpoint or single endpoint exact match,
2664 * it's possible that it's a SIP trunk with a specified user (user@trunkname),
2665 * so extract the user before @ sign.
2666 */
2667 endpoint_name = strchr(args.endpoint, '@');
2668 if (!endpoint_name) {
2669 /*
2670 * Couldn't find an '@' so it had to be an endpoint
2671 * name that doesn't exist.
2672 */
2673 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n",
2674 args.endpoint);
2676 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2677 }
2678 request_user = args.endpoint;
2679 *endpoint_name++ = '\0';
2680
2681 if (ast_strlen_zero(endpoint_name)) {
2682 ast_log(LOG_ERROR, "Unable to create PJSIP channel with empty endpoint name: %s@<endpoint-name>\n",
2683 request_user);
2685 SCOPE_EXIT_RTN_VALUE(-1, "Empty endpoint name\n");
2686 }
2687
2688 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2689 endpoint_name);
2690 if (!endpoint) {
2691 ast_log(LOG_ERROR, "Unable to create PJSIP channel - endpoint '%s' was not found\n", endpoint_name);
2693 SCOPE_EXIT_RTN_VALUE(-1, "Endpoint not found\n");
2694 }
2695 }
2696 }
2697
2698 session = ast_sip_session_create_outgoing(endpoint, NULL, args.aor, request_user,
2699 req_data->topology);
2700 ao2_ref(endpoint, -1);
2701 if (!session) {
2702 ast_log(LOG_ERROR, "Failed to create outgoing session to endpoint '%s'\n", endpoint_name);
2704 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create session\n");
2705 }
2706
2707 req_data->session = session;
2708
2710}
2711
2712/*! \brief Function called by core to create a new outgoing PJSIP session */
2713static 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)
2714{
2715 struct request_data req_data;
2717 SCOPE_ENTER(1, "%s Topology: %s\n", data,
2719
2720 req_data.topology = topology;
2721 req_data.dest = data;
2722 /* Default failure value in case ast_sip_push_task_wait_servant() itself fails. */
2723 req_data.cause = AST_CAUSE_FAILURE;
2724
2725 if (ast_sip_push_task_wait_servant(NULL, request, &req_data)) {
2726 *cause = req_data.cause;
2727 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't push task\n");
2728 }
2729
2730 session = req_data.session;
2731
2732 if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
2733 /* Session needs to be terminated prematurely */
2734 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create channel\n");
2735 }
2736
2737 SCOPE_EXIT_RTN_VALUE(session->channel, "Channel: %s\n", ast_channel_name(session->channel));
2738}
2739
2740static 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)
2741{
2742 struct ast_stream_topology *topology;
2743 struct ast_channel *chan;
2744
2746 if (!topology) {
2747 return NULL;
2748 }
2749
2750 chan = chan_pjsip_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
2751
2752 ast_stream_topology_free(topology);
2753
2754 return chan;
2755}
2756
2760};
2761
2762static void sendtext_data_destroy(void *obj)
2763{
2764 struct sendtext_data *data = obj;
2765 ao2_cleanup(data->session);
2766 ast_free(data->msg);
2767}
2768
2770 struct ast_msg_data *msg)
2771{
2772 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
2773 struct sendtext_data *data = ao2_alloc(sizeof(*data), sendtext_data_destroy);
2774
2775 if (!data) {
2776 return NULL;
2777 }
2778
2779 data->msg = ast_msg_data_dup(msg);
2780 if (!data->msg) {
2781 ao2_cleanup(data);
2782 return NULL;
2783 }
2784 data->session = channel->session;
2785 ao2_ref(data->session, +1);
2786
2787 return data;
2788}
2789
2790static int sendtext(void *obj)
2791{
2792 struct sendtext_data *data = obj;
2793 pjsip_tx_data *tdata;
2794 const char *body_text = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_BODY);
2795 const char *content_type = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_CONTENT_TYPE);
2796 char *sep;
2797 struct ast_sip_body body = {
2798 .type = "text",
2799 .subtype = "plain",
2800 .body_text = body_text,
2801 };
2802
2803 if (!ast_strlen_zero(content_type)) {
2804 sep = strchr(content_type, '/');
2805 if (sep) {
2806 *sep = '\0';
2807 body.type = content_type;
2808 body.subtype = ++sep;
2809 }
2810 }
2811
2812 if (data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2813 ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
2814 data->session->inv_session->cause,
2815 pjsip_get_status_text(data->session->inv_session->cause)->ptr);
2816 } else {
2817 pjsip_from_hdr *hdr;
2818 pjsip_name_addr *name_addr;
2819 const char *from = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_FROM);
2820 const char *to = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_TO);
2821 int invalidate_tdata = 0;
2822
2823 ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
2824 ast_sip_add_body(tdata, &body);
2825
2826 /*
2827 * If we have a 'from' in the msg, set the display name in the From
2828 * header to it.
2829 */
2830 if (!ast_strlen_zero(from)) {
2831 hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
2832 name_addr = (pjsip_name_addr *) hdr->uri;
2833 pj_strdup2(tdata->pool, &name_addr->display, from);
2834 invalidate_tdata = 1;
2835 }
2836
2837 /*
2838 * If we have a 'to' in the msg, set the display name in the To
2839 * header to it.
2840 */
2841 if (!ast_strlen_zero(to)) {
2842 hdr = PJSIP_MSG_TO_HDR(tdata->msg);
2843 name_addr = (pjsip_name_addr *) hdr->uri;
2844 pj_strdup2(tdata->pool, &name_addr->display, to);
2845 invalidate_tdata = 1;
2846 }
2847
2848 if (invalidate_tdata) {
2849 pjsip_tx_data_invalidate_msg(tdata);
2850 }
2851
2852 ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
2853 }
2854
2855 ao2_cleanup(data);
2856
2857 return 0;
2858}
2859
2860/*! \brief Function called by core to send text on PJSIP session */
2861static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
2862{
2863 struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
2864 struct sendtext_data *data = sendtext_data_create(ast, msg);
2865
2866 ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
2869 ast_channel_name(ast),
2871
2872 if (!data) {
2873 return -1;
2874 }
2875
2876 if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
2877 ao2_ref(data, -1);
2878 return -1;
2879 }
2880 return 0;
2881}
2882
2883static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
2884{
2885 struct ast_msg_data *msg;
2886 int rc;
2887 struct ast_msg_data_attribute attrs[] =
2888 {
2889 {
2891 .value = (char *)text,
2892 }
2893 };
2894
2896 if (!msg) {
2897 return -1;
2898 }
2899 rc = chan_pjsip_sendtext_data(ast, msg);
2900 ast_free(msg);
2901
2902 return rc;
2903}
2904
2906{
2907 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2909
2910 if (session->endpoint->media.direct_media.glare_mitigation ==
2912 SCOPE_EXIT_RTN("Direct media no glare mitigation\n");
2913 }
2914
2916 "direct_media_glare_mitigation");
2917
2918 if (!datastore) {
2919 SCOPE_EXIT_RTN("Couldn't create datastore\n");
2920 }
2921
2924}
2925
2926/*! \brief Function called when the session ends */
2928{
2930
2931 if (!session->channel) {
2932 SCOPE_EXIT_RTN("No channel\n");
2933 }
2934
2935
2936 if (session->active_media_state &&
2937 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO]) {
2938 struct ast_sip_session_media *media =
2939 session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
2940 if (media->rtp) {
2942 }
2943 }
2944
2946
2947 ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
2948 if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
2949 int cause = ast_sip_hangup_sip2cause(session->inv_session->cause);
2950
2951 ast_queue_hangup_with_cause(session->channel, cause);
2952 } else {
2953 ast_queue_hangup(session->channel);
2954 }
2955
2957}
2958
2960{
2961 const pj_str_t *host = ast_sip_pjsip_uri_get_hostname(session->request_uri);
2962 size_t size = pj_strlen(host) + 1;
2963 char *domain = ast_alloca(size);
2964
2965 ast_copy_pj_str(domain, host, size);
2966
2967 pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
2968 return;
2969}
2970
2971/*! \brief Function called when a request is received on the session */
2972static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
2973{
2974 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
2975 struct transport_info_data *transport_data;
2976 pjsip_tx_data *packet = NULL;
2978
2979 if (session->channel) {
2980 SCOPE_EXIT_RTN_VALUE(0, "%s: No channel\n", ast_sip_session_get_name(session));
2981 }
2982
2983 /* Check for a to-tag to determine if this is a reinvite */
2984 if (rdata->msg_info.to->tag.slen) {
2985 /* Weird case. We've received a reinvite but we don't have a channel. The most
2986 * typical case for this happening is that a blind transfer fails, and so the
2987 * transferer attempts to reinvite himself back into the call. We already got
2988 * rid of that channel, and the other side of the call is unrecoverable.
2989 *
2990 * We treat this as a failure, so our best bet is to just hang this call
2991 * up and not create a new channel. Clearing defer_terminate here ensures that
2992 * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
2993 */
2994 session->defer_terminate = 0;
2996 SCOPE_EXIT_RTN_VALUE(-1, "%s: We have a To tag but no channel. Terminating session\n", ast_sip_session_get_name(session));
2997 }
2998
2999 datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
3000 if (!datastore) {
3001 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info datastore\n", ast_sip_session_get_name(session));
3002 }
3003
3004 transport_data = ast_calloc(1, sizeof(*transport_data));
3005 if (!transport_data) {
3006 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc transport_info\n", ast_sip_session_get_name(session));
3007 }
3008 pj_sockaddr_cp(&transport_data->local_addr, &rdata->tp_info.transport->local_addr);
3009 pj_sockaddr_cp(&transport_data->remote_addr, &rdata->pkt_info.src_addr);
3010 datastore->data = transport_data;
3012
3013 if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
3014 if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS
3015 && packet) {
3017 }
3018
3019 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to allocate new PJSIP channel on incoming SIP INVITE\n",
3021 }
3022
3024
3025 /* channel gets created on incoming request, but we wait to call start
3026 so other supplements have a chance to run */
3028}
3029
3030static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
3031{
3032 struct ast_features_pickup_config *pickup_cfg;
3033 struct ast_channel *chan;
3034
3035 /* Check for a to-tag to determine if this is a reinvite */
3036 if (rdata->msg_info.to->tag.slen) {
3037 /* We don't care about reinvites */
3038 return 0;
3039 }
3040
3041 pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
3042 if (!pickup_cfg) {
3043 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension.\n");
3044 return 0;
3045 }
3046
3047 if (strcmp(session->exten, pickup_cfg->pickupexten)) {
3048 ao2_ref(pickup_cfg, -1);
3049 return 0;
3050 }
3051 ao2_ref(pickup_cfg, -1);
3052
3053 /* We can't directly use session->channel because the pickup operation will cause a masquerade to occur,
3054 * changing the channel pointer in session to a different channel. To ensure we work on the right channel
3055 * we store a pointer locally before we begin and keep a reference so it remains valid no matter what.
3056 */
3057 chan = ast_channel_ref(session->channel);
3058 if (ast_pickup_call(chan)) {
3060 } else {
3062 }
3063 /* A hangup always occurs because the pickup operation will have either failed resulting in the call
3064 * needing to be hung up OR the pickup operation was a success and the channel we now have is actually
3065 * the channel that was replaced, which should be hung up since it is literally in limbo not connected
3066 * to anything at all.
3067 */
3068 ast_hangup(chan);
3069 ast_channel_unref(chan);
3070
3071 return 1;
3072}
3073
3075 .method = "INVITE",
3076 .priority = AST_SIP_SUPPLEMENT_PRIORITY_LAST - 1,
3077 .incoming_request = call_pickup_incoming_request,
3078};
3079
3080static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
3081{
3082 int res;
3084
3085 /* Check for a to-tag to determine if this is a reinvite */
3086 if (rdata->msg_info.to->tag.slen) {
3087 /* We don't care about reinvites */
3088 SCOPE_EXIT_RTN_VALUE(0, "Reinvite\n");
3089 }
3090
3091 res = ast_pbx_start(session->channel);
3092
3093 switch (res) {
3094 case AST_PBX_FAILED:
3095 ast_log(LOG_WARNING, "Failed to start PBX ;(\n");
3097 ast_hangup(session->channel);
3098 break;
3099 case AST_PBX_CALL_LIMIT:
3100 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
3102 ast_hangup(session->channel);
3103 break;
3104 case AST_PBX_SUCCESS:
3105 default:
3106 break;
3107 }
3108
3109 ast_debug(3, "Started PBX on new PJSIP channel %s\n", ast_channel_name(session->channel));
3110
3111 SCOPE_EXIT_RTN_VALUE((res == AST_PBX_SUCCESS) ? 0 : -1, "RC: %d\n", res);
3112}
3113
3115 .method = "INVITE",
3117 .incoming_request = pbx_start_incoming_request,
3118};
3119
3120/*! \brief Function called when a response is received on the session */
3121static void chan_pjsip_incoming_response_update_cause(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3122{
3123 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3124 struct ast_control_pvt_cause_code *cause_code;
3125 int data_size = sizeof(*cause_code);
3126 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3127
3128 if (!session->channel) {
3129 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3130 }
3131
3132 /* Build and send the tech-specific cause information */
3133 /* size of the string making up the cause code is "SIP " number + " " + reason length */
3134 data_size += 4 + 4 + pj_strlen(&status.reason);
3135 cause_code = ast_alloca(data_size);
3136 memset(cause_code, 0, data_size);
3137
3139
3140 snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
3141 (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
3142
3143 cause_code->ast_cause = ast_sip_hangup_sip2cause(status.code);
3144 ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
3145 ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
3146
3148}
3149
3150/*! \brief Function called when a response is received on the session */
3151static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3152{
3153 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
3154 SCOPE_ENTER(3, "%s: Status: %d\n", ast_sip_session_get_name(session), status.code);
3155
3156 if (!session->channel) {
3157 SCOPE_EXIT_RTN("%s: No channel\n", ast_sip_session_get_name(session));
3158 }
3159
3160 switch (status.code) {
3161 case 180: {
3162 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3163 if (sdp && sdp->body.ptr) {
3164 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3165 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3167 } else {
3168 ast_trace(-1, "%s: Queueing RINGING\n", ast_sip_session_get_name(session));
3170 }
3171
3172 ast_channel_lock(session->channel);
3173 if (ast_channel_state(session->channel) != AST_STATE_UP) {
3175 }
3176 ast_channel_unlock(session->channel);
3177 break;
3178 }
3179 case 183:
3180 if (session->endpoint->ignore_183_without_sdp) {
3181 pjsip_rdata_sdp_info *sdp = pjsip_rdata_get_sdp_info(rdata);
3182 if (sdp && sdp->body.ptr) {
3183 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3184 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS with SDP\n", ast_sip_session_get_name(session),
3185 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3186 session->early_confirmed = pjsip_100rel_is_reliable(rdata) == PJ_TRUE;
3188 }
3189 } else {
3190 ast_trace(-1, "%s: Queueing PROGRESS\n", ast_sip_session_get_name(session));
3191 ast_trace(1, "%s Method: %.*s Status: %d Queueing PROGRESS without SDP\n", ast_sip_session_get_name(session),
3192 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
3194 }
3195 break;
3196 case 200:
3197 ast_trace(-1, "%s: Queueing ANSWER\n", ast_sip_session_get_name(session));
3199 break;
3200 default:
3201 ast_trace(-1, "%s: Not queueing anything\n", ast_sip_session_get_name(session));
3202 break;
3203 }
3204
3206}
3207
3208static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3209{
3211
3212 if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
3213 if (session->endpoint->media.direct_media.enabled && session->channel) {
3214 ast_trace(-1, "%s: Queueing SRCCHANGE\n", ast_sip_session_get_name(session));
3216 }
3217 }
3219}
3220
3221static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
3222{
3224
3225 if (pj_strcmp2(&rdata->msg_info.msg->line.req.method.name, "PRACK") == 0 &&
3226 pjmedia_sdp_neg_get_state(session->inv_session->neg) == PJMEDIA_SDP_NEG_STATE_DONE) {
3227
3228 session->early_confirmed = 1;
3229 }
3231}
3232
3233static int update_devstate(void *obj, void *arg, int flags)
3234{
3236 "PJSIP/%s", ast_sorcery_object_get_id(obj));
3237 return 0;
3238}
3239
3241 .name = "PJSIP_DIAL_CONTACTS",
3243};
3244
3246 .name = "PJSIP_PARSE_URI",
3248};
3249
3251 .name = "PJSIP_PARSE_URI_FROM",
3253};
3254
3256 .name = "PJSIP_MEDIA_OFFER",
3259};
3260
3262 .name = "PJSIP_DTMF_MODE",
3265};
3266
3268 .name = "PJSIP_MOH_PASSTHROUGH",
3271};
3272
3274 .name = "PJSIP_SEND_SESSION_REFRESH",
3276};
3277
3278static char *app_pjsip_hangup = "PJSIPHangup";
3279
3280/*!
3281 * \brief Load the module
3282 *
3283 * Module loading including tests for configuration or dependencies.
3284 * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
3285 * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
3286 * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
3287 * configuration file or other non-critical problem return
3288 * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
3289 */
3290static int load_module(void)
3291{
3292 struct ao2_container *endpoints;
3293
3296 }
3297
3299
3301
3303 ast_log(LOG_ERROR, "Unable to register channel class %s\n", channel_type);
3304 goto end;
3305 }
3306
3308 ast_log(LOG_ERROR, "Unable to register PJSIP_DIAL_CONTACTS dialplan function\n");
3309 goto end;
3310 }
3311
3313 ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI dialplan function\n");
3314 goto end;
3315 }
3316
3318 ast_log(LOG_ERROR, "Unable to register PJSIP_PARSE_URI_FROM dialplan function\n");
3319 goto end;
3320 }
3321
3323 ast_log(LOG_WARNING, "Unable to register PJSIP_MEDIA_OFFER dialplan function\n");
3324 goto end;
3325 }
3326
3328 ast_log(LOG_WARNING, "Unable to register PJSIP_DTMF_MODE dialplan function\n");
3329 goto end;
3330 }
3331
3333 ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
3334 goto end;
3335 }
3336
3338 ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
3339 goto end;
3340 }
3341
3343 ast_log(LOG_WARNING, "Unable to register PJSIPHangup dialplan application\n");
3344 goto end;
3345 }
3347
3348
3350
3353
3357 ast_log(LOG_ERROR, "Unable to create held channels container\n");
3358 goto end;
3359 }
3360
3365
3367 ast_log(LOG_ERROR, "Unable to register PJSIP Channel CLI\n");
3368 goto end;
3369 }
3370
3371 /* since endpoints are loaded before the channel driver their device
3372 states get set to 'invalid', so they need to be updated */
3373 if ((endpoints = ast_sip_get_endpoints())) {
3375 ao2_ref(endpoints, -1);
3376 }
3377
3378 return 0;
3379
3380end:
3399
3402
3404}
3405
3406/*! \brief Unload the PJSIP channel from Asterisk */
3407static int unload_module(void)
3408{
3411
3413
3420
3422
3432
3436
3437 return 0;
3438}
3439
3441 .support_level = AST_MODULE_SUPPORT_CORE,
3442 .load = load_module,
3443 .unload = unload_module,
3444 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
3445 .requires = "res_pjsip,res_pjsip_session,res_pjsip_pubsub",
Access Control of various sorts.
char digit
jack_status_t status
Definition: app_jack.c:146
char * text
Definition: app_queue.c:1639
#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_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
@ 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
static int tmp()
Definition: bt_open.c:389
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_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
enum cc_state state
Definition: ccss.c:393
static PGresult * result
Definition: cel_pgsql.c:84
static const char type[]
Definition: chan_ooh323.c:109
static void transfer_data_destroy(void *obj)
Definition: chan_pjsip.c:1887
static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3208
static struct ast_datastore_info direct_media_mitigation_info
Definition: chan_pjsip.c:274
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:252
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:269
static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
Callback function to report status of implicit REFER-NOTIFY subscription.
Definition: chan_pjsip.c:1964
static int hangup_cause2sip(int cause)
Internal function which translates from Asterisk cause codes to SIP response codes.
Definition: chan_pjsip.c:2439
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.
Definition: chan_pjsip.c:1487
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:327
static int chan_pjsip_devicestate(const char *data)
Function called to get the device state of an endpoint.
Definition: chan_pjsip.c:1179
static int uid_hold_sort_fn(const void *obj_left, const void *obj_right, const int flags)
Definition: chan_pjsip.c:1089
static int chan_pjsip_transfer(struct ast_channel *ast, const char *target)
Function called by core for Asterisk initiated transfer.
Definition: chan_pjsip.c:2168
static int update_connected_line_information(void *data)
Update connected line information.
Definition: chan_pjsip.c:1434
static void transfer_redirect(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1914
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.
Definition: chan_pjsip.c:2513
static char * app_pjsip_hangup
Definition: chan_pjsip.c:3278
static void chan_pjsip_session_end(struct ast_sip_session *session)
Function called when the session ends.
Definition: chan_pjsip.c:2927
static int sendtext(void *obj)
Definition: chan_pjsip.c:2790
static void update_initial_connected_line(struct ast_sip_session *session)
Definition: chan_pjsip.c:2370
static int update_devstate(void *obj, void *arg, int flags)
Definition: chan_pjsip.c:3233
static struct ast_sip_session_supplement chan_pjsip_supplement
SIP session supplement structure.
Definition: chan_pjsip.c:143
static int remote_send_unhold(void *data)
Update local hold state to be unheld.
Definition: chan_pjsip.c:1506
static void rtp_direct_media_data_destroy(void *data)
Definition: chan_pjsip.c:366
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.
Definition: chan_pjsip.c:2422
static int direct_media_mitigate_glare(struct ast_sip_session *session)
Definition: chan_pjsip.c:276
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:448
static int request(void *obj)
Definition: chan_pjsip.c:2605
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.
Definition: chan_pjsip.c:1625
static int chan_pjsip_hangup(struct ast_channel *ast)
Function called by core to hang up a PJSIP session.
Definition: chan_pjsip.c:2562
static void chan_pjsip_pvt_dtor(void *obj)
Definition: chan_pjsip.c:82
static struct topology_change_refresh_data * topology_change_refresh_data_alloc(struct ast_sip_session *session, const struct ast_stream_topology *topology)
Definition: chan_pjsip.c:1524
static int handle_topology_request_change(struct ast_sip_session *session, const struct ast_stream_topology *proposed)
Definition: chan_pjsip.c:1601
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:179
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.
Definition: chan_pjsip.c:2740
static struct ast_custom_function chan_pjsip_dial_contacts_function
Definition: chan_pjsip.c:3240
static int send_topology_change_refresh(void *data)
Definition: chan_pjsip.c:1575
static int indicate(void *data)
Definition: chan_pjsip.c:1338
static int remote_send_hold(void *data)
Update local hold state to be held.
Definition: chan_pjsip.c:1500
static int on_topology_change_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:1549
static struct ao2_container * pjsip_uids_onhold
Definition: chan_pjsip.c:1112
static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
Function called to query options on a channel.
Definition: chan_pjsip.c:1242
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.
Definition: chan_pjsip.c:2972
struct ast_channel_tech chan_pjsip_tech
PBX interface structure for channel registration.
Definition: chan_pjsip.c:109
static void set_channel_on_rtp_instance(const struct ast_sip_session *session, const char *channel_id)
Definition: chan_pjsip.c:494
static int chan_pjsip_incoming_prack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3221
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.
Definition: chan_pjsip.c:2713
static int uid_hold_hash_fn(const void *obj, const int flags)
Definition: chan_pjsip.c:1071
static struct ast_sip_session_supplement pbx_start_supplement
Definition: chan_pjsip.c:3114
static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit)
Function called by core to start a DTMF digit.
Definition: chan_pjsip.c:2187
static struct ast_custom_function chan_pjsip_parse_uri_from_function
Definition: chan_pjsip.c:3250
static struct ast_sip_session_supplement chan_pjsip_prack_supplement
Definition: chan_pjsip.c:172
static void chan_pjsip_session_begin(struct ast_sip_session *session)
SIP session interaction functions.
Definition: chan_pjsip.c:2905
static void topology_change_refresh_data_free(struct topology_change_refresh_data *refresh_data)
Definition: chan_pjsip.c:1516
static struct indicate_data * indicate_data_alloc(struct ast_sip_session *session, int condition, int response_code, const void *frame_data, size_t datalen)
Definition: chan_pjsip.c:1313
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:377
static struct sendtext_data * sendtext_data_create(struct ast_channel *chan, struct ast_msg_data *msg)
Definition: chan_pjsip.c:2769
static void transport_info_destroy(void *obj)
Destructor function for transport_info_data.
Definition: chan_pjsip.c:261
static int send_direct_media_request(void *data)
Definition: chan_pjsip.c:396
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.
Definition: chan_pjsip.c:2861
static struct ast_rtp_glue chan_pjsip_rtp_glue
Local glue for interacting with the RTP engine core.
Definition: chan_pjsip.c:486
static pjsip_module refer_callback_module
REFER Callback module, used to attach session data structure to subscription.
Definition: chan_pjsip.c:1952
static int call_pickup_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3030
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:223
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:306
static int transfer(void *data)
Definition: chan_pjsip.c:2133
static const char channel_type[]
Definition: chan_pjsip.c:78
static void chan_pjsip_remove_hold(const char *chan_uid)
Remove a channel ID from the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1153
static int hangup(void *data)
Definition: chan_pjsip.c:2520
static int transmit_info_with_vidupdate(void *data)
Send SIP INFO with video update request.
Definition: chan_pjsip.c:1356
static void sendtext_data_destroy(void *obj)
Definition: chan_pjsip.c:2762
static struct ast_custom_function moh_passthrough_function
Definition: chan_pjsip.c:3267
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.
Definition: chan_pjsip.c:3121
static struct hangup_data * hangup_data_alloc(int cause, struct ast_channel *chan)
Definition: chan_pjsip.c:2498
static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
Definition: chan_pjsip.c:954
static int answer(void *data)
Definition: chan_pjsip.c:687
static int transmit_info_dtmf(void *data)
Definition: chan_pjsip.c:2255
static struct ast_custom_function media_offer_function
Definition: chan_pjsip.c:3255
static int chan_pjsip_write(struct ast_channel *ast, struct ast_frame *f)
Definition: chan_pjsip.c:1044
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:526
static void hangup_data_destroy(void *obj)
Definition: chan_pjsip.c:2491
static int load_module(void)
Load the module.
Definition: chan_pjsip.c:3290
static struct ast_sip_session_supplement chan_pjsip_ack_supplement
Definition: chan_pjsip.c:164
static int chan_pjsip_get_hold(const char *chan_uid)
Determine whether a channel ID is in the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1166
#define UNIQUEID_BUFSIZE
Definition: chan_pjsip.c:76
static int call(void *data)
Definition: chan_pjsip.c:2395
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
Definition: chan_pjsip.c:2883
static struct ast_custom_function chan_pjsip_parse_uri_function
Definition: chan_pjsip.c:3245
static void transfer_refer(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:2081
static struct ast_threadstorage uniqueid_threadbuf
Definition: chan_pjsip.c:75
static int unload_module(void)
Unload the PJSIP channel from Asterisk.
Definition: chan_pjsip.c:3407
static int pbx_start_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
Definition: chan_pjsip.c:3080
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:829
static unsigned int chan_idx
Definition: chan_pjsip.c:80
static void indicate_data_destroy(void *obj)
Definition: chan_pjsip.c:1305
static struct ast_custom_function session_refresh_function
Definition: chan_pjsip.c:3273
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:770
static const char * chan_pjsip_get_uniqueid(struct ast_channel *ast)
Definition: chan_pjsip.c:1283
static struct transfer_data * transfer_data_alloc(struct ast_sip_session *session, const char *target)
Definition: chan_pjsip.c:1895
static int chan_pjsip_answer(struct ast_channel *ast)
Function called by core when we should answer a PJSIP session.
Definition: chan_pjsip.c:731
static void info_dtmf_data_destroy(void *obj)
Definition: chan_pjsip.c:2236
static int chan_pjsip_add_hold(const char *chan_uid)
Add a channel ID to the list of PJSIP channels on hold.
Definition: chan_pjsip.c:1122
static struct info_dtmf_data * info_dtmf_data_alloc(struct ast_sip_session *session, char digit, unsigned int duration)
Definition: chan_pjsip.c:2242
static int is_colp_update_allowed(struct ast_sip_session *session)
Definition: chan_pjsip.c:1407
static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
Function called by core to stop a DTMF digit.
Definition: chan_pjsip.c:2299
static struct ast_sip_session_supplement chan_pjsip_supplement_response
SIP session supplement structure just for responses.
Definition: chan_pjsip.c:155
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:843
static void set_sipdomain_variable(struct ast_sip_session *session)
Definition: chan_pjsip.c:2959
static int chan_pjsip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Function called by core to change the underlying owner channel.
Definition: chan_pjsip.c:1050
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:547
static struct ast_sip_session_supplement call_pickup_supplement
Definition: chan_pjsip.c:3074
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.
Definition: chan_pjsip.c:3151
static struct ast_custom_function dtmf_mode_function
Definition: chan_pjsip.c:3261
PJSIP Channel Driver shared data structures.
General Asterisk PBX channel definitions.
const char * ast_channel_name(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:10518
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.
@ 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
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:5507
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2560
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1169
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1840
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:2968
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:570
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:1250
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2993
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:1257
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:891
#define AST_CHANNEL_INITIALIZERS_VERSION
struct ABI version
Definition: channel.h:620
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1185
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:10567
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:2518
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:4365
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:539
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
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:1784
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:2041
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2864
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2445
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:5543
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:9128
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:2969
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RING
Definition: channelstate.h:40
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_DOWN
Definition: channelstate.h:36
@ AST_STATE_BUSY
Definition: channelstate.h:43
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7408
Standard Command Line Interface.
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:462
void pjsip_channel_cli_unregister(void)
Unregisters the channel cli commands.
Definition: cli_commands.c:498
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.
Definition: devicestate.c:636
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.
Definition: devicestate.c:510
void ast_devstate_aggregate_init(struct ast_devstate_aggregate *agg)
Initialize aggregate device state.
Definition: devicestate.c:630
enum ast_device_state ast_devstate_aggregate_result(struct ast_devstate_aggregate *agg)
Get the aggregate device state result.
Definition: devicestate.c:663
enum ast_device_state ast_state_chan2dev(enum ast_channel_state chanstate)
Convert channel state to devicestate.
Definition: devicestate.c:242
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.
Definition: devicestate.c:471
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_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:1783
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:1499
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1777
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
char connected
Definition: eagi_proxy.c:82
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
const char * ast_endpoint_get_tech(const struct ast_endpoint *endpoint)
Gets the technology of the given endpoint.
const char * ast_endpoint_get_resource(const struct ast_endpoint *endpoint)
Gets the resource name 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.
Definition: format_cache.c:176
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:181
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:196
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:191
#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:744
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:400
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:417
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:523
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:581
@ 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:734
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:687
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:653
#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:395
static int exists(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:157
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7606
#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.
struct ast_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
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
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:2099
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:2165
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:2179
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:3162
#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_control_transfer
@ 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_VIDEO
@ AST_FRAME_VOICE
@ AST_FRAME_RTCP
@ AST_FRAME_MODEM
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED
@ AST_CONTROL_BUSY
@ 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_HOLD
@ 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
Definition: indications.c:439
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
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:757
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:191
#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:392
@ 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:7788
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7798
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:372
@ AST_PBX_CALL_LIMIT
Definition: pbx.h:373
@ AST_PBX_SUCCESS
Definition: pbx.h:371
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:4175
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:1558
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:4708
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:6969
Call Pickup API.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:199
static int cdata(void *userdata, int state, const char *cdata, size_t len)
struct stasis_forward * sub
Definition: res_corosync.c:240
const char * method
Definition: res_pjsip.c:1279
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:133
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:117
const int ast_sip_hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition: res_pjsip.c:3531
@ AST_SIP_MEDIA_ENCRYPT_NONE
Definition: res_pjsip.h:647
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition: res_pjsip.h:3186
@ AST_SIP_SUPPLEMENT_PRIORITY_LAST
Definition: res_pjsip.h:3188
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:2201
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:1979
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:2052
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting 'disable multi domain'.
@ AST_SIP_DTMF_NONE
Definition: res_pjsip.h:545
@ AST_SIP_DTMF_AUTO_INFO
Definition: res_pjsip.h:556
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:554
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:550
@ AST_SIP_DTMF_INFO
Definition: res_pjsip.h:552
@ AST_SIP_DTMF_RFC_4733
Definition: res_pjsip.h:548
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:1435
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:2008
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:3496
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE
Definition: res_pjsip.h:632
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING
Definition: res_pjsip.h:640
@ AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING
Definition: res_pjsip.h:636
ast_sip_session_refresh_method
Definition: res_pjsip.h:623
@ AST_SIP_SESSION_REFRESH_METHOD_UPDATE
Definition: res_pjsip.h:627
@ AST_SIP_SESSION_REFRESH_METHOD_INVITE
Definition: res_pjsip.h:625
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_ENABLED
@ 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.
Definition: pjsip_session.c:63
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.
#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.
Definition: rtp_engine.c:2691
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2313
@ 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.
Definition: rtp_engine.h:1286
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:2257
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:727
int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
Definition: rtp_engine.c:2285
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:590
@ 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:575
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:905
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:2368
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:408
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
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:1853
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:936
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:788
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
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:848
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:930
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:667
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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
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:683
unsigned long indent
Definition: chan_pjsip.c:684
Generic container type.
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
char chan_name[AST_CHANNEL_NAME]
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.
Definition: devicestate.h:228
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
union ast_frame::@226 data
enum ast_frame_type frametype
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::@208 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:2325
const char * type
Definition: res_pjsip.h:2327
const char * body_text
Definition: res_pjsip.h:2331
const char * subtype
Definition: res_pjsip.h:2329
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:913
struct ast_sip_direct_media_configuration direct_media
Definition: res_pjsip.h:915
struct ast_sip_t38_configuration t38
Definition: res_pjsip.h:917
An entity with which Asterisk communicates.
Definition: res_pjsip.h:961
const ast_string_field aors
Definition: res_pjsip.h:992
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:996
unsigned int inband_progress
Definition: res_pjsip.h:1018
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:856
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_stream_topology * topology
The media stream topology.
struct ast_sip_session_media_state::@263 sessions
Mapping of stream to media sessions.
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
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.
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 ast_sip_session_media_state * pending_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
Definition: astman.c:222
struct ast_channel * chan
Definition: chan_pjsip.c:2488
void * frame_data
Definition: chan_pjsip.c:1301
size_t datalen
Definition: chan_pjsip.c:1302
struct ast_sip_session * session
Definition: chan_pjsip.c:1298
unsigned int duration
Definition: chan_pjsip.c:2233
struct ast_sip_session * session
Definition: chan_pjsip.c:2231
Number structure.
Definition: app_followme.c:154
struct ast_sip_session * session
struct ast_stream_topology * topology
Definition: chan_pjsip.c:2600
struct ast_sip_session * session
Definition: chan_pjsip.c:2599
const char * dest
Definition: chan_pjsip.c:2601
struct ast_sip_session * session
Definition: chan_pjsip.c:363
struct ast_rtp_instance * vrtp
Definition: chan_pjsip.c:361
struct ast_channel * chan
Definition: chan_pjsip.c:359
struct ast_rtp_instance * rtp
Definition: chan_pjsip.c:360
struct ast_format_cap * cap
Definition: chan_pjsip.c:362
struct ast_msg_data * msg
Definition: chan_pjsip.c:2759
struct ast_sip_session * session
Definition: chan_pjsip.c:2758
struct ast_sip_session * session
Definition: chan_pjsip.c:1512
struct ast_sip_session_media_state * media_state
Definition: chan_pjsip.c:1513
struct ast_sip_session * session
Definition: chan_pjsip.c:1883
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
const char * args
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.
Definition: threadstorage.h:86
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:930
#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:941
#define ast_assert(a)
Definition: utils.h:739
#define ARRAY_LEN(a)
Definition: utils.h:666
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668