446#define REREGISTER_BUFFER_TIME 10 
  449#define LINE_PARAMETER_SIZE 8 
  480    str = 
"Unregistered";
 
 
  624#define MAX_UNLOAD_TIMEOUT_TIME     35   
  630#define DEFAULT_STATE_BUCKETS 53 
  662    const char *right_key = arg;
 
 
  712    pjsip_param *line = arg;
 
  714    return !pj_strcmp2(&line->value, 
state->client_state->line) ? 
CMP_MATCH : 0;
 
 
  719    static const pj_str_t LINE_STR = { 
"line", 4 };
 
 
  746    ast_debug(3, 
"Determined relationship to outbound registration '%s' based on line '%s', using configured endpoint '%s'\n",
 
 
  760        &client_state->
timer, client_state->
timer.id)) {
 
 
  787    if (!contact_status) {
 
  794    *ret = contact_status;
 
 
  804    if (!contact_status) {
 
 
  822    pjsip_tx_data *tdata)
 
  824    int add_sec_client_header = 0;
 
  830    static const pj_str_t security_verify = { 
"Security-Verify", 15 };
 
  831    static const pj_str_t security_client = { 
"Security-Client", 15 };
 
  845        if (contact_status) {
 
  856        if (sec_mechs != 
NULL && pjsip_msg_find_hdr_by_name(tdata->msg, &security_verify, 
NULL) == 
NULL) {
 
  863            add_sec_client_header = (pjsip_msg_find_hdr_by_name(tdata->msg, &security_client, 
NULL) == 
NULL) ? 1 : 0;
 
  869    if (add_sec_client_header) {
 
  874    if (contact_status) {
 
 
  884    pjsip_tx_data *tdata)
 
  887    int *callback_invoked;
 
  888    pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
 
  891    if (!callback_invoked) {
 
  892        pjsip_tx_data_dec_ref(tdata);
 
  895    *callback_invoked = 0;
 
  904    pjsip_tx_data_add_ref(tdata);
 
  913        static const pj_str_t user_agent_str = { 
"User-Agent", 10 };
 
  914        pjsip_generic_string_hdr *default_user_agent_hdr;
 
  915        pjsip_generic_string_hdr *user_agent_hdr;
 
  916        pj_str_t user_agent_val;
 
  917        default_user_agent_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &user_agent_str, 
NULL);
 
  918        user_agent_val = pj_str(client_state->
user_agent);
 
  919        user_agent_hdr = pjsip_generic_string_hdr_create(tdata->pool, &user_agent_str, &user_agent_val);
 
  920        if (!user_agent_hdr) {
 
  921            ast_log(
LOG_ERROR, 
"Could not add custom User-Agent to outbound registration %s, sending REGISTER request with non-custom header\n", client_state->
registration_name);
 
  923            if (default_user_agent_hdr) {
 
  924                pj_list_erase(default_user_agent_hdr);
 
  926            pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)user_agent_hdr);
 
  936    pjsip_regc_set_transport(client_state->
client, &selector);
 
  945    if ((
status != PJ_SUCCESS) && !(*callback_invoked)) {
 
  946        pjsip_tx_data_dec_ref(tdata);
 
  957        pjsip_tx_data_dec_ref(client_state->
last_tdata);
 
 
  967    pjsip_supported_hdr *hdr;
 
  970    hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, 
NULL);
 
  973        hdr = pjsip_supported_hdr_create(tdata->pool);
 
  975            pjsip_tx_data_dec_ref(tdata);
 
  979        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
 
  983    for (i = 0; i < hdr->count; ++i) {
 
  984        if (pj_stricmp(&hdr->values[i], 
name) == 0) {
 
  989    if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
 
  994    pj_strassign(&hdr->values[hdr->count++], 
name);
 
 
 1021    pjsip_tx_data *tdata;
 
 1028        || pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS) {
 
 1033        pjsip_regc_info info;
 
 1035        pjsip_regc_get_info(client_state->client, &info);
 
 1036        ast_log(
LOG_DEBUG, 
"Outbound REGISTER attempt %u to '%.*s' with client '%.*s'\n",
 
 1037            client_state->retries + 1,
 
 1038            (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1039            (
int) info.client_uri.slen, info.client_uri.ptr);
 
 
 1073    pj_time_val delay = { .sec = seconds, };
 
 1074    pjsip_regc_info info;
 
 1078    pjsip_regc_get_info(client_state->
client, &info);
 
 1079    ast_debug(1, 
"Scheduling outbound registration to server '%.*s' from client '%.*s' in %d seconds\n",
 
 1080            (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1081            (
int) info.client_uri.slen, info.client_uri.ptr,
 
 1086        ast_log(
LOG_WARNING, 
"Failed to schedule registration to server '%.*s' from client '%.*s'\n",
 
 1087                (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1088                (
int) info.client_uri.slen, info.client_uri.ptr);
 
 
 1096    const char *status_old;
 
 1097    const char *status_new;
 
 1108    if (!strcmp(status_old, status_new)) {
 
 
 1129    if (client_state->
client) {
 
 1130        pjsip_regc_info info;
 
 1131        pjsip_tx_data *tdata;
 
 1133        pjsip_regc_get_info(client_state->
client, &info);
 
 1135        if (info.is_busy == PJ_TRUE) {
 
 1138                "Registration transaction is busy with server '%.*s' from client '%.*s'.\n",
 
 1139                (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1140                (
int) info.client_uri.slen, info.client_uri.ptr);
 
 1146        switch (client_state->
status) {
 
 1151                "Trying to unregister with server '%.*s' from client '%.*s' before destruction.\n",
 
 1152                (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1153                (
int) info.client_uri.slen, info.client_uri.ptr);
 
 1157            if (pjsip_regc_unregister(client_state->
client, &tdata) == PJ_SUCCESS
 
 1171        pjsip_regc_destroy(client_state->
client);
 
 
 1207    if (response->
rdata) {
 
 1208        pjsip_rx_data_free_cloned(response->
rdata);
 
 
 1223    if (
code == PJSIP_SC_REQUEST_TIMEOUT ||
 
 1224        code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
 
 1225        code == PJSIP_SC_BAD_GATEWAY ||
 
 1226        code == PJSIP_SC_SERVICE_UNAVAILABLE ||
 
 1227        code == PJSIP_SC_SERVER_TIMEOUT ||
 
 1228        ((
code == PJSIP_SC_UNAUTHORIZED ||
 
 1229          code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
 
 1231        PJSIP_IS_STATUS_IN_CLASS(
code, 600)) {
 
 
 1239               const char *
server_uri, 
const char *client_uri)
 
 1244    if (response->
rdata) {
 
 1246            "registration attempt to '%s', retrying in '%u'\n",
 
 1250            "registration attempt to '%s', retrying in '%u'\n",
 
 
 1265        pjsip_regc_info info;
 
 1267        pjsip_regc_get_info(
state->client_state->client, &info);
 
 1269            "Outbound registration transport to server '%.*s' from client '%.*s' shutdown\n",
 
 1270            (
int) info.server_uri.slen, info.server_uri.ptr,
 
 1271            (
int) info.client_uri.slen, info.client_uri.ptr);
 
 
 1294    const char *registration_name = obj;
 
 
 1312    return strcmp(ma, mb) == 0;
 
 
 1325    strcpy(monitor, registration_name);
 
 1334        ast_log(
LOG_NOTICE, 
"Failed to register transport monitor for regisration %s: %d\n", registration_name, monitor_res);
 
 
 1341    static const pj_str_t associated_uri_str = { 
"P-Associated-URI", 16 };
 
 1342    static const pj_str_t service_route_str = { 
"Service-Route", 13 };
 
 1344    pjsip_msg *msg = response->
rdata->msg_info.msg;
 
 1355        char *service_route;
 
 1362        size = pj_strlen(&((pjsip_generic_string_hdr*)
header)->hvalue) + 1;
 
 1364        if (!service_route) {
 
 1365            if (service_routes) {
 
 1367                service_routes = 
NULL;
 
 1374        if (!service_routes) {
 
 1376            if (!service_routes) {
 
 1385            service_routes = 
NULL;
 
 1391    if (service_routes) {
 
 1398    header = pjsip_msg_find_hdr_by_name(msg, &associated_uri_str, 
NULL);
 
 1400        char value[pj_strlen(&((pjsip_generic_string_hdr*)
header)->hvalue) + 1];
 
 
 1412    pjsip_regc_info info;
 
 1414    char client_uri[PJSIP_MAX_URL_SIZE];
 
 1426    ast_debug(1, 
"Processing REGISTER response %d from server '%s' for client '%s'\n",
 
 1429    if (response->
code == 408 || response->
code == 503) {
 
 1434            if (res == PJ_SUCCESS) {
 
 1439    } 
else if ((response->
code == 401 || response->
code == 407 || response->
code == 494)
 
 1443        pjsip_cseq_hdr *cseq_hdr;
 
 1444        pjsip_tx_data *tdata;
 
 1450            pjsip_generic_string_hdr *
header;
 
 1452            static const pj_str_t security_server = { 
"Security-Server", 15 };
 
 1462            header = pjsip_msg_find_hdr_by_name(response->
rdata->msg_info.msg, &security_server, 
NULL);
 
 1464                header = pjsip_msg_find_hdr_by_name(response->
rdata->msg_info.msg, &security_server, 
header->
next)) {
 
 1468            if (contact_container) {
 
 1480        if (response->
code == 494) {
 
 1489            ast_debug(1, 
"Sending authenticated REGISTER to server '%s' from client '%s'\n",
 
 1491            pjsip_tx_data_add_ref(tdata);
 
 1496            cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
 
 1499            pjsip_tx_data_dec_ref(tdata);
 
 1500            if (res == PJ_SUCCESS) {
 
 1505            ast_log(
LOG_WARNING, 
"Failed to create authenticated REGISTER request to server '%s' from client '%s'\n",
 
 1513    if (PJSIP_IS_STATUS_IN_CLASS(response->
code, 200)) {
 
 1516            int next_registration_round;
 
 1519            ast_debug(1, 
"Outbound registration to '%s' with client '%s' successful\n", 
server_uri, client_uri);
 
 1523            if (next_registration_round < 0) {
 
 1525                next_registration_round = 0;
 
 1530            if (PJSIP_TRANSPORT_IS_RELIABLE(response->
rdata->tp_info.transport)) {
 
 1535            ast_debug(1, 
"Outbound unregistration to '%s' with client '%s' successful\n", 
server_uri, client_uri);
 
 1537            if (PJSIP_TRANSPORT_IS_RELIABLE(response->
rdata->tp_info.transport)) {
 
 1555            ast_log(
LOG_WARNING, 
"Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
 
 1563        if (response->
code == 403
 
 1570            ast_log(
LOG_WARNING, 
"403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
 
 1578            ast_log(
LOG_WARNING, 
"'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
 
 1583            if (response->
rdata) {
 
 1584                ast_log(
LOG_WARNING, 
"Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
 
 1587                ast_log(
LOG_WARNING, 
"Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
 
 
 1610    int *callback_invoked;
 
 1617    *callback_invoked = 1;
 
 1624    response->
code = param->code;
 
 1633    ast_debug(1, 
"Received REGISTER response %d(%.*s)\n",
 
 1634        param->code, (
int) param->reason.slen, param->reason.ptr);
 
 1637        struct pjsip_retry_after_hdr *retry_after;
 
 1638        pjsip_transaction *tsx;
 
 1640        retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
 
 1642        response->
retry_after = retry_after ? retry_after->ivalue : 0;
 
 1651        pjsip_tx_data_dec_ref(client_state->
last_tdata);
 
 1653        tsx = pjsip_rdata_get_tsx(param->rdata);
 
 1656        pjsip_rx_data_clone(param->rdata, 0, &response->
rdata);
 
 1672        ast_log(
LOG_WARNING, 
"Failed to pass incoming registration response to threadpool\n");
 
 
 1682    ast_debug(3, 
"Destroying registration state for registration to server '%s' from client '%s'\n",
 
 1683        state->registration ? 
state->registration->server_uri : 
"",
 
 1684        state->registration ? 
state->registration->client_uri : 
"");
 
 1687    if (!
state->client_state) {
 
 1689    } 
else if (!
state->client_state->serializer) {
 
 1693        ast_log(
LOG_WARNING, 
"Failed to pass outbound registration client destruction to threadpool\n");
 
 
 1712        pjsip_tx_data_dec_ref(client_state->
last_tdata);
 
 
 1728    if (!
state->client_state) {
 
 1734    pj_timer_entry_init(&
state->client_state->timer, 0, 
state->client_state,
 
 1737    state->client_state->registration_name =
 
 1745    if (!
state->client_state->transport_name
 
 1746        || !
state->client_state->registration_name) {
 
 1757    if (!
state->client_state->serializer) {
 
 
 1789    return registration;
 
 
 1794    const pj_str_t *target, pjsip_tpselector *selector, 
const char *
line, 
const char *header_params)
 
 1796    pj_str_t tmp, local_addr;
 
 1798    pjsip_sip_uri *sip_uri;
 
 1799    pjsip_transport_type_e 
type;
 
 1802    pj_strdup_with_null(pool, &tmp, target);
 
 1804    if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
 
 1805        (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
 
 1809    sip_uri = pjsip_uri_get_uri(uri);
 
 1811    type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
 
 1812    if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
 
 1813        if (
type == PJSIP_TRANSPORT_UNSPECIFIED
 
 1814            || !(pjsip_transport_get_flag_from_type(
type) & PJSIP_TRANSPORT_SECURE)) {
 
 1815            type = PJSIP_TRANSPORT_TLS;
 
 1817    } 
else if (!sip_uri->transport_param.slen) {
 
 1818        type = PJSIP_TRANSPORT_UDP;
 
 1819    } 
else if (
type == PJSIP_TRANSPORT_UNSPECIFIED) {
 
 1823    if (pj_strchr(&sip_uri->host, 
':')) {
 
 1824        type |= PJSIP_TRANSPORT_IPV6;
 
 1828        pool, 
type, selector, &local_addr, &local_port) != PJ_SUCCESS) {
 
 1832    if (!pj_strchr(&sip_uri->host, 
':') && pj_strchr(&local_addr, 
':')) {
 
 1833        type |= PJSIP_TRANSPORT_IPV6;
 
 1836    contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
 
 1837    contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
 
 1838        "<%s:%s@%s%.*s%s:%d%s%s%s%s>%s%s",
 
 1839        ((pjsip_transport_get_flag_from_type(
type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ? 
"sips" : 
"sip",
 
 1841        (
type & PJSIP_TRANSPORT_IPV6) ? 
"[" : 
"",
 
 1842        (int)local_addr.slen,
 
 1844        (
type & PJSIP_TRANSPORT_IPV6) ? 
"]" : 
"",
 
 1846        (
type != PJSIP_TRANSPORT_UDP && 
type != PJSIP_TRANSPORT_UDP6) ? 
";transport=" : 
"",
 
 1847        (
type != PJSIP_TRANSPORT_UDP && 
type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(
type) : 
"",
 
 1851        S_OR(header_params, 
""));
 
 
 1894    const char *
url = 
"https://www.googleapis.com/oauth2/v3/token";
 
 1902        ast_log(
LOG_ERROR, 
"CURL is unavailable. This is required for Google OAuth 2.0 authentication. Please ensure it is loaded.\n");
 
 1907        "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
 
 1913    ast_debug(2, 
"Performing Google OAuth 2.0 authentication using command: %s\n", cmd);
 
 1919        ast_log(
LOG_ERROR, 
"Could not retrieve Google OAuth 2.0 authentication\n");
 
 1923    ast_debug(2, 
"Google OAuth 2.0 authentication returned: %s\n", 
buf);
 
 1927        ast_log(
LOG_ERROR, 
"Could not parse Google OAuth 2.0 authentication: %d(%d) %s: '%s'\n",
 
 1934        ast_log(
LOG_ERROR, 
"Could not find Google OAuth 2.0 access_token in: '%s'\n",
 
 
 1955    const char *access_token;
 
 1956    pjsip_cred_info auth_creds[1];
 
 1957    pjsip_auth_clt_pref prefs;
 
 1961    memset(auths, 0, 
sizeof(auths));
 
 1967    for (idx = 0; idx < auth_size; ++idx) {
 
 1968        switch (auths[idx]->
type) {
 
 1970            pj_cstr(&auth_creds[0].username, auths[idx]->
auth_user);
 
 1971            pj_cstr(&auth_creds[0].scheme, 
"Bearer");
 
 1972            pj_cstr(&auth_creds[0].
realm, auths[idx]->
realm);
 
 1973            ast_debug(2, 
"Obtaining Google OAuth access token\n");
 
 1975            if (!access_token) {
 
 1980            ast_debug(2, 
"Setting data to '%s'\n", access_token);
 
 1982            pj_cstr(&auth_creds[0].data, access_token);
 
 1983            auth_creds[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
 
 1985            pjsip_regc_set_credentials(regc, 1, auth_creds);
 
 1988            prefs.initial_auth = PJ_TRUE;
 
 1989            pj_cstr(&prefs.algorithm, 
"oauth");
 
 1990            pjsip_regc_set_prefs(regc, &prefs);
 
 1992            if (access_token != auths[idx]->
auth_pass) {
 
 
 2016    pj_str_t 
server_uri, client_uri, contact_uri;
 
 2017    pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
 
 2021        ast_log(
LOG_ERROR, 
"Could not create pool for URI validation on outbound registration '%s'\n",
 
 2027    uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
 
 2029        ast_log(
LOG_ERROR, 
"Invalid server URI '%s' specified on outbound registration '%s'\n",
 
 2036    uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
 
 2038        ast_log(
LOG_ERROR, 
"Invalid client URI '%s' specified on outbound registration '%s'\n",
 
 2049            &
state->client_state->client) != PJ_SUCCESS) {
 
 2054    pjsip_regc_set_transport(
state->client_state->client, &selector);
 
 2057        pjsip_route_hdr route_set, *route;
 
 2058        static const pj_str_t ROUTE_HNAME = { 
"Route", 5 };
 
 2061        pj_list_init(&route_set);
 
 2063        pj_strdup2_with_null(pjsip_regc_get_pool(
state->client_state->client), &tmp,
 
 2065        route = pjsip_parse_hdr(pjsip_regc_get_pool(
state->client_state->client),
 
 2066            &ROUTE_HNAME, tmp.ptr, tmp.slen, 
NULL);
 
 2071        pj_list_insert_nodes_before(&route_set, route);
 
 2073        pjsip_regc_set_route_set(
state->client_state->client, &route_set);
 
 2076    if (
state->registration->line) {
 
 2092    if (pjsip_regc_init(
state->client_state->client, &
server_uri, &client_uri,
 
 
 2127    state->client_state->retries = 0;
 
 2134    pjsip_regc_update_expires(
state->client_state->client, registration->
expiration);
 
 
 2161        ast_log(
LOG_ERROR, 
"No server URI specified on outbound registration '%s'\n",
 
 2165            ast_log(
LOG_ERROR, 
"Server URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
 
 2169        ast_log(
LOG_ERROR, 
"No client URI specified on outbound registration '%s'\n",
 
 2173            ast_log(
LOG_ERROR, 
"Client URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
 
 2177        ast_log(
LOG_ERROR, 
"Line support has been enabled on outbound registration '%s' without providing an endpoint\n",
 
 2181        ast_log(
LOG_ERROR, 
"An endpoint has been specified on outbound registration '%s' without enabling line support\n",
 
 2188            "No change between old configuration and new configuration on outbound registration '%s'. Using previous state\n",
 
 
 2299    struct pjsip_regc *client = 
state->client_state->client;
 
 2300    pjsip_tx_data *tdata;
 
 2301    pjsip_regc_info info;
 
 2303    pjsip_regc_get_info(client, &info);
 
 2304    ast_debug(1, 
"Unregistering contacts with server '%s' from client '%s'\n",
 
 2305        state->registration->server_uri, 
state->registration->client_uri);
 
 2309    if (pjsip_regc_unregister(client, &tdata) == PJ_SUCCESS
 
 
 2374    wordlen = strlen(
word);
 
 2375    if (wordlen == 0 && ++which > 
state) {
 
 
 2407    const char *registration_name;
 
 2411        e->
command = 
"pjsip send unregister";
 
 2413            "Usage: pjsip send unregister <registration> | *all\n" 
 2414            "       Unregisters the specified (or all) outbound registration(s) " 
 2415            "and stops future registration attempts.\n";
 
 2425    registration_name = 
a->argv[3];
 
 2427    if (strcmp(registration_name, 
"*all") == 0) {
 
 2429        ast_cli(
a->fd, 
"Unregister all queued\n");
 
 2435        ast_cli(
a->fd, 
"Unable to retrieve registration %s\n", registration_name);
 
 2440        ast_cli(
a->fd, 
"Failed to queue unregistration\n");
 
 
 2450    const char *registration_name;
 
 2454        e->
command = 
"pjsip send register";
 
 2456            "Usage: pjsip send register <registration> | *all \n" 
 2457            "       Unregisters the specified (or all) outbound " 
 2458            "registration(s) then starts registration(s) and schedules re-registrations.\n";
 
 2468    registration_name = 
a->argv[3];
 
 2470    if (strcmp(registration_name, 
"*all") == 0) {
 
 2472        ast_cli(
a->fd, 
"Re-register all queued\n");
 
 2478        ast_cli(
a->fd, 
"Unable to retrieve registration %s\n", registration_name);
 
 2486        ast_cli(
a->fd, 
"Failed to queue unregistration\n");
 
 2488        ast_cli(
a->fd, 
"Failed to queue registration\n");
 
 
 2505    if (strcmp(registration_name, 
"*all") == 0) {
 
 
 2537    if (strcmp(registration_name, 
"*all") == 0) {
 
 
 2585        pjsip_regc_info info;
 
 2596        pjsip_regc_get_info(
state->client_state->client, &info);
 
 
 2611    ami->registration = obj;
 
 
 2625                  "outbound registrations\n");
 
 2637        "Registered: %d\r\n" 
 2638        "NotRegistered: %d\r\n",
 
 
 2702        " <Registration/ServerURI..............................>  <Auth....................>  <Status.......>\n");
 
 
 2714#define REGISTRATION_URI_FIELD_LEN  53 
 2717    expsecs = 
state ? 
state->client_state->registration_expires - ((int) time(
NULL)) : 0;
 
 2719    ast_str_append(&context->output_buffer, 0, 
" %-s/%-*.*s  %-26s  %-16s %s%d%s\n",
 
 2728        state ? 
" (exp. " : 
"", 
abs(expsecs), 
state ? (expsecs < 0 ? 
"s ago)" : 
"s)") : 
"");
 
 2731    if (context->show_details
 
 2732        || (context->show_details_only_level_0 && context->indent_level == 0)) {
 
 
 2754        .
command = 
"pjsip list registrations",
 
 2755        .
usage = 
"Usage: pjsip list registrations [ like <pattern> ]\n" 
 2756                "       List the configured PJSIP Registrations\n" 
 2757                "       Optional regular expression pattern is used to filter the list.\n"),
 
 2759        .
command = 
"pjsip show registrations",
 
 2760        .
usage = 
"Usage: pjsip show registrations [ like <pattern> ]\n" 
 2761                "       Show the configured PJSIP Registrations\n" 
 2762                "       Optional regular expression pattern is used to filter the list.\n"),
 
 2764        .
command = 
"pjsip show registration",
 
 2765        .
usage = 
"Usage: pjsip show registration <id>\n" 
 2766                 "       Show the configured PJSIP Registration\n"),
 
 
 2776    const char *registration_id;
 
 2779    ast_debug(4, 
"Auths updated. Checking for any outbound registrations that are in permanent rejected state so they can be retried\n");
 
 2793            ast_debug(4, 
"Trying outbound registration '%s' again\n", registration_id);
 
 2797                ast_log(
LOG_ERROR, 
"Failed to perform outbound registration on '%s'\n", registration_id);
 
 
 2818    if (!registration) {
 
 
 2840    if (strcmp(object_type, 
"registration")) {
 
 
 2893    ast_debug(3, 
"Received network change event\n");
 
 
 2924    ast_debug(2, 
"Waiting for registration transactions to complete for unload.\n");
 
 2932        ast_log(
LOG_WARNING, 
"Unload incomplete.  Could not stop %d outbound registrations.  Try again later.\n",
 
 
 3067    .
requires = 
"res_pjsip",
 
 3068    .optional_modules = 
"res_statsd",
 
void ast_cli_unregister_multiple(void)
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_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
#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 struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
Standard Command Line Interface.
#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.
const char * astman_get_header(const struct message *m, char *var)
Get header from 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,...)
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_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
#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 struct ast_sorcery * sorcery
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
struct ao2_container * container
struct pjsip_param * ast_sip_pjsip_uri_get_other_param(pjsip_uri *uri, const pj_str_t *param_str)
Find an 'other' SIP/SIPS URI parameter by name.
void ast_sip_header_to_security_mechanism(const pjsip_generic_string_hdr *hdr, struct ast_sip_security_mechanism_vector *security_mechanisms)
Append to security mechanism vector from SIP header.
int ast_sip_set_security_negotiation(enum ast_sip_security_negotiation *security_negotiation, const char *val)
Set the security negotiation based on a given string.
void ast_sip_security_mechanisms_vector_copy(struct ast_sip_security_mechanism_vector *dst, const struct ast_sip_security_mechanism_vector *src)
Duplicate a security mechanism.
int ast_sip_transport_state_set_transport(const char *transport_name, pjsip_transport *transport)
Sets the PJSIP transport on a child transport.
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.
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.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Register a SIP endpoint identifier.
#define AST_SIP_MAKE_REMOTE_IPADDR_PORT_STR(_transport, _dest)
Fill a buffer with a pjsip transport's remote ip address and port.
int ast_sip_retrieve_auths(const struct ast_sip_auth_vector *auths, struct ast_sip_auth **out)
Retrieve relevant SIP auth structures from sorcery.
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_security_mechanisms_vector_destroy(struct ast_sip_security_mechanism_vector *security_mechanisms)
Free contents of a security mechanism vector.
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.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *ao2_data, ast_transport_monitor_data_matcher matches)
Register a reliable transport shutdown monitor callback replacing any duplicate.
int ast_sip_security_mechanisms_to_str(const struct ast_sip_security_mechanism_vector *security_mechanisms, int add_qvalue, char **buf)
Writes the security mechanisms of an endpoint into a buffer as a string and returns the buffer.
#define IP6ADDR_COLON_PORT_BUFLEN
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
struct ast_sip_service_route_vector * ast_sip_service_route_vector_alloc(void)
Allocate a vector of service routes.
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
ast_transport_monitor_reg
struct ao2_container * ast_sip_location_retrieve_contacts_from_aor_list(const char *aor_list)
Retrieve all contacts from a list of AORs.
void ast_sip_remove_headers_by_name_and_value(pjsip_msg *msg, const pj_str_t *hdr_name, const char *value)
Removes all headers of a specific name and value from a pjsip_msg.
void ast_sip_auth_vector_destroy(struct ast_sip_auth_vector *vector)
Free contents of an auth vector.
ast_sip_security_negotiation
The kind of security negotiation.
@ AST_SIP_SECURITY_NEG_MEDIASEC
@ AST_SIP_SECURITY_NEG_NONE
int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
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.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
struct ast_sip_contact_status * ast_sip_get_contact_status(const struct ast_sip_contact *contact)
Retrieve the current status for a contact.
int ast_sip_security_mechanism_vector_init(struct ast_sip_security_mechanism_vector *security_mechanism, const char *value)
Initialize security mechanism vector from string of security mechanisms.
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 ast_sip_transport_monitor_unregister_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
int ast_sip_add_security_headers(struct ast_sip_security_mechanism_vector *security_mechanisms, const char *header_name, int add_qval, pjsip_tx_data *tdata)
Add security headers to transmission data.
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.
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 int sip_outbound_registration_regc_alloc(void *data)
Helper function that allocates a pjsip registration client and configures it.
static void save_response_fields_to_transport(struct registration_response *response)
static void * sip_outbound_registration_alloc(const char *name)
Allocator function for registration information.
#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 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 char * cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#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 struct pjsip_param * get_uri_option_line(const void *uri)
static void add_security_headers(struct sip_outbound_registration_client_state *client_state, pjsip_tx_data *tdata)
Adds security negotiation mechanisms of outbound registration client state as Security headers to tda...
static int handle_client_registration(void *data)
Callback function for registering.
#define DEFAULT_STATE_BUCKETS
Default number of state container buckets.
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 void registration_transport_monitor_setup(const char *transport_key, const char *registration_name)
static int ami_register(struct mansession *s, const struct message *m)
static pj_str_t PATH_NAME
static int contact_has_security_mechanisms(void *obj, void *arg, int flags)
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 * fetch_google_access_token(const struct ast_sip_auth *auth)
Get google oauth2 access token using refresh token.
static int contact_add_security_headers_to_status(void *obj, void *arg, int flags)
static int security_negotiation_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static struct sip_outbound_registration_state * get_state(const char *id)
static int security_mechanisms_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static void registration_response_destroy(void *obj)
Registration response structure destructor.
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 sip_outbound_registration_client_state_destroy(void *obj)
Destructor function for client registration state.
static int reload_module(void)
static int reregister_immediately_cb(void *obj)
static int security_mechanism_to_str(const void *obj, const intptr_t *args, char **buf)
static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
Helper function to add string to Supported header.
static struct sip_outbound_registration_state * sip_outbound_registration_state_alloc(struct sip_outbound_registration *registration)
Allocator function for registration state.
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 const char * sip_outbound_registration_status_str(enum sip_outbound_registration_status state)
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 * cli_retrieve_by_id(const char *id)
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 char * cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 ao2_container * cli_get_container(const char *regex)
static char * cli_complete_registration(const char *line, const char *word, int pos, int state)
static void sip_outbound_registration_destroy(void *obj)
Destructor function for registration information.
static const char * security_negotiation_map[]
static pj_str_t OUTBOUND_NAME
static struct stasis_subscription * network_change_sub
static struct ao2_container * get_registrations(void)
static int load_module(void)
static int cli_print_body(void *obj, void *arg, int flags)
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 security_negotiation_to_str(const void *obj, const intptr_t *args, char **buf)
static char * my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 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.
int ast_sip_validate_uri_length(const char *uri)
static void cleanup(void)
Clean up any old apps that we don't need any more.
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.
struct ast_serializer_shutdown_group * ast_serializer_shutdown_group_alloc(void)
Create a serializer group shutdown control object.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
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_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
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.
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.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
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.
#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.
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.
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.
@ 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_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
#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_OPTIONAL_API_NAME() 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_OPTIONAL_API_NAME() 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_OPTIONAL_API_NAME() 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.
#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 *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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
void *(* retrieve_by_id)(const char *id)
const char *(* get_id)(const void *obj)
ao2_callback_fn * print_body
struct ao2_container *(* get_container)(const char *regex)
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.
const ast_string_field aors
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.
char transport_key[IP6ADDR_COLON_PORT_BUFLEN]
Key for the reliable transport in use.
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.
char * user_agent
The value for the User-Agent header sent in requests.
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.
enum ast_sip_security_negotiation security_negotiation
Type of security negotiation to use (RFC 3329).
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.
int last_status_code
Status code of last response if we have tried to register before.
unsigned int registration_expires
Expected time of registration lapse/expiration.
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
unsigned int destroy
Registration should be destroyed after completion of transaction.
struct ast_sip_security_mechanism_vector server_security_mechanisms
Security mechanisms of the peer (RFC 3329).
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.
struct ast_sip_security_mechanism_vector security_mechanisms
Client security mechanisms (RFC 3329).
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.
enum ast_sip_security_negotiation security_negotiation
Type of security negotiation to use (RFC 3329).
unsigned int support_path
Whether Path support is enabled.
const ast_string_field contact_header_params
const ast_string_field outbound_proxy
unsigned int max_random_initial_delay
Maximum random initial delay interval for initial registrations.
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 user_agent
const ast_string_field client_uri
unsigned int line
Whether to add a line parameter to the outbound Contact or not.
struct ast_sip_security_mechanism_vector security_mechanisms
Client security mechanisms (RFC 3329).
const ast_string_field contact_user
structure to hold users read from phoneprov_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).
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)
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
Vector container support.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_FREE(vec)
Deallocates this 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_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.