static char *complete_mailbox(const char *word, int state) { struct ao2_iterator iter; int wordlen = strlen(word); int which = 0; char *ret = NULL; char *regex; const struct ast_mwi_mailbox_object *mailbox; RAII_VAR(struct ao2_container *, mailboxes, NULL, ao2_cleanup); regex = ast_alloca(2 + wordlen); sprintf(regex, "^%s", word);/* Safe */ mailboxes = ast_mwi_mailbox_get_by_regex(regex); if (!mailboxes) { return NULL; } iter = ao2_iterator_init(mailboxes, 0); for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) { if (++which > state) { ret = ast_strdup(ast_sorcery_object_get_id(mailbox)); ast_mwi_mailbox_unref(mailbox); break; } } ao2_iterator_destroy(&iter); return ret; }
/*! * \brief Explicitly shutdown a session. * * \details An explicit shutdown is necessary, since the \ref stasis_app has a reference * to this session. We also need to be sure to null out the \c ws_session field, * since the websocket is about to go away. * * \internal * * \param session Event session object (\ref event_session). */ static void event_session_shutdown(struct event_session *session) { struct ao2_iterator i; char *app; int j; SCOPED_AO2LOCK(lock, session); /* Clean up the websocket_apps container */ if (session->websocket_apps) { i = ao2_iterator_init(session->websocket_apps, 0); while ((app = ao2_iterator_next(&i))) { stasis_app_unregister(app); ao2_cleanup(app); } ao2_iterator_destroy(&i); ao2_cleanup(session->websocket_apps); session->websocket_apps = NULL; } /* Clean up the message_queue container */ for (j = 0; j < AST_VECTOR_SIZE(&session->message_queue); j++) { struct ast_json *msg = AST_VECTOR_GET(&session->message_queue, j); ast_json_unref(msg); } AST_VECTOR_FREE(&session->message_queue); /* Remove the handle to the underlying websocket session */ session->ws_session = NULL; }
/*! * \internal * \brief Do completion on the endpoint. */ static char *cli_complete_endpoint(const char *word, int state) { char *result = NULL; int wordlen = strlen(word); int which = 0; struct ast_sip_endpoint *endpoint; RAII_VAR(struct ao2_container *, endpoints, ast_sip_get_endpoints(), ao2_cleanup); struct ao2_iterator i = ao2_iterator_init(endpoints, 0); while ((endpoint = ao2_iterator_next(&i))) { const char *name = ast_sorcery_object_get_id(endpoint); if (!strncasecmp(word, name, wordlen) && ++which > state) { result = ast_strdup(name); } ao2_cleanup(endpoint); if (result) { break; } } ao2_iterator_destroy(&i); return result; }
static int get_write_timeout(void) { int write_timeout = -1; struct ao2_container *transport_states; transport_states = ast_sip_get_transport_states(); if (transport_states) { struct ao2_iterator it_transport_states = ao2_iterator_init(transport_states, 0); struct ast_sip_transport_state *transport_state; for (; (transport_state = ao2_iterator_next(&it_transport_states)); ao2_cleanup(transport_state)) { struct ast_sip_transport *transport; if (transport_state->type != AST_TRANSPORT_WS && transport_state->type != AST_TRANSPORT_WSS) { continue; } transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id); ast_debug(5, "Found %s transport with write timeout: %d\n", transport->type == AST_TRANSPORT_WS ? "WS" : "WSS", transport->write_timeout); write_timeout = MAX(write_timeout, transport->write_timeout); } ao2_iterator_destroy(&it_transport_states); ao2_cleanup(transport_states); } if (write_timeout < 0) { write_timeout = AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT; } ast_debug(1, "Write timeout for WS/WSS transports: %d\n", write_timeout); return write_timeout; }
int control_prestart_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan) { struct ao2_container *command_queue; int count = 0; struct ao2_iterator iter; struct stasis_app_command *command; ast_channel_lock(chan); command_queue = command_prestart_get_container(chan); ast_channel_unlock(chan); if (!command_queue) { return 0; } iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK); while ((command = ao2_iterator_next(&iter))) { command_invoke(command, control, chan); ao2_cleanup(command); ++count; } ao2_iterator_destroy(&iter); ao2_cleanup(command_queue); return count; }
/*! \brief Helper function which returns a UDP transport bound to the given address and port */ static pjsip_transport *multihomed_get_udp_transport(pj_str_t *address, int port) { struct ao2_container *transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL); struct ast_sip_transport *transport; struct ao2_iterator iter; pjsip_transport *sip_transport = NULL; if (!transports) { return NULL; } for (iter = ao2_iterator_init(transports, 0); (transport = ao2_iterator_next(&iter)); ao2_ref(transport, -1)) { if ((transport->type != AST_TRANSPORT_UDP) || (pj_strcmp(&transport->state->transport->local_name.host, address)) || (transport->state->transport->local_name.port != port)) { continue; } sip_transport = transport->state->transport; ao2_ref(transport, -1); break; } ao2_iterator_destroy(&iter); ao2_ref(transports, -1); return sip_transport; }
struct ast_json *stasis_app_mailboxes_to_json() { struct ast_json *array = ast_json_array_create(); struct ao2_container *mailboxes; struct ao2_iterator iter; const struct ast_mwi_mailbox_object *mailbox; if (!array) { return NULL; } mailboxes = ast_mwi_mailbox_get_all(); if (!mailboxes) { ast_json_unref(array); return NULL; } iter = ao2_iterator_init(mailboxes, 0); for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) { struct ast_json *appending = mailbox_to_json(mailbox); if (!appending || ast_json_array_append(array, appending)) { /* Failed to append individual mailbox to the array. Abort. */ ast_json_unref(array); array = NULL; break; } } ao2_iterator_destroy(&iter); return array; }
void stasis_app_set_global_debug(int debug) { global_debug = debug; if (!global_debug) { struct ao2_container *app_names = stasis_app_get_all(); struct ao2_iterator it_app_names; char *app_name; struct stasis_app *app; if (!app_names || !ao2_container_count(app_names)) { ao2_cleanup(app_names); return; } it_app_names = ao2_iterator_init(app_names, 0); while ((app_name = ao2_iterator_next(&it_app_names))) { if ((app = stasis_app_get_by_name(app_name))) { stasis_app_set_debug(app, 0); } ao2_cleanup(app_name); ao2_cleanup(app); } ao2_iterator_cleanup(&it_app_names); ao2_cleanup(app_names); } }
/*! * \internal * \brief Shutdown the local proxy channel. * \since 12.0.0 * * \return Nothing */ static void local_shutdown(void) { struct local_pvt *p; struct ao2_iterator it; /* First, take us out of the channel loop */ ast_cli_unregister_multiple(cli_local, ARRAY_LEN(cli_local)); ast_manager_unregister("LocalOptimizeAway"); ast_channel_unregister(&local_tech); it = ao2_iterator_init(locals, 0); while ((p = ao2_iterator_next(&it))) { if (p->base.owner) { ast_softhangup(p->base.owner, AST_SOFTHANGUP_APPUNLOAD); } ao2_ref(p, -1); } ao2_iterator_destroy(&it); ao2_ref(locals, -1); locals = NULL; ao2_cleanup(local_tech.capabilities); local_tech.capabilities = NULL; STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_begin_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_end_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_local_bridge_type); }
static char *complete_show_sorcery_object(struct ao2_container *container, struct ast_sip_cli_formatter_entry *formatter_entry, const char *word, int state) { char *result = NULL; int wordlen = strlen(word); int which = 0; struct ao2_iterator i = ao2_iterator_init(container, 0); void *object; while ((object = ao2_t_iterator_next(&i, "iterate thru endpoints table"))) { const char *id = formatter_entry->get_id(object); if (!strncasecmp(word, id, wordlen) && ++which > state) { result = ast_strdup(id); } ao2_t_ref(object, -1, "toss iterator endpoint ptr before break"); if (result) { break; } } ao2_iterator_destroy(&i); return result; }
/*! \brief Function which adds ICE attributes to a media stream */ static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media) { struct ast_rtp_engine_ice *ice; struct ao2_container *candidates; const char *username, *password; pj_str_t stmp; pjmedia_sdp_attr *attr; struct ao2_iterator it_candidates; struct ast_rtp_engine_ice_candidate *candidate; if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) || !(candidates = ice->get_local_candidates(session_media->rtp))) { return; } if ((username = ice->get_ufrag(session_media->rtp))) { attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username)); media->attr[media->attr_count++] = attr; } if ((password = ice->get_password(session_media->rtp))) { attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password)); media->attr[media->attr_count++] = attr; } it_candidates = ao2_iterator_init(candidates, 0); for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) { struct ast_str *attr_candidate = ast_str_create(128); ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport, candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address)); ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address)); switch (candidate->type) { case AST_RTP_ICE_CANDIDATE_TYPE_HOST: ast_str_append(&attr_candidate, -1, "host"); break; case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX: ast_str_append(&attr_candidate, -1, "srflx"); break; case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED: ast_str_append(&attr_candidate, -1, "relay"); break; } if (!ast_sockaddr_isnull(&candidate->relay_address)) { ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address)); ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address)); } attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate))); media->attr[media->attr_count++] = attr; ast_free(attr_candidate); } ao2_iterator_destroy(&it_candidates); ao2_ref(candidates, -1); }
int parking_lot_get_space(struct parking_lot *lot, int target_override) { int original_target; int current_target; struct ao2_iterator i; struct parked_user *user; int wrap; if (lot->cfg->parkfindnext) { /* Use next_space if the lot already has next_space set; otherwise use lot start. */ original_target = lot->next_space ? lot->next_space : lot->cfg->parking_start; } else { original_target = lot->cfg->parking_start; } if (target_override >= lot->cfg->parking_start && target_override <= lot->cfg->parking_stop) { original_target = target_override; } current_target = original_target; wrap = lot->cfg->parking_start; i = ao2_iterator_init(lot->parked_users, 0); while ((user = ao2_iterator_next(&i))) { /* Increment the wrap on each pass until we find an empty space */ if (wrap == user->parking_space) { wrap += 1; } if (user->parking_space < current_target) { /* It's lower than the anticipated target, so we haven't reached the target yet. */ ao2_ref(user, -1); continue; } if (user->parking_space > current_target) { /* The current target is usable because all items below have been read and the next target is higher than the one we want. */ ao2_ref(user, -1); break; } /* We found one already parked here. */ current_target += 1; ao2_ref(user, -1); } ao2_iterator_destroy(&i); if (current_target <= lot->cfg->parking_stop) { return current_target; } if (wrap <= lot->cfg->parking_stop) { return wrap; } return -1; }
struct ast_channel *ast_pickup_find_by_group(struct ast_channel *chan) { struct ao2_container *candidates;/*!< Candidate channels found to pickup. */ struct ast_channel *target;/*!< Potential pickup target */ candidates = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL); if (!candidates) { return NULL; } /* Find all candidate targets by group. */ ast_channel_callback(find_channel_by_group, chan, candidates, 0); /* Find the oldest pickup target candidate */ target = NULL; for (;;) { struct ast_channel *candidate;/*!< Potential new older target */ struct ao2_iterator iter; iter = ao2_iterator_init(candidates, 0); while ((candidate = ao2_iterator_next(&iter))) { if (!target) { /* First target. */ target = candidate; continue; } if (ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) { /* We have a new target. */ ast_channel_unref(target); target = candidate; continue; } ast_channel_unref(candidate); } ao2_iterator_destroy(&iter); if (!target) { /* No candidates found. */ break; } /* The found channel must be locked and ref'd. */ ast_channel_lock(target); /* Recheck pickup ability */ if (ast_can_pickup(target)) { /* This is the channel to pickup. */ break; } /* Someone else picked it up or the call went away. */ ast_channel_unlock(target); ao2_unlink(candidates, target); target = ast_channel_unref(target); } ao2_ref(candidates, -1); return target; }
void ast_ari_channels_list(struct ast_variable *headers, struct ast_ari_channels_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer(); cache = ast_channel_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } ao2_ref(cache, +1); snapshots = stasis_cache_dump(cache, ast_channel_snapshot_type()); if (!snapshots) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } for (i = ao2_iterator_init(snapshots, 0); (obj = ao2_iterator_next(&i)); ao2_cleanup(obj)) { RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup); struct ast_channel_snapshot *snapshot = stasis_message_data(msg); int r; if (sanitize && sanitize->channel_snapshot && sanitize->channel_snapshot(snapshot)) { continue; } r = ast_json_array_append( json, ast_channel_snapshot_to_json(snapshot, NULL)); if (r != 0) { ast_ari_response_alloc_failed(response); ao2_cleanup(obj); ao2_iterator_destroy(&i); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }
static int manager_parking_status_single_lot(struct mansession *s, const struct message *m, const char *id_text, const char *lot_name) { RAII_VAR(struct parking_lot *, curlot, NULL, ao2_cleanup); struct parked_user *curuser; struct ao2_iterator iter_users; int total = 0; curlot = parking_lot_find_by_name(lot_name); if (!curlot) { astman_send_error(s, m, "Requested parking lot could not be found."); return RESULT_SUCCESS; } astman_send_ack(s, m, "Parked calls will follow"); iter_users = ao2_iterator_init(curlot->parked_users, 0); while ((curuser = ao2_iterator_next(&iter_users))) { RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free); payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL); if (!payload) { astman_send_error(s, m, "Failed to retrieve parking data about a parked user."); return RESULT_FAILURE; } parked_call_string = manager_build_parked_call_string(payload); if (!parked_call_string) { astman_send_error(s, m, "Failed to retrieve parkingd ata about a parked user."); return RESULT_FAILURE; } total++; astman_append(s, "Event: ParkedCall\r\n" "%s" /* The parked call string */ "%s" /* The action ID */ "\r\n", ast_str_buffer(parked_call_string), id_text); ao2_ref(curuser, -1); } ao2_iterator_destroy(&iter_users); astman_append(s, "Event: ParkedCallsComplete\r\n" "Total: %d\r\n" "%s" "\r\n", total, id_text); return RESULT_SUCCESS; }
/*! * \internal * \brief Delete all mailboxes in container. * \since 12.1.0 * * \param mailboxes Mailbox objects to delete from sorcery. * * \return Nothing */ static void mwi_mailbox_delete_all(struct ao2_container *mailboxes) { struct ast_mwi_mailbox_object *mailbox; struct ao2_iterator iter; iter = ao2_iterator_init(mailboxes, AO2_ITERATOR_UNLINK); for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) { mwi_mailbox_delete(mailbox); } ao2_iterator_destroy(&iter); }
void control_flush_queue(struct stasis_app_control *control) { struct ao2_iterator iter; struct stasis_app_command *command; iter = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK); while ((command = ao2_iterator_next(&iter))) { command_complete(command, -1); ao2_ref(command, -1); } ao2_iterator_destroy(&iter); }
/*! \brief Adds devicestate to local channels */ static int local_devicestate(const char *data) { int is_inuse = 0; int res = AST_DEVICE_INVALID; char *exten = ast_strdupa(data); char *context; char *opts; struct local_pvt *lp; struct ao2_iterator it; /* Strip options if they exist */ opts = strchr(exten, '/'); if (opts) { *opts = '\0'; } context = strchr(exten, '@'); if (!context) { ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", data); return AST_DEVICE_INVALID; } *context++ = '\0'; it = ao2_iterator_init(locals, 0); for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) { ao2_lock(lp); if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context)) { res = AST_DEVICE_NOT_INUSE; if (lp->base.owner && ast_test_flag(&lp->base, AST_UNREAL_CARETAKER_THREAD)) { is_inuse = 1; } } ao2_unlock(lp); if (is_inuse) { res = AST_DEVICE_INUSE; ao2_ref(lp, -1); break; } } ao2_iterator_destroy(&it); if (res == AST_DEVICE_INVALID) { ast_debug(3, "Checking if extension %[email protected]%s exists (devicestate)\n", exten, context); if (ast_exists_extension(NULL, context, exten, 1, NULL)) { res = AST_DEVICE_NOT_INUSE; } } return res; }
struct ast_json *app_to_json(const struct stasis_app *app) { struct ast_json *json; struct ast_json *channels; struct ast_json *bridges; struct ast_json *endpoints; struct ao2_iterator i; struct app_forwards *forwards; json = ast_json_pack("{s: s, s: [], s: [], s: []}", "name", app->name, "channel_ids", "bridge_ids", "endpoint_ids"); if (!json) { return NULL; } channels = ast_json_object_get(json, "channel_ids"); bridges = ast_json_object_get(json, "bridge_ids"); endpoints = ast_json_object_get(json, "endpoint_ids"); i = ao2_iterator_init(app->forwards, 0); while ((forwards = ao2_iterator_next(&i))) { struct ast_json *array = NULL; int append_res; switch (forwards->forward_type) { case FORWARD_CHANNEL: array = channels; break; case FORWARD_BRIDGE: array = bridges; break; case FORWARD_ENDPOINT: array = endpoints; break; } /* If forward_type value is unexpected this will safely return an error. */ append_res = ast_json_array_append(array, ast_json_string_create(forwards->id)); ao2_ref(forwards, -1); if (append_res != 0) { ast_log(LOG_ERROR, "Error building response\n"); ao2_iterator_destroy(&i); ast_json_unref(json); return NULL; } } ao2_iterator_destroy(&i); return json; }
/*! * \internal * \brief List all mailboxes in the given container. * \since 12.1.0 * * \param cli_fd File descriptor for CLI output. * \param mailboxes What to list. * * \return Nothing */ static void mwi_cli_list_mailboxes(int cli_fd, struct ao2_container *mailboxes) { struct ao2_iterator iter; const struct ast_mwi_mailbox_object *mailbox; ast_cli(cli_fd, FORMAT_MAILBOX_HDR, "New", "Old", "Mailbox"); iter = ao2_iterator_init(mailboxes, 0); for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) { mwi_cli_print_mailbox(cli_fd, mailbox); } ao2_iterator_destroy(&iter); }
/*! * \internal * \brief Do completion on the notify CLI command. */ static char *cli_complete_notify(const char *line, const char *word, int pos, int state, int using_uri) { char *c = NULL; if (pos == 3) { int which = 0; int wordlen = strlen(word); RAII_VAR(struct notify_cfg *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); struct notify_option *option; /* do completion for notify type */ struct ao2_iterator i = ao2_iterator_init(cfg->notify_options, 0); while ((option = ao2_iterator_next(&i))) { if (!strncasecmp(word, option->name, wordlen) && ++which > state) { c = ast_strdup(option->name); } ao2_cleanup(option); if (c) { break; } } ao2_iterator_destroy(&i); return c; } if (pos == 4) { int wordlen = strlen(word); if (ast_strlen_zero(word)) { if (state == 0) { c = ast_strdup("endpoint"); } else if (state == 1) { c = ast_strdup("uri"); } } else if (state == 0) { if (!strncasecmp(word, "endpoint", wordlen)) { c = ast_strdup("endpoint"); } else if (!strncasecmp(word, "uri", wordlen)) { c = ast_strdup("uri"); } } return c; } return pos > 4 && !using_uri ? cli_complete_endpoint(word, state) : NULL; }
struct ast_json *app_to_json(const struct stasis_app *app) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ast_json *channels; struct ast_json *bridges; struct ast_json *endpoints; struct ao2_iterator i; void *obj; json = ast_json_pack("{s: s, s: [], s: [], s: []}", "name", app->name, "channel_ids", "bridge_ids", "endpoint_ids"); channels = ast_json_object_get(json, "channel_ids"); bridges = ast_json_object_get(json, "bridge_ids"); endpoints = ast_json_object_get(json, "endpoint_ids"); i = ao2_iterator_init(app->forwards, 0); while ((obj = ao2_iterator_next(&i))) { RAII_VAR(struct app_forwards *, forwards, obj, ao2_cleanup); RAII_VAR(struct ast_json *, id, NULL, ast_json_unref); int append_res = -1; id = ast_json_string_create(forwards->id); switch (forwards->forward_type) { case FORWARD_CHANNEL: append_res = ast_json_array_append(channels, ast_json_ref(id)); break; case FORWARD_BRIDGE: append_res = ast_json_array_append(bridges, ast_json_ref(id)); break; case FORWARD_ENDPOINT: append_res = ast_json_array_append(endpoints, ast_json_ref(id)); break; } if (append_res != 0) { ast_log(LOG_ERROR, "Error building response\n"); ao2_iterator_destroy(&i); return NULL; } } ao2_iterator_destroy(&i); return ast_json_ref(json); }
void ast_ari_bridges_list(struct ast_variable *headers, struct ast_ari_bridges_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; cache = ast_bridge_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } ao2_ref(cache, +1); snapshots = stasis_cache_dump(cache, ast_bridge_snapshot_type()); if (!snapshots) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } i = ao2_iterator_init(snapshots, 0); while ((obj = ao2_iterator_next(&i))) { RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup); struct ast_bridge_snapshot *snapshot = stasis_message_data(msg); struct ast_json *json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer()); if (!json_bridge || ast_json_array_append(json, json_bridge)) { ao2_iterator_destroy(&i); ast_ari_response_alloc_failed(response); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }
int ast_sip_for_each_contact(const struct ast_sip_aor *aor, ao2_callback_fn on_contact, void *arg) { struct ao2_container *contacts; struct ao2_iterator i; int res = 0; void *object = NULL; if (!on_contact || !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) { return 0; } i = ao2_iterator_init(contacts, 0); while ((object = ao2_iterator_next(&i))) { RAII_VAR(struct ast_sip_contact *, contact, object, ao2_cleanup); RAII_VAR(struct ast_sip_contact_wrapper *, wrapper, NULL, ao2_cleanup); const char *aor_id = ast_sorcery_object_get_id(aor); wrapper = ao2_alloc_options(sizeof(struct ast_sip_contact_wrapper), contact_wrapper_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!wrapper) { res = -1; break; } wrapper->contact_id = ast_malloc(strlen(aor_id) + strlen(contact->uri) + 2); if (!wrapper->contact_id) { res = -1; break; } sprintf(wrapper->contact_id, "%s/%s", aor_id, contact->uri); wrapper->aor_id = ast_strdup(aor_id); if (!wrapper->aor_id) { res = -1; break; } wrapper->contact = contact; ao2_bump(wrapper->contact); if ((res = on_contact(wrapper, arg, 0))) { break; } } ao2_iterator_destroy(&i); ao2_ref(contacts, -1); return res; }
/*! * \brief Explicitly shutdown a session. * * An explicit shutdown is necessary, since stasis-app has a reference to this * session. We also need to be sure to null out the \c ws_session field, since * the websocket is about to go away. * * \param session Session info struct. */ static void session_shutdown(struct event_session *session) { struct ao2_iterator i; char *app; SCOPED_AO2LOCK(lock, session); i = ao2_iterator_init(session->websocket_apps, 0); while ((app = ao2_iterator_next(&i))) { stasis_app_unregister(app); ao2_cleanup(app); } ao2_iterator_destroy(&i); ao2_cleanup(session->websocket_apps); session->websocket_apps = NULL; session->ws_session = NULL; }
static void mwi_subscription_mailboxes_str(struct ao2_container *stasis_subs, struct ast_str **str) { int num = ao2_container_count(stasis_subs); struct mwi_stasis_subscription *node; struct ao2_iterator i = ao2_iterator_init(stasis_subs, 0); while ((node = ao2_iterator_next(&i))) { if (--num) { ast_str_append(str, 0, "%s,", node->mailbox); } else { ast_str_append(str, 0, "%s", node->mailbox); } ao2_ref(node, -1); } ao2_iterator_destroy(&i); }
/*! * \internal * \brief Build the NOTIFY request from CLI info adding header and content * when specified. */ static void build_cli_notify(pjsip_tx_data *tdata, void *info) { struct notify_option *option = info; RAII_VAR(struct ast_str *, content_type, NULL, ast_free); RAII_VAR(struct ast_str *, content, NULL, ast_free); struct notify_option_item *item; struct ao2_iterator i = ao2_iterator_init(option->items, 0); while ((item = ao2_iterator_next(&i))) { build_notify(tdata, item->name, item->value, &content_type, &content); ao2_cleanup(item); } ao2_iterator_destroy(&i); build_notify_body(tdata, content_type, content); }
int control_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan) { int count = 0; struct ao2_iterator iter; struct stasis_app_command *command; ast_assert(control->channel == chan); iter = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK); while ((command = ao2_iterator_next(&iter))) { command_invoke(command, control, chan); ao2_ref(command, -1); ++count; } ao2_iterator_destroy(&iter); return count; }
static int dialgroup_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) { struct ao2_iterator i; struct group *grhead = ao2_find(group_container, data, 0); struct group_entry *entry; size_t bufused = 0; int trunc_warning = 0; int res = 0; if (!grhead) { if (!ast_strlen_zero(cmd)) { ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); } return -1; } buf[0] = '\0'; i = ao2_iterator_init(grhead->entries, OBJ_POINTER); while ((entry = ao2_iterator_next(&i))) { int tmp = strlen(entry->name); /* Ensure that we copy only complete names, not partials */ if (len - bufused > tmp + 2) { if (bufused != 0) buf[bufused++] = '&'; ast_copy_string(buf + bufused, entry->name, len - bufused); bufused += tmp; } else if (trunc_warning++ == 0) { if (!ast_strlen_zero(cmd)) { ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); } else { res = 1; ao2_ref(entry, -1); break; } } ao2_ref(entry, -1); } ao2_iterator_destroy(&i); return res; }
/*! \brief Adds devicestate to local channels */ static int local_devicestate(const char *data) { char *exten = ast_strdupa(data); char *context = NULL, *opts = NULL; int res; struct local_pvt *lp; struct ao2_iterator it; if (!(context = strchr(exten, '@'))) { ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten); return AST_DEVICE_INVALID; } *context++ = '\0'; /* Strip options if they exist */ if ((opts = strchr(context, '/'))) *opts = '\0'; ast_debug(3, "Checking if extension %[email protected]%s exists (devicestate)\n", exten, context); res = ast_exists_extension(NULL, context, exten, 1, NULL); if (!res) return AST_DEVICE_INVALID; res = AST_DEVICE_NOT_INUSE; it = ao2_iterator_init(locals, 0); while ((lp = ao2_iterator_next(&it)) && (res == AST_DEVICE_NOT_INUSE)) { if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) { ao2_lock(lp); if (ast_test_flag(lp, LOCAL_LAUNCHED_PBX)) { res = AST_DEVICE_INUSE; } ao2_unlock(lp); } ao2_ref(lp, -1); } ao2_iterator_destroy(&it); return res; }