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;
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);
589 status = pjsip_regc_send(client_state->
client, tdata);
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;
748 if (client_state->
status == status) {
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)) {
889 if (response->
rdata) {
891 "registration attempt to '%s', retrying in '%u'\n",
892 response->
code, server_uri, client_uri, interval);
895 "registration attempt to '%s', retrying in '%u'\n",
896 server_uri, client_uri, interval);
910 pjsip_regc_info
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);
941 const char *registration_name = obj;
959 return strcmp(ma, mb) == 0;
966 if (!PJSIP_TRANSPORT_IS_RELIABLE(transport)) {
974 strcpy(monitor, registration_name);
988 static const pj_str_t associated_uri_str = {
"P-Associated-URI", 16 };
989 static const pj_str_t service_route_str = {
"Service-Route", 13 };
991 pjsip_msg *msg = response->
rdata->msg_info.msg;
992 struct ast_sip_service_route_vector *service_routes =
NULL;
1001 while ((header = pjsip_msg_find_hdr_by_name(msg, &service_route_str, header ? header->next :
NULL))) {
1002 char *service_route;
1009 size = pj_strlen(&((pjsip_generic_string_hdr*)header)->hvalue) + 1;
1011 if (!service_route) {
1012 if (service_routes) {
1014 service_routes =
NULL;
1019 ast_copy_pj_str(service_route, &((pjsip_generic_string_hdr*)header)->hvalue, size);
1021 if (!service_routes) {
1023 if (!service_routes) {
1032 service_routes =
NULL;
1038 if (service_routes) {
1045 header = pjsip_msg_find_hdr_by_name(msg, &associated_uri_str, NULL);
1047 char value[pj_strlen(&((pjsip_generic_string_hdr*)header)->hvalue) + 1];
1049 ast_copy_pj_str(value, &((pjsip_generic_string_hdr*)header)->hvalue,
sizeof(value));
1059 pjsip_regc_info
info;
1072 ast_debug(1,
"Processing REGISTER response %d from server '%s' for client '%s'\n",
1073 response->
code, server_uri, client_uri);
1075 if (response->
code == 408 || response->
code == 503) {
1080 if (res == PJ_SUCCESS) {
1085 }
else if ((response->
code == 401 || response->
code == 407)
1089 pjsip_cseq_hdr *cseq_hdr;
1090 pjsip_tx_data *tdata;
1095 ast_debug(1,
"Sending authenticated REGISTER to server '%s' from client '%s'\n",
1096 server_uri, client_uri);
1097 pjsip_tx_data_add_ref(tdata);
1101 cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
1104 pjsip_tx_data_dec_ref(tdata);
1105 if (res == PJ_SUCCESS) {
1110 ast_log(
LOG_WARNING,
"Failed to create authenticated REGISTER request to server '%s' from client '%s'\n",
1111 server_uri, client_uri);
1118 if (PJSIP_IS_STATUS_IN_CLASS(response->
code, 200)) {
1121 int next_registration_round;
1124 ast_debug(1,
"Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri);
1128 if (next_registration_round < 0) {
1130 next_registration_round = 0;
1138 ast_debug(1,
"Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri);
1156 ast_log(
LOG_WARNING,
"Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
1157 server_uri, client_uri);
1164 if (response->
code == 403
1171 ast_log(
LOG_WARNING,
"403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1179 ast_log(
LOG_WARNING,
"'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1184 if (response->
rdata) {
1185 ast_log(
LOG_WARNING,
"Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
1186 response->
code, server_uri, client_uri);
1188 ast_log(
LOG_WARNING,
"Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
1211 int *callback_invoked;
1218 *callback_invoked = 1;
1225 response->
code = param->code;
1234 ast_debug(1,
"Received REGISTER response %d(%.*s)\n",
1235 param->code, (
int) param->reason.slen, param->reason.ptr);
1238 struct pjsip_retry_after_hdr *retry_after;
1239 pjsip_transaction *tsx;
1241 retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
1243 response->
retry_after = retry_after ? retry_after->ivalue : 0;
1252 pjsip_tx_data_dec_ref(client_state->
last_tdata);
1254 tsx = pjsip_rdata_get_tsx(param->rdata);
1257 pjsip_rx_data_clone(param->rdata, 0, &response->
rdata);
1270 ast_log(
LOG_WARNING,
"Failed to pass incoming registration response to threadpool\n");
1280 ast_debug(3,
"Destroying registration state for registration to server '%s' from client '%s'\n",
1291 ast_log(
LOG_WARNING,
"Failed to pass outbound registration client destruction to threadpool\n");
1309 pjsip_tx_data_dec_ref(client_state->
last_tdata);
1384 return registration;
1389 const pj_str_t *target, pjsip_tpselector *selector,
const char *
line,
const char *header_params)
1391 pj_str_t
tmp, local_addr;
1393 pjsip_sip_uri *sip_uri;
1394 pjsip_transport_type_e
type;
1397 pj_strdup_with_null(pool, &tmp, target);
1399 if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
1400 (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1404 sip_uri = pjsip_uri_get_uri(uri);
1406 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
1407 if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
1408 if (type == PJSIP_TRANSPORT_UNSPECIFIED
1409 || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
1410 type = PJSIP_TRANSPORT_TLS;
1412 }
else if (!sip_uri->transport_param.slen) {
1413 type = PJSIP_TRANSPORT_UDP;
1414 }
else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
1418 if (pj_strchr(&sip_uri->host,
':')) {
1419 type |= PJSIP_TRANSPORT_IPV6;
1423 pool, type, selector, &local_addr, &local_port) != PJ_SUCCESS) {
1427 if (!pj_strchr(&sip_uri->host,
':') && pj_strchr(&local_addr,
':')) {
1428 type |= PJSIP_TRANSPORT_IPV6;
1431 contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
1432 contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
1433 "<%s:%s@%s%.*s%s:%d%s%s%s%s>%s%s",
1434 ((pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ?
"sips" :
"sip",
1436 (type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
1437 (
int)local_addr.slen,
1439 (type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
1441 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
1442 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"",
1446 S_OR(header_params,
""));
1489 const char *
url =
"https://www.googleapis.com/oauth2/v3/token";
1497 ast_log(
LOG_ERROR,
"CURL is unavailable. This is required for Google OAuth 2.0 authentication. Please ensure it is loaded.\n");
1502 "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
1508 ast_debug(2,
"Performing Google OAuth 2.0 authentication using command: %s\n", cmd);
1514 ast_log(
LOG_ERROR,
"Could not retrieve Google OAuth 2.0 authentication\n");
1518 ast_debug(2,
"Google OAuth 2.0 authentication returned: %s\n", buf);
1522 ast_log(
LOG_ERROR,
"Could not parse Google OAuth 2.0 authentication: %d(%d) %s: '%s'\n",
1529 ast_log(
LOG_ERROR,
"Could not find Google OAuth 2.0 access_token in: '%s'\n",
1550 const char *access_token;
1551 pjsip_cred_info auth_creds[1];
1552 pjsip_auth_clt_pref prefs;
1556 memset(auths, 0,
sizeof(auths));
1562 for (idx = 0; idx < auth_size; ++idx) {
1563 switch (auths[idx]->
type) {
1565 pj_cstr(&auth_creds[0].username, auths[idx]->
auth_user);
1566 pj_cstr(&auth_creds[0].scheme,
"Bearer");
1567 pj_cstr(&auth_creds[0].
realm, auths[idx]->realm);
1568 ast_debug(2,
"Obtaining Google OAuth access token\n");
1570 if (!access_token) {
1575 ast_debug(2,
"Setting data to '%s'\n", access_token);
1577 pj_cstr(&auth_creds[0].data, access_token);
1578 auth_creds[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
1580 pjsip_regc_set_credentials(regc, 1, auth_creds);
1583 prefs.initial_auth = PJ_TRUE;
1584 pj_cstr(&prefs.algorithm,
"oauth");
1585 pjsip_regc_set_prefs(regc, &prefs);
1587 if (access_token != auths[idx]->
auth_pass) {
1612 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1616 ast_log(
LOG_ERROR,
"Could not create pool for URI validation on outbound registration '%s'\n",
1622 uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1624 ast_log(
LOG_ERROR,
"Invalid server URI '%s' specified on outbound registration '%s'\n",
1631 uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1633 ast_log(
LOG_ERROR,
"Invalid client URI '%s' specified on outbound registration '%s'\n",
1641 uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1643 ast_log(
LOG_ERROR,
"Invalid outbound proxy URI '%s' specified on outbound registration '%s'\n",
1664 pjsip_route_hdr route_set, *route;
1665 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
1668 pj_list_init(&route_set);
1673 &ROUTE_HNAME, tmp.ptr, tmp.slen,
NULL);
1678 pj_list_insert_nodes_before(&route_set, route);
1760 ast_log(
LOG_ERROR,
"No server URI specified on outbound registration '%s'\n",
1764 ast_log(
LOG_ERROR,
"Server URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
1768 ast_log(
LOG_ERROR,
"No client URI specified on outbound registration '%s'\n",
1772 ast_log(
LOG_ERROR,
"Client URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
1776 ast_log(
LOG_ERROR,
"Line support has been enabled on outbound registration '%s' without providing an endpoint\n",
1780 ast_log(
LOG_ERROR,
"An endpoint has been specified on outbound registration '%s' without enabling line support\n",
1787 "No change between old configuration and new configuration on outbound registration '%s'. Using previous state\n",
1864 pjsip_tx_data *tdata;
1865 pjsip_regc_info
info;
1867 pjsip_regc_get_info(client, &info);
1868 ast_debug(1,
"Unregistering contacts with server '%s' from client '%s'\n",
1873 if (pjsip_regc_unregister(client, &tdata) == PJ_SUCCESS
1938 wordlen = strlen(word);
1939 if (wordlen == 0 && ++which > state) {
1945 if (!registrations) {
1953 if (!strncasecmp(word, name, wordlen) && ++which > state) {
1971 const char *registration_name;
1975 e->
command =
"pjsip send unregister";
1977 "Usage: pjsip send unregister <registration> | *all\n" 1978 " Unregisters the specified (or all) outbound registration(s) " 1979 "and stops future registration attempts.\n";
1989 registration_name = a->
argv[3];
1991 if (strcmp(registration_name,
"*all") == 0) {
1993 ast_cli(a->
fd,
"Unregister all queued\n");
1999 ast_cli(a->
fd,
"Unable to retrieve registration %s\n", registration_name);
2004 ast_cli(a->
fd,
"Failed to queue unregistration\n");
2014 const char *registration_name;
2018 e->
command =
"pjsip send register";
2020 "Usage: pjsip send register <registration> | *all \n" 2021 " Unregisters the specified (or all) outbound " 2022 "registration(s) then starts registration(s) and schedules re-registrations.\n";
2032 registration_name = a->
argv[3];
2034 if (strcmp(registration_name,
"*all") == 0) {
2036 ast_cli(a->
fd,
"Re-register all queued\n");
2042 ast_cli(a->
fd,
"Unable to retrieve registration %s\n", registration_name);
2050 ast_cli(a->
fd,
"Failed to queue unregistration\n");
2052 ast_cli(a->
fd,
"Failed to queue registration\n");
2069 if (strcmp(registration_name,
"*all") == 0) {
2101 if (strcmp(registration_name,
"*all") == 0) {
2149 pjsip_regc_info
info;
2189 "outbound registrations\n");
2201 "Registered: %d\r\n" 2202 "NotRegistered: %d\r\n",
2266 " <Registration/ServerURI..............................> <Auth..........> <Status.......>\n");
2277 #define REGISTRATION_URI_FIELD_LEN 53 2315 .
command =
"pjsip list registrations",
2316 .
usage =
"Usage: pjsip list registrations [ like <pattern> ]\n" 2317 " List the configured PJSIP Registrations\n" 2318 " Optional regular expression pattern is used to filter the list.\n"),
2320 .
command =
"pjsip show registrations",
2321 .
usage =
"Usage: pjsip show registrations [ like <pattern> ]\n" 2322 " Show the configured PJSIP Registrations\n" 2323 " Optional regular expression pattern is used to filter the list.\n"),
2325 .
command =
"pjsip show registration",
2326 .
usage =
"Usage: pjsip show registration <id>\n" 2327 " Show the configured PJSIP Registration\n"),
2337 const char *registration_id;
2340 ast_debug(4,
"Auths updated. Checking for any outbound registrations that are in permanent rejected state so they can be retried\n");
2354 ast_debug(4,
"Trying outbound registration '%s' again\n", registration_id);
2358 ast_log(
LOG_ERROR,
"Failed to perform outbound registration on '%s'\n", registration_id);
2379 if (!registration) {
2403 if (strcmp(object_type,
"registration")) {
2456 ast_debug(3,
"Received network change event\n");
2473 cli_formatter =
NULL;
2487 ast_debug(2,
"Waiting for registration transactions to complete for unload.\n");
2495 ast_log(
LOG_WARNING,
"Unload incomplete. Could not stop %d outbound registrations. Try again later.\n",
2503 shutdown_group =
NULL;
2513 if (!shutdown_group) {
2562 &observer_callbacks_registrations)
2564 &observer_callbacks_auth)
2566 ®istration_observer)) {
2577 if (!cli_formatter) {
2582 cli_formatter->
name =
"registration";
2626 .requires =
"res_pjsip",
2627 .optional_modules =
"res_statsd",
struct ast_str * output_buffer
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
unsigned int support_path
Whether Path support is enabled.
struct ao2_container *(* get_container)(const char *regex)
enum sip_cc_notify_state state
unsigned int auth_attempted
Non-zero if we have attempted sending a REGISTER with authentication.
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
static void update_client_state_status(struct sip_outbound_registration_client_state *client_state, enum sip_outbound_registration_status status)
#define AST_CLI_DEFINE(fn, txt,...)
static void registration_transport_monitor_setup(pjsip_transport *transport, const char *registration_name)
static void * cli_retrieve_by_id(const char *id)
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
int ast_sip_auth_vector_init(struct ast_sip_auth_vector *vector, const char *auth_names)
Initialize an auth vector with the configured values.
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
static struct sip_outbound_registration_state * sip_outbound_registration_state_alloc(struct sip_outbound_registration *registration)
Allocator function for registration state.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
#define MAX_UNLOAD_TIMEOUT_TIME
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void(* deleted)(const void *object)
Callback for when an object is deleted.
static const char * fetch_google_access_token(const struct ast_sip_auth *auth)
static char * cli_complete_registration(const char *line, const char *word, int pos, int state)
unsigned int max_retries
Maximum number of retries permitted.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
const ast_string_field oauth_secret
char text[AST_JSON_ERROR_TEXT_LENGTH]
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.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
The arg parameter is a search key, but is not an object.
unsigned int support_outbound
Determines whether SIP Outbound support should be advertised.
static char * my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
pjsip_tx_data * old_request
Request for which the response was received.
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 ast_sip_auth_vector_destroy(struct ast_sip_auth_vector *vector)
Free contents of an auth vector.
descriptor for a cli entry.
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.
enum sip_outbound_registration_status status
Current state of this registration.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static struct ast_sip_endpoint_identifier line_identifier
#define ao2_callback(c, flags, cb_fn, arg)
struct ast_serializer_shutdown_group * ast_serializer_shutdown_group_alloc(void)
Create a serializer group shutdown control object.
struct stasis_message_type * ast_network_change_type(void)
A stasis_message_type for network changes.
static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
Apply function which finds or allocates a state structure.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Structure for variables, used for configurations and for channel variables.
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
const ast_string_field client_uri
URI for the AOR.
int ast_sip_transport_state_set_preferred_identity(const char *transport_name, const char *identity)
Sets the P-Preferred-Identity on a child transport.
static void registration_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Perform no matching, return all objects.
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
static void save_response_fields_to_transport(struct registration_response *response)
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
static struct stasis_subscription * network_change_sub
pj_timer_entry timer
Timer entry for retrying on temporal responses.
Full structure for sorcery.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
static int ami_outbound_registration_task(void *obj)
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Type for a default handler that should do nothing.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
const ast_string_field server_uri
URI for the registrar.
static const struct ast_sorcery_observer observer_callbacks_auth
static int registration_state_hash(const void *obj, const int flags)
hashing function for state objects
Outbound registration state information (persists for lifetime that registration should exist) ...
static int handle_client_state_destruction(void *data)
Callback function for unregistering (potentially) and destroying state.
static int queue_unregister(struct sip_outbound_registration_state *state)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define ao2_global_obj_ref(holder)
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
unsigned int expiration
Requested expiration time.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define ast_sorcery_apply_config(sorcery, name)
Return all matching objects.
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 ao2_alloc_options(data_size, destructor_fn, options)
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Outbound registration client state information (persists for lifetime of regc)
#define ast_strdup(str)
A wrapper for strdup()
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.
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...
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...
static pj_str_t OUTBOUND_NAME
Definitions to aid in the use of thread local storage.
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.
void ast_cli(int fd, const char *fmt,...)
static struct ast_threadstorage register_callback_invoked
static char * cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
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.
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.
static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
#define REGISTRATION_URI_FIELD_LEN
char line[LINE_PARAMETER_SIZE]
Optional line parameter placed into Contact.
Structure for registration response.
unsigned int max_retries
Maximum number of retries permitted.
JSON parsing error information.
static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
Callback function for outbound registration client.
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
unsigned int support_outbound
Whether Outbound support is enabled.
static struct ao2_container * get_registrations(void)
const ast_string_field contact_user
Optional user for contact header.
static struct pjsip_param * get_uri_option_line(const void *uri)
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.
sip_outbound_registration_status
Various states that an outbound registration may be in.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
const ast_string_field oauth_clientid
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
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.
#define ast_strlen_zero(foo)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
static pj_str_t PATH_NAME
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
int ast_sip_failover_request(pjsip_tx_data *tdata)
Set a request to use the next value in the list of resolved addresses.
static void sip_outbound_registration_destroy(void *obj)
Destructor function for registration information.
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
static const struct ast_sorcery_observer registration_observer
static void unregister_all(void)
Type for default option handler for bools (ast_true/ast_false)
static void registration_transport_shutdown_cb(void *obj)
static int sip_outbound_registration_perform(void *data)
Helper function which performs a single registration.
int ast_sip_retrieve_auths(const struct ast_sip_auth_vector *auths, struct ast_sip_auth **out)
Retrieve relevant SIP auth structures from sorcery.
static int can_reuse_registration(struct sip_outbound_registration *existing, struct sip_outbound_registration *applied)
static const char * sip_outbound_registration_status_str(enum sip_outbound_registration_status state)
#define EVENT_FLAG_SYSTEM
#define ast_debug(level,...)
Log a DEBUG message.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
struct sip_outbound_registration_client_state * client_state
Client state information.
#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.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Register a SIP endpoint identifier.
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
static int load_module(void)
Registration is stopping.
const ast_string_field outbound_proxy
Outbound proxy to use.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
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_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Type for default option handler for unsigned integers.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
static int unload_module(void)
Interface for the sorcery instance observer.
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.
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.
#define AST_STRING_FIELD(name)
Declare a string field.
static int ami_register(struct mansession *s, const struct message *m)
#define ao2_ref(o, delta)
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
long int ast_random(void)
#define DEFAULT_STATE_BUCKETS
Default number of state container buckets.
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void *(* retrieve_by_id)(const char *id)
unsigned int support_path
Determines whether SIP Path support should be advertised.
const ast_string_field transport
Explicit transport to use for registration.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
pjsip_tx_data * last_tdata
Last tdata sent We need the original tdata to resend a request on auth failure or timeout...
#define ast_malloc(len)
A wrapper for malloc()
struct ao2_container * container
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_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.
#define ast_variable_new(name, value, filename)
char * registration_name
The name of the registration sorcery object.
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
An entity with which Asterisk communicates.
static void registration_deleted_observer(const void *obj)
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
int ast_sip_format_auths_ami(const struct ast_sip_auth_vector *auths, struct ast_sip_ami *ami)
Format auth details for AMI.
void ast_statsd_log(const char *metric_name, const char *metric_type, intmax_t value)
Send a stat to the configured statsd server.
Core PBX routines and definitions.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
struct ast_sip_service_route_vector * ast_sip_service_route_vector_alloc(void)
Allocate a vector of service routes.
#define stasis_subscribe(topic, callback, data)
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.
static int set_outbound_initial_authentication_credentials(pjsip_regc *regc, const struct ast_sip_auth_vector *auth_vector)
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.
static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
static struct ast_cli_entry cli_outbound_registration[]
struct sip_outbound_registration * registration
Outbound registration configuration object.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
#define REREGISTER_BUFFER_TIME
Amount of buffer time (in seconds) before expiration that we re-register at.
int code
Response code for the registration attempt.
Outbound registration information.
static int ami_show_outbound_registrations(struct mansession *s, const struct message *m)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
void ast_sip_service_route_vector_destroy(struct ast_sip_service_route_vector *service_routes)
Destroy a vector of service routes.
int expiration
Expiration time for registration.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Registration was rejected, permanently.
#define ao2_unlink(container, obj)
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.
const ast_string_field realm
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
static struct sip_outbound_registration_state * get_state(const char *id)
Interface for a sorcery object type observer.
#define ao2_global_obj_release(holder)
static unsigned int monitor
Type for default option handler for bools (ast_true/ast_false)
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
#define ast_sorcery_apply_default(sorcery, type, name, data)
#define LINE_PARAMETER_SIZE
Size of the buffer for creating a unique string for the line.
static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
Helper function to add string to Supported header.
SORCERY_OBJECT(details)
Sorcery object details.
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
static int monitor_matcher(void *a, void *b)
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes. ...
void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
Clean up retrieved auth structures from memory.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
struct ast_taskprocessor * serializer
Serializer for stuff and things.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static AO2_GLOBAL_OBJ_STATIC(current_states)
static int reload_module(void)
const ast_string_field auth_pass
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Module has failed to load, may be in an inconsistent state.
static void * sip_outbound_registration_alloc(const char *name)
Allocator function for registration information.
Vector container support.
#define ao2_find(container, arg, flags)
An API for managing task processing threads that can be shared across modules.
static int queue_register(struct sip_outbound_registration_state *state)
An entity responsible for identifying the source of a SIP message.
const char *(* get_id)(const void *obj)
int ast_sip_transport_state_set_transport(const char *transport_name, pjsip_transport *transport)
Sets the PJSIP transport on a child transport.
static struct registrations registrations
structure to hold users read from users.conf
const ast_string_field refresh_token
static int ami_outbound_registration_detail(void *obj, void *arg, int flags)
static void * cleanup(void *unused)
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
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.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
char * transport_name
The name of the transport to be used for the registration.
static int handle_registration_response(void *data)
Callback function for handling a response to a registration attempt.
static int line_identify_relationship(void *obj, void *arg, int flags)
Callback function for matching an outbound registration based on line.
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.
static int registration_state_cmp(void *obj, void *arg, int flags)
comparator function for state objects
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.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
static int unregister_task(void *obj)
#define EVENT_FLAG_REPORTING
#define AST_STATSD_GAUGE
Support for publishing to a statsd server.
static struct ao2_container * cli_get_container(const char *regex)
#define ao2_global_obj_replace_unref(holder, obj)
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
The arg parameter is an object of the same type.
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.
unsigned int retries
Current number of retries.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
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.
static int outbound_auths_to_str(const void *obj, const intptr_t *args, char **buf)
A ast_taskprocessor structure is a singleton by name.
int ast_sip_validate_uri_length(const char *uri)
#define ao2_replace(dst, src)
static struct ast_sorcery * sorcery
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
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.
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
const ast_string_field endpoint
Endpoint to use for related incoming calls.
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
struct sip_outbound_registration_client_state * client_state
Outbound registration client state.
static struct ao2_container * new_states
Used on [re]loads to hold new state data.
static struct ast_sip_cli_formatter_entry * cli_formatter
static int ami_unregister(struct mansession *s, const struct message *m)
static int cli_print_body(void *obj, void *arg, int flags)
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
int ast_sip_sorcery_object_to_ami(const void *obj, struct ast_str **buf)
Converts a sorcery object to a string of object properties.
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.
static int check_state(void *obj, void *arg, int flags)
struct stasis_forward * sub
static void sip_outbound_registration_state_destroy(void *obj)
Destructor function for registration state.
static void auth_observer(const char *type)
static int cli_print_header(void *obj, void *arg, int flags)
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Abstract JSON element (object, array, string, int, ...).
Type for default option handler for stringfields.
static void schedule_retry(struct registration_response *response, unsigned int interval, const char *server_uri, const char *client_uri)
ao2_callback_fn * print_header
int retry_after
Retry-After value.
static void registration_response_destroy(void *obj)
Registration response structure destructor.
static int handle_client_registration(void *data)
Callback function for registering.
static void sip_outbound_registration_client_state_destroy(void *obj)
Destructor function for client registration state.
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 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.
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
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 sip_outbound_registration * registration
unsigned int destroy
Registration should be destroyed after completion of transaction.
Search option field mask.
static char context[AST_MAX_CONTEXT]
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.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
static pj_timer_heap_t * timer_heap
Global timer heap.
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
ao2_callback_fn * print_body
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define DEBUG_ATLEAST(level)
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
static struct ast_serializer_shutdown_group * shutdown_group
static const struct ast_sorcery_instance_observer observer_callbacks_registrations
const ast_string_field contact_header_params
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 reregister_immediately_cb(void *obj)
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
static void reregister_all(void)
static int outbound_auths_to_var_list(const void *obj, struct ast_variable **fields)
pjsip_rx_data * rdata
The response message.
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.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field auth_user
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define ast_variable_list_append(head, new_var)
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.
Registration was rejected, but response was temporal.
static int sip_outbound_registration_regc_alloc(void *data)
Helper function that allocates a pjsip registration client and configures it.
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.
pjsip_regc * client
Outbound registration client.
static char * cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
unsigned show_details_only_level_0
int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
Registration has been stopped.
static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
Helper function which cancels the timer on a client.
unsigned int line
Whether to add a line parameter to the outbound Contact or not.
#define ao2_link(container, obj)