248 #define REREGISTER_BUFFER_TIME 10
251 #define LINE_PARAMETER_SIZE 8
282 str =
"Unregistered";
406 #define MAX_UNLOAD_TIMEOUT_TIME 35
412 #define DEFAULT_STATE_BUCKETS 53
444 const char *right_key = arg;
494 pjsip_param *line = arg;
496 return !pj_strcmp2(&line->value,
state->client_state->line) ?
CMP_MATCH : 0;
501 pjsip_sip_uri *pjuri;
502 static const pj_str_t LINE_STR = {
"line", 4 };
504 if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) {
507 pjuri = pjsip_uri_get_uri(uri);
508 return pjsip_param_find(&pjuri->other_param, &LINE_STR);
533 ast_debug(3,
"Determined relationship to outbound registration '%s' based on line '%s', using configured endpoint '%s'\n",
547 &client_state->
timer, client_state->
timer.id)) {
558 pjsip_tx_data *tdata)
561 int *callback_invoked;
562 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
565 if (!callback_invoked) {
566 pjsip_tx_data_dec_ref(tdata);
569 *callback_invoked = 0;
578 pjsip_tx_data_add_ref(tdata);
586 pjsip_regc_set_transport(client_state->
client, &selector);
595 if ((
status != PJ_SUCCESS) && !(*callback_invoked)) {
596 pjsip_tx_data_dec_ref(tdata);
607 pjsip_tx_data_dec_ref(client_state->
last_tdata);
617 pjsip_supported_hdr *hdr;
620 hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED,
NULL);
623 hdr = pjsip_supported_hdr_create(tdata->pool);
625 pjsip_tx_data_dec_ref(tdata);
629 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
633 for (i = 0; i < hdr->count; ++i) {
634 if (pj_stricmp(&hdr->values[i],
name) == 0) {
639 if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
644 pj_strassign(&hdr->values[hdr->count++],
name);
671 pjsip_tx_data *tdata;
678 || pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS) {
683 pjsip_regc_info
info;
685 pjsip_regc_get_info(client_state->client, &
info);
686 ast_log(
LOG_DEBUG,
"Outbound REGISTER attempt %u to '%.*s' with client '%.*s'\n",
687 client_state->retries + 1,
688 (
int)
info.server_uri.slen,
info.server_uri.ptr,
689 (
int)
info.client_uri.slen,
info.client_uri.ptr);
723 pj_time_val delay = { .sec = seconds, };
724 pjsip_regc_info
info;
728 pjsip_regc_get_info(client_state->
client, &
info);
729 ast_debug(1,
"Scheduling outbound registration to server '%.*s' from client '%.*s' in %d seconds\n",
730 (
int)
info.server_uri.slen,
info.server_uri.ptr,
731 (
int)
info.client_uri.slen,
info.client_uri.ptr,
736 ast_log(
LOG_WARNING,
"Failed to schedule registration to server '%.*s' from client '%.*s'\n",
737 (
int)
info.server_uri.slen,
info.server_uri.ptr,
738 (
int)
info.client_uri.slen,
info.client_uri.ptr);
745 const char *status_old;
746 const char *status_new;
757 if (!strcmp(status_old, status_new)) {
778 if (client_state->
client) {
779 pjsip_regc_info
info;
780 pjsip_tx_data *tdata;
782 pjsip_regc_get_info(client_state->
client, &
info);
784 if (
info.is_busy == PJ_TRUE) {
787 "Registration transaction is busy with server '%.*s' from client '%.*s'.\n",
788 (
int)
info.server_uri.slen,
info.server_uri.ptr,
789 (
int)
info.client_uri.slen,
info.client_uri.ptr);
795 switch (client_state->
status) {
800 "Trying to unregister with server '%.*s' from client '%.*s' before destruction.\n",
801 (
int)
info.server_uri.slen,
info.server_uri.ptr,
802 (
int)
info.client_uri.slen,
info.client_uri.ptr);
806 if (pjsip_regc_unregister(client_state->
client, &tdata) == PJ_SUCCESS
820 pjsip_regc_destroy(client_state->
client);
852 if (response->
rdata) {
853 pjsip_rx_data_free_cloned(response->
rdata);
868 if (
code == PJSIP_SC_REQUEST_TIMEOUT ||
869 code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
870 code == PJSIP_SC_BAD_GATEWAY ||
871 code == PJSIP_SC_SERVICE_UNAVAILABLE ||
872 code == PJSIP_SC_SERVER_TIMEOUT ||
873 ((
code == PJSIP_SC_UNAUTHORIZED ||
874 code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
876 PJSIP_IS_STATUS_IN_CLASS(
code, 600)) {
884 const char *
server_uri,
const char *client_uri)
889 if (response->
rdata) {
891 "registration attempt to '%s', retrying in '%u'\n",
895 "registration attempt to '%s', retrying in '%u'\n",
910 pjsip_regc_info
info;
912 pjsip_regc_get_info(
state->client_state->client, &
info);
914 "Outbound registration transport to server '%.*s' from client '%.*s' shutdown\n",
915 (
int)
info.server_uri.slen,
info.server_uri.ptr,
916 (
int)
info.client_uri.slen,
info.client_uri.ptr);
939 const char *registration_name = obj;
957 return strcmp(ma, mb) == 0;
964 if (!PJSIP_TRANSPORT_IS_RELIABLE(transport)) {
972 strcpy(monitor, registration_name);
986 static const pj_str_t associated_uri_str = {
"P-Associated-URI", 16 };
987 static const pj_str_t service_route_str = {
"Service-Route", 13 };
989 pjsip_msg *msg = response->
rdata->msg_info.msg;
1000 char *service_route;
1007 size = pj_strlen(&((pjsip_generic_string_hdr*)
header)->hvalue) + 1;
1009 if (!service_route) {
1010 if (service_routes) {
1012 service_routes =
NULL;
1019 if (!service_routes) {
1021 if (!service_routes) {
1030 service_routes =
NULL;
1036 if (service_routes) {
1043 header = pjsip_msg_find_hdr_by_name(msg, &associated_uri_str,
NULL);
1045 char value[pj_strlen(&((pjsip_generic_string_hdr*)
header)->hvalue) + 1];
1057 pjsip_regc_info
info;
1059 char client_uri[PJSIP_MAX_URL_SIZE];
1070 ast_debug(1,
"Processing REGISTER response %d from server '%s' for client '%s'\n",
1073 if (response->
code == 408 || response->
code == 503) {
1078 if (res == PJ_SUCCESS) {
1083 }
else if ((response->
code == 401 || response->
code == 407)
1087 pjsip_cseq_hdr *cseq_hdr;
1088 pjsip_tx_data *tdata;
1093 ast_debug(1,
"Sending authenticated REGISTER to server '%s' from client '%s'\n",
1095 pjsip_tx_data_add_ref(tdata);
1099 cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
1102 pjsip_tx_data_dec_ref(tdata);
1103 if (res == PJ_SUCCESS) {
1108 ast_log(
LOG_WARNING,
"Failed to create authenticated REGISTER request to server '%s' from client '%s'\n",
1116 if (PJSIP_IS_STATUS_IN_CLASS(response->
code, 200)) {
1119 int next_registration_round;
1122 ast_debug(1,
"Outbound registration to '%s' with client '%s' successful\n",
server_uri, client_uri);
1126 if (next_registration_round < 0) {
1128 next_registration_round = 0;
1136 ast_debug(1,
"Outbound unregistration to '%s' with client '%s' successful\n",
server_uri, client_uri);
1154 ast_log(
LOG_WARNING,
"Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
1162 if (response->
code == 403
1169 ast_log(
LOG_WARNING,
"403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1177 ast_log(
LOG_WARNING,
"'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1182 if (response->
rdata) {
1183 ast_log(
LOG_WARNING,
"Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
1186 ast_log(
LOG_WARNING,
"Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
1209 int *callback_invoked;
1216 *callback_invoked = 1;
1223 response->
code = param->code;
1232 ast_debug(1,
"Received REGISTER response %d(%.*s)\n",
1233 param->code, (
int) param->reason.slen, param->reason.ptr);
1236 struct pjsip_retry_after_hdr *retry_after;
1237 pjsip_transaction *tsx;
1239 retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
1241 response->
retry_after = retry_after ? retry_after->ivalue : 0;
1250 pjsip_tx_data_dec_ref(client_state->
last_tdata);
1252 tsx = pjsip_rdata_get_tsx(param->rdata);
1255 pjsip_rx_data_clone(param->rdata, 0, &response->
rdata);
1268 ast_log(
LOG_WARNING,
"Failed to pass incoming registration response to threadpool\n");
1278 ast_debug(3,
"Destroying registration state for registration to server '%s' from client '%s'\n",
1279 state->registration ?
state->registration->server_uri :
"",
1280 state->registration ?
state->registration->client_uri :
"");
1283 if (!
state->client_state) {
1285 }
else if (!
state->client_state->serializer) {
1289 ast_log(
LOG_WARNING,
"Failed to pass outbound registration client destruction to threadpool\n");
1307 pjsip_tx_data_dec_ref(client_state->
last_tdata);
1323 if (!
state->client_state) {
1329 pj_timer_entry_init(&
state->client_state->timer, 0,
state->client_state,
1332 state->client_state->registration_name =
1339 if (!
state->client_state->transport_name
1340 || !
state->client_state->registration_name) {
1351 if (!
state->client_state->serializer) {
1382 return registration;
1387 const pj_str_t *target, pjsip_tpselector *selector,
const char *
line,
const char *header_params)
1389 pj_str_t
tmp, local_addr;
1391 pjsip_sip_uri *sip_uri;
1392 pjsip_transport_type_e
type;
1395 pj_strdup_with_null(pool, &
tmp, target);
1397 if (!(uri = pjsip_parse_uri(pool,
tmp.ptr,
tmp.slen, 0)) ||
1398 (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1402 sip_uri = pjsip_uri_get_uri(uri);
1404 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
1405 if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
1406 if (
type == PJSIP_TRANSPORT_UNSPECIFIED
1407 || !(pjsip_transport_get_flag_from_type(
type) & PJSIP_TRANSPORT_SECURE)) {
1408 type = PJSIP_TRANSPORT_TLS;
1410 }
else if (!sip_uri->transport_param.slen) {
1411 type = PJSIP_TRANSPORT_UDP;
1412 }
else if (
type == PJSIP_TRANSPORT_UNSPECIFIED) {
1416 if (pj_strchr(&sip_uri->host,
':')) {
1417 type |= PJSIP_TRANSPORT_IPV6;
1421 pool,
type, selector, &local_addr, &local_port) != PJ_SUCCESS) {
1425 if (!pj_strchr(&sip_uri->host,
':') && pj_strchr(&local_addr,
':')) {
1426 type |= PJSIP_TRANSPORT_IPV6;
1429 contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
1430 contact->slen = pj_ansi_snprintf(
contact->ptr, PJSIP_MAX_URL_SIZE,
1431 "<%s:%s@%s%.*s%s:%d%s%s%s%s>%s%s",
1432 ((pjsip_transport_get_flag_from_type(
type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ?
"sips" :
"sip",
1434 (
type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
1435 (
int)local_addr.slen,
1437 (
type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
1439 (
type != PJSIP_TRANSPORT_UDP &&
type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
1440 (
type != PJSIP_TRANSPORT_UDP &&
type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(
type) :
"",
1444 S_OR(header_params,
""));
1487 const char *
url =
"https://www.googleapis.com/oauth2/v3/token";
1495 ast_log(
LOG_ERROR,
"CURL is unavailable. This is required for Google OAuth 2.0 authentication. Please ensure it is loaded.\n");
1500 "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
1506 ast_debug(2,
"Performing Google OAuth 2.0 authentication using command: %s\n", cmd);
1512 ast_log(
LOG_ERROR,
"Could not retrieve Google OAuth 2.0 authentication\n");
1516 ast_debug(2,
"Google OAuth 2.0 authentication returned: %s\n",
buf);
1520 ast_log(
LOG_ERROR,
"Could not parse Google OAuth 2.0 authentication: %d(%d) %s: '%s'\n",
1527 ast_log(
LOG_ERROR,
"Could not find Google OAuth 2.0 access_token in: '%s'\n",
1548 const char *access_token;
1549 pjsip_cred_info auth_creds[1];
1550 pjsip_auth_clt_pref prefs;
1554 memset(auths, 0,
sizeof(auths));
1560 for (idx = 0; idx < auth_size; ++idx) {
1561 switch (auths[idx]->
type) {
1563 pj_cstr(&auth_creds[0].username, auths[idx]->
auth_user);
1564 pj_cstr(&auth_creds[0].scheme,
"Bearer");
1565 pj_cstr(&auth_creds[0].
realm, auths[idx]->
realm);
1566 ast_debug(2,
"Obtaining Google OAuth access token\n");
1568 if (!access_token) {
1573 ast_debug(2,
"Setting data to '%s'\n", access_token);
1575 pj_cstr(&auth_creds[0].data, access_token);
1576 auth_creds[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
1578 pjsip_regc_set_credentials(regc, 1, auth_creds);
1581 prefs.initial_auth = PJ_TRUE;
1582 pj_cstr(&prefs.algorithm,
"oauth");
1583 pjsip_regc_set_prefs(regc, &prefs);
1585 if (access_token != auths[idx]->
auth_pass) {
1609 pj_str_t
server_uri, client_uri, contact_uri;
1610 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1614 ast_log(
LOG_ERROR,
"Could not create pool for URI validation on outbound registration '%s'\n",
1620 uri = pjsip_parse_uri(pool,
tmp.ptr,
tmp.slen, 0);
1622 ast_log(
LOG_ERROR,
"Invalid server URI '%s' specified on outbound registration '%s'\n",
1629 uri = pjsip_parse_uri(pool,
tmp.ptr,
tmp.slen, 0);
1631 ast_log(
LOG_ERROR,
"Invalid client URI '%s' specified on outbound registration '%s'\n",
1639 uri = pjsip_parse_uri(pool,
tmp.ptr,
tmp.slen, 0);
1641 ast_log(
LOG_ERROR,
"Invalid outbound proxy URI '%s' specified on outbound registration '%s'\n",
1654 &
state->client_state->client) != PJ_SUCCESS) {
1659 pjsip_regc_set_transport(
state->client_state->client, &selector);
1662 pjsip_route_hdr route_set, *route;
1663 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
1666 pj_list_init(&route_set);
1668 pj_strdup2_with_null(pjsip_regc_get_pool(
state->client_state->client), &
tmp,
1670 route = pjsip_parse_hdr(pjsip_regc_get_pool(
state->client_state->client),
1676 pj_list_insert_nodes_before(&route_set, route);
1678 pjsip_regc_set_route_set(
state->client_state->client, &route_set);
1681 if (
state->registration->line) {
1697 if (pjsip_regc_init(
state->client_state->client, &
server_uri, &client_uri,
1727 state->client_state->retries = 0;
1732 pjsip_regc_update_expires(
state->client_state->client, registration->
expiration);
1758 ast_log(
LOG_ERROR,
"No server URI specified on outbound registration '%s'\n",
1762 ast_log(
LOG_ERROR,
"Server URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
1766 ast_log(
LOG_ERROR,
"No client URI specified on outbound registration '%s'\n",
1770 ast_log(
LOG_ERROR,
"Client URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
1774 ast_log(
LOG_ERROR,
"Line support has been enabled on outbound registration '%s' without providing an endpoint\n",
1778 ast_log(
LOG_ERROR,
"An endpoint has been specified on outbound registration '%s' without enabling line support\n",
1785 "No change between old configuration and new configuration on outbound registration '%s'. Using previous state\n",
1861 struct pjsip_regc *client =
state->client_state->client;
1862 pjsip_tx_data *tdata;
1863 pjsip_regc_info
info;
1865 pjsip_regc_get_info(client, &
info);
1866 ast_debug(1,
"Unregistering contacts with server '%s' from client '%s'\n",
1867 state->registration->server_uri,
state->registration->client_uri);
1871 if (pjsip_regc_unregister(client, &tdata) == PJ_SUCCESS
1936 wordlen = strlen(
word);
1937 if (wordlen == 0 && ++which >
state) {
1969 const char *registration_name;
1973 e->
command =
"pjsip send unregister";
1975 "Usage: pjsip send unregister <registration> | *all\n"
1976 " Unregisters the specified (or all) outbound registration(s) "
1977 "and stops future registration attempts.\n";
1987 registration_name =
a->argv[3];
1989 if (strcmp(registration_name,
"*all") == 0) {
1991 ast_cli(
a->fd,
"Unregister all queued\n");
1997 ast_cli(
a->fd,
"Unable to retrieve registration %s\n", registration_name);
2002 ast_cli(
a->fd,
"Failed to queue unregistration\n");
2012 const char *registration_name;
2016 e->
command =
"pjsip send register";
2018 "Usage: pjsip send register <registration> | *all \n"
2019 " Unregisters the specified (or all) outbound "
2020 "registration(s) then starts registration(s) and schedules re-registrations.\n";
2030 registration_name =
a->argv[3];
2032 if (strcmp(registration_name,
"*all") == 0) {
2034 ast_cli(
a->fd,
"Re-register all queued\n");
2040 ast_cli(
a->fd,
"Unable to retrieve registration %s\n", registration_name);
2048 ast_cli(
a->fd,
"Failed to queue unregistration\n");
2050 ast_cli(
a->fd,
"Failed to queue registration\n");
2067 if (strcmp(registration_name,
"*all") == 0) {
2099 if (strcmp(registration_name,
"*all") == 0) {
2147 pjsip_regc_info
info;
2158 pjsip_regc_get_info(
state->client_state->client, &
info);
2173 ami->registration = obj;
2187 "outbound registrations\n");
2199 "Registered: %d\r\n"
2200 "NotRegistered: %d\r\n",
2264 " <Registration/ServerURI..............................> <Auth..........> <Status.......>\n");
2275 #define REGISTRATION_URI_FIELD_LEN 53
2291 || (
context->show_details_only_level_0 &&
context->indent_level == 0)) {
2313 .
command =
"pjsip list registrations",
2314 .
usage =
"Usage: pjsip list registrations [ like <pattern> ]\n"
2315 " List the configured PJSIP Registrations\n"
2316 " Optional regular expression pattern is used to filter the list.\n"),
2318 .
command =
"pjsip show registrations",
2319 .
usage =
"Usage: pjsip show registrations [ like <pattern> ]\n"
2320 " Show the configured PJSIP Registrations\n"
2321 " Optional regular expression pattern is used to filter the list.\n"),
2323 .
command =
"pjsip show registration",
2324 .
usage =
"Usage: pjsip show registration <id>\n"
2325 " Show the configured PJSIP Registration\n"),
2335 const char *registration_id;
2338 ast_debug(4,
"Auths updated. Checking for any outbound registrations that are in permanent rejected state so they can be retried\n");
2352 ast_debug(4,
"Trying outbound registration '%s' again\n", registration_id);
2356 ast_log(
LOG_ERROR,
"Failed to perform outbound registration on '%s'\n", registration_id);
2377 if (!registration) {
2399 if (strcmp(object_type,
"registration")) {
2452 ast_debug(3,
"Received network change event\n");
2483 ast_debug(2,
"Waiting for registration transactions to complete for unload.\n");
2491 ast_log(
LOG_WARNING,
"Unload incomplete. Could not stop %d outbound registrations. Try again later.\n",
2622 .requires =
"res_pjsip",
2623 .optional_modules =
"res_statsd",
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_malloc(len)
A wrapper for malloc()
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_unlink(container, obj)
Remove an object from a container.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#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.
static char context[AST_MAX_CONTEXT]
static struct registrations registrations
enum sip_cc_notify_state state
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_YESNO_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
struct ast_taskprocessor * ast_sip_create_serializer_group(const char *name, struct ast_serializer_shutdown_group *shutdown_group)
Create a new serializer for SIP tasks.
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.
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.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
#define EVENT_FLAG_REPORTING
#define EVENT_FLAG_SYSTEM
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Core PBX routines and definitions.
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
static void * cleanup(void *unused)
struct stasis_forward * sub
struct ao2_container * container
int ast_sip_transport_state_set_transport(const char *transport_name, pjsip_transport *transport)
Sets the PJSIP transport on a child transport.
struct ast_sip_service_route_vector * ast_sip_service_route_vector_alloc(void)
Allocate a vector of service routes.
void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
Clean up retrieved auth structures from memory.
int ast_sip_format_auths_ami(const struct ast_sip_auth_vector *auths, struct ast_sip_ami *ami)
Format auth details for AMI.
int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *tdata, pjsip_tx_data **new_request)
Create a response to an authentication challenge.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
struct ast_str * ast_sip_create_ami_event(const char *event, struct ast_sip_ami *ami)
Creates a string to store AMI event data in.
void ast_sip_transport_monitor_unregister(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
int ast_sip_auths_to_str(const struct ast_sip_auth_vector *auths, char **buf)
Converts an auths array to a string of comma separated values.
int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Register a SIP endpoint identifier.
int ast_sip_retrieve_auths(const struct ast_sip_auth_vector *auths, struct ast_sip_auth **out)
Retrieve relevant SIP auth structures from sorcery.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
void ast_sip_service_route_vector_destroy(struct ast_sip_service_route_vector *service_routes)
Destroy a vector of service routes.
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
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.
void ast_sip_transport_monitor_unregister_all(ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a transport shutdown monitor from all reliable transports.
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *ao2_data)
Register a reliable transport shutdown monitor callback.
int ast_sip_sorcery_object_to_ami(const void *obj, struct ast_str **buf)
Converts a sorcery object to a string of object properties.
@ AST_SIP_AUTH_TYPE_GOOGLE_OAUTH
void ast_sip_auth_vector_destroy(struct ast_sip_auth_vector *vector)
Free contents of an auth vector.
int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
int ast_sip_auth_vector_init(struct ast_sip_auth_vector *vector, const char *auth_names)
Initialize an auth vector with the configured values.
int ast_sip_transport_state_set_preferred_identity(const char *transport_name, const char *identity)
Sets the P-Preferred-Identity on a child transport.
int ast_sip_failover_request(pjsip_tx_data *tdata)
Set a request to use the next value in the list of resolved addresses.
int ast_sip_transport_state_set_service_routes(const char *transport_name, struct ast_sip_service_route_vector *service_routes)
Sets the service routes on a child transport.
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
static struct ao2_container * new_states
Used on [re]loads to hold new state data.
static int ami_show_outbound_registrations(struct mansession *s, const struct message *m)
static const struct ast_sorcery_instance_observer observer_callbacks_registrations
static char * cli_complete_registration(const char *line, const char *word, int pos, int state)
static int sip_outbound_registration_regc_alloc(void *data)
Helper function that allocates a pjsip registration client and configures it.
static void * cli_retrieve_by_id(const char *id)
static struct ast_sip_endpoint * line_identify(pjsip_rx_data *rdata)
Endpoint identifier which uses the 'line' parameter to establish a relationship to an outgoing regist...
static void save_response_fields_to_transport(struct registration_response *response)
#define REREGISTER_BUFFER_TIME
Amount of buffer time (in seconds) before expiration that we re-register at.
static void unregister_all(void)
#define LINE_PARAMETER_SIZE
Size of the buffer for creating a unique string for the line.
static int queue_unregister(struct sip_outbound_registration_state *state)
static char * my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void registration_deleted_observer(const void *obj)
static int cli_print_header(void *obj, void *arg, int flags)
static struct ast_serializer_shutdown_group * shutdown_group
static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
static void * sip_outbound_registration_alloc(const char *name)
Allocator function for registration information.
#define REGISTRATION_URI_FIELD_LEN
static int registration_state_cmp(void *obj, void *arg, int flags)
comparator function for state objects
static int handle_registration_response(void *data)
Callback function for handling a response to a registration attempt.
static int handle_client_registration(void *data)
Callback function for registering.
#define DEFAULT_STATE_BUCKETS
Default number of state container buckets.
static AO2_GLOBAL_OBJ_STATIC(current_states)
static void sip_outbound_registration_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
Timer callback function, used just for registrations.
static const struct ast_sorcery_observer registration_observer
static int queue_register(struct sip_outbound_registration_state *state)
static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const char *user, const pj_str_t *target, pjsip_tpselector *selector, const char *line, const char *header_params)
Helper function which populates a pj_str_t with a contact header.
static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
#define MAX_UNLOAD_TIMEOUT_TIME
static int ami_register(struct mansession *s, const struct message *m)
static pj_str_t PATH_NAME
static int ami_unregister(struct mansession *s, const struct message *m)
static void registration_transport_shutdown_cb(void *obj)
static void sip_outbound_registration_state_destroy(void *obj)
Destructor function for registration state.
static const char * sip_outbound_registration_status_str(enum sip_outbound_registration_status state)
static char * cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct pjsip_param * get_uri_option_line(const void *uri)
static void registration_response_destroy(void *obj)
Registration response structure destructor.
static void sip_outbound_registration_client_state_destroy(void *obj)
Destructor function for client registration state.
static int reload_module(void)
static const char * fetch_google_access_token(const struct ast_sip_auth *auth)
Get google oauth2 access token using refresh token.
static int reregister_immediately_cb(void *obj)
static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
Helper function to add string to Supported header.
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static int sip_outbound_registration_is_temporal(unsigned int code, struct sip_outbound_registration_client_state *client_state)
Helper function which determines if a response code is temporal or not.
static int handle_client_state_destruction(void *data)
Callback function for unregistering (potentially) and destroying state.
static void auth_observer(const char *type)
static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
Apply function which finds or allocates a state structure.
static void update_client_state_status(struct sip_outbound_registration_client_state *client_state, enum sip_outbound_registration_status status)
static void registration_transport_monitor_setup(pjsip_transport *transport, const char *registration_name)
static const struct ast_sorcery_observer observer_callbacks_auth
static pj_status_t registration_client_send(struct sip_outbound_registration_client_state *client_state, pjsip_tx_data *tdata)
Helper function which sends a message and cleans up, if needed, on failure.
static int outbound_auths_to_str(const void *obj, const intptr_t *args, char **buf)
static int ami_outbound_registration_detail(void *obj, void *arg, int flags)
static void reregister_all(void)
static struct ast_sip_endpoint_identifier line_identifier
static int unregister_task(void *obj)
static int outbound_auths_to_var_list(const void *obj, struct ast_variable **fields)
static struct ast_threadstorage register_callback_invoked
static struct sip_outbound_registration_state * get_state(const char *id)
static struct ao2_container * get_registrations(void)
static void sip_outbound_registration_destroy(void *obj)
Destructor function for registration information.
static pj_str_t OUTBOUND_NAME
static struct stasis_subscription * network_change_sub
static struct ao2_container * cli_get_container(const char *regex)
static int load_module(void)
static int cli_print_body(void *obj, void *arg, int flags)
static struct sip_outbound_registration_state * sip_outbound_registration_state_alloc(struct sip_outbound_registration *registration)
Allocator function for registration state.
static void schedule_retry(struct registration_response *response, unsigned int interval, const char *server_uri, const char *client_uri)
static void schedule_registration(struct sip_outbound_registration_client_state *client_state, unsigned int seconds)
Helper function which sets up the timer to re-register in a specific amount of time.
sip_outbound_registration_status
Various states that an outbound registration may be in.
@ SIP_REGISTRATION_REGISTERED
Registered, yay!
@ SIP_REGISTRATION_REJECTED_PERMANENT
Registration was rejected, permanently.
@ SIP_REGISTRATION_STOPPED
Registration has been stopped.
@ SIP_REGISTRATION_STOPPING
Registration is stopping.
@ SIP_REGISTRATION_UNREGISTERED
Currently unregistered.
@ SIP_REGISTRATION_REJECTED_TEMPORARY
Registration was rejected, but response was temporal.
static int unload_module(void)
static int line_identify_relationship(void *obj, void *arg, int flags)
Callback function for matching an outbound registration based on line.
static int set_outbound_initial_authentication_credentials(pjsip_regc *regc, const struct ast_sip_auth_vector *auth_vector)
static struct ast_cli_entry cli_outbound_registration[]
static char * cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_sip_cli_formatter_entry * cli_formatter
static int check_state(void *obj, void *arg, int flags)
static int sip_outbound_registration_perform(void *data)
Helper function which performs a single registration.
static int can_reuse_registration(struct sip_outbound_registration *existing, struct sip_outbound_registration *applied)
static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
Callback function for outbound registration client.
static int registration_state_hash(const void *obj, const int flags)
hashing function for state objects
static int monitor_matcher(void *a, void *b)
static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
Helper function which cancels the timer on a client.
static void registration_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
static int ami_outbound_registration_task(void *obj)
static int add_configured_supported_headers(struct sip_outbound_registration_client_state *client_state, pjsip_tx_data *tdata)
Helper function to add configured supported headers.
static struct ast_sorcery * sorcery
int ast_sip_validate_uri_length(const char *uri)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
#define ast_sorcery_apply_config(sorcery, name)
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
#define ast_sorcery_apply_default(sorcery, type, name, data)
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define stasis_subscribe(topic, callback, data)
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
Publish a channel driver outgoing registration message.
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes.
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.
void ast_statsd_log_string_va(const char *metric_name, const char *metric_type, const char *value, double sample_rate,...)
Send a stat to the configured statsd server.
#define AST_STATSD_GAUGE
Support for publishing to a statsd server.
void ast_statsd_log_string(const char *metric_name, const char *metric_type, const char *value, double sample_rate)
Send a stat to the configured statsd server.
void ast_statsd_log(const char *metric_name, const char *metric_type, intmax_t value)
Send a stat to the configured statsd server.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
descriptor for a cli entry.
JSON parsing error information.
Abstract JSON element (object, array, string, int, ...).
const ast_string_field oauth_clientid
const ast_string_field oauth_secret
const ast_string_field realm
const ast_string_field auth_user
const ast_string_field refresh_token
const ast_string_field auth_pass
CLI Formatter Context passed to all formatters.
CLI Formatter Registry Entry.
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
ao2_callback_fn * print_header
const char *(* get_id)(const void *obj)
struct ao2_container *(* get_container)(const char *regex)
void *(* retrieve_by_id)(const char *id)
ao2_callback_fn * print_body
An entity responsible for identifying the source of a SIP message.
struct ast_sip_endpoint *(* identify_endpoint)(pjsip_rx_data *rdata)
Callback used to identify the source of a message. See ast_sip_identify_endpoint for more details.
An entity with which Asterisk communicates.
Interface for the sorcery instance observer.
void(* object_type_loaded)(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Callback after any object_type is loaded/reloaded.
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
void(* deleted)(const void *object)
Callback for when an object is deleted.
Full structure for sorcery.
Support for dynamic strings.
A ast_taskprocessor structure is a singleton by name.
Structure for variables, used for configurations and for channel variables.
In case you didn't read that giant block of text above the mansession_session struct,...
Structure for registration response.
struct sip_outbound_registration_client_state * client_state
Outbound registration client state.
pjsip_rx_data * rdata
The response message.
int code
Response code for the registration attempt.
int expiration
Expiration time for registration.
int retry_after
Retry-After value.
pjsip_tx_data * old_request
Request for which the response was received.
struct sip_outbound_registration * registration
Outbound registration client state information (persists for lifetime of regc)
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
unsigned int support_outbound
Determines whether SIP Outbound support should be advertised.
unsigned int auth_attempted
Non-zero if we have attempted sending a REGISTER with authentication.
char line[LINE_PARAMETER_SIZE]
Optional line parameter placed into Contact.
unsigned int support_path
Determines whether SIP Path support should be advertised.
char * transport_name
The name of the transport to be used for the registration.
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
unsigned int destroy
Registration should be destroyed after completion of transaction.
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
struct ast_taskprocessor * serializer
Serializer for stuff and things.
unsigned int max_retries
Maximum number of retries permitted.
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
char * registration_name
The name of the registration sorcery object.
pj_timer_entry timer
Timer entry for retrying on temporal responses.
enum sip_outbound_registration_status status
Current state of this registration.
unsigned int retries
Current number of retries.
pjsip_tx_data * last_tdata
Last tdata sent We need the original tdata to resend a request on auth failure or timeout....
pjsip_regc * client
Outbound registration client.
Outbound registration state information (persists for lifetime that registration should exist)
struct sip_outbound_registration_client_state * client_state
Client state information.
struct sip_outbound_registration * registration
Outbound registration configuration object.
Outbound registration information.
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
SORCERY_OBJECT(details)
Sorcery object details.
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
unsigned int expiration
Requested expiration time.
const ast_string_field transport
unsigned int support_outbound
Whether Outbound support is enabled.
unsigned int support_path
Whether Path support is enabled.
const ast_string_field contact_header_params
const ast_string_field outbound_proxy
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
const ast_string_field server_uri
const ast_string_field endpoint
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
unsigned int max_retries
Maximum number of retries permitted.
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
const ast_string_field client_uri
unsigned int line
Whether to add a line parameter to the outbound Contact or not.
const ast_string_field contact_user
structure to hold users read from users.conf
An API for managing task processing threads that can be shared across modules.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
struct ast_serializer_shutdown_group * ast_serializer_shutdown_group_alloc(void)
Create a serializer group shutdown control object.
int ast_serializer_shutdown_group_join(struct ast_serializer_shutdown_group *shutdown_group, int timeout)
Wait for the serializers in the group to shutdown with timeout.
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.
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
long int ast_random(void)
Vector container support.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.