static int manager_parking_lot_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); struct ao2_container *lot_container; char id_text[256]; struct park_list_data list_data; id_text[0] = '\0'; if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } lot_container = get_parking_lot_container(); if (!lot_container) { ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n"); astman_send_error(s, m, "Could not create parking lot list"); return 0; } astman_send_listack(s, m, "Parking lots will follow", "start"); list_data.id_text = id_text; list_data.count = 0; ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_data_cb, s, &list_data); astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count); astman_send_list_complete_end(s); return 0; }
void ast_ari_sounds_list(struct ast_variable *headers, struct ast_ari_sounds_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct ao2_container *, sound_files, NULL, ao2_cleanup); struct ast_json *sounds_blob; RAII_VAR(struct ast_media_index *, sounds_index, ast_sounds_get_index(), ao2_cleanup); if (!sounds_index) { ast_ari_response_error(response, 500, "Internal Error", "Sounds index not available"); return; } sound_files = ast_media_get_media(sounds_index); if (!sound_files) { ast_ari_response_error(response, 500, "Internal Error", "Allocation Error"); return; } sounds_blob = ast_json_array_create(); if (!sounds_blob) { ast_ari_response_error(response, 500, "Internal Error", "Allocation Error"); return; } ao2_callback_data(sound_files, OBJ_NODATA, append_sound_cb, sounds_blob, args); if (!ast_json_array_size(sounds_blob)) { ast_ari_response_error(response, 404, "Not Found", "No sounds found that matched the query"); return; } ast_ari_response_ok(response, sounds_blob); }
static int manager_parking_lot_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); char id_text[256] = ""; struct ao2_container *lot_container; if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } lot_container = get_parking_lot_container(); if (!lot_container) { ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n"); astman_send_error(s, m, "Could not create parking lot list"); return -1; } astman_send_ack(s, m, "Parking lots will follow"); ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_data_cb, s, id_text); astman_append(s, "Event: ParkinglotsComplete\r\n" "%s" "\r\n",id_text); return RESULT_SUCCESS; }
static int manager_bridge_info(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free); struct ast_bridge_snapshot *snapshot; struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (ast_strlen_zero(bridge_uniqueid)) { astman_send_error(s, m, "BridgeUniqueid must be provided"); return 0; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } msg = stasis_cache_get(ast_bridge_cache(), ast_bridge_snapshot_type(), bridge_uniqueid); if (!msg) { astman_send_error(s, m, "Specified BridgeUniqueid not found"); return 0; } snapshot = stasis_message_data(msg); bridge_info = ast_manager_build_bridge_state_string(snapshot); if (!bridge_info) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge channel listing will follow", "start"); list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count); if (!ast_strlen_zero(ast_str_buffer(bridge_info))) { astman_append(s, "%s", ast_str_buffer(bridge_info)); } astman_send_list_complete_end(s); return 0; }
static char *complete_parking_lot(const char *word, int seeking) { char *ret = NULL; struct parking_lot *lot; struct ao2_container *global_lots = get_parking_lot_container(); struct parking_lot_complete search = { .seeking = seeking, }; lot = ao2_callback_data(global_lots, ast_strlen_zero(word) ? 0 : OBJ_PARTIAL_KEY, complete_parking_lot_search, (char *) word, &search); if (!lot) { return NULL; } ret = ast_strdup(lot->name); ao2_ref(lot, -1); return ret; }
static int manager_bridges_list(struct mansession *s, const struct message *m) { const char *id = astman_get_header(m, "ActionID"); const char *type_filter = astman_get_header(m, "BridgeType"); RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free); RAII_VAR(struct ao2_container *, bridges, NULL, ao2_cleanup); struct bridge_list_data list_data; if (!id_text) { astman_send_error(s, m, "Internal error"); return -1; } if (!ast_strlen_zero(id)) { ast_str_set(&id_text, 0, "ActionID: %s\r\n", id); } bridges = stasis_cache_dump(ast_bridge_cache(), ast_bridge_snapshot_type()); if (!bridges) { astman_send_error(s, m, "Internal error"); return -1; } astman_send_listack(s, m, "Bridge listing will follow", "start"); if (!ast_strlen_zero(type_filter)) { char *type_filter_dup = ast_strdupa(type_filter); ao2_callback(bridges, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, filter_bridge_type_cb, type_filter_dup); } list_data.id_text = ast_str_buffer(id_text); list_data.count = 0; ao2_callback_data(bridges, OBJ_NODATA, send_bridge_list_item_cb, s, &list_data); astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count); astman_send_list_complete_end(s); return 0; }
/*! * \brief Remove threads from the threadpool * * The preference is to kill idle threads. However, if there are * more threads to remove than there are idle threads, then active * threads will be zombified instead. * * This function is called from the threadpool control taskprocessor thread. * * \param pool The threadpool to remove threads from * \param delta The number of threads to remove */ static void shrink(struct ast_threadpool *pool, int delta) { /* * Preference is to kill idle threads, but * we'll move on to deactivating active threads * if we have to */ int idle_threads = ao2_container_count(pool->idle_threads); int idle_threads_to_kill = MIN(delta, idle_threads); int active_threads_to_zombify = delta - idle_threads_to_kill; ast_debug(3, "Destroying %d idle threads in threadpool %s\n", idle_threads_to_kill, ast_taskprocessor_name(pool->tps)); ao2_callback(pool->idle_threads, OBJ_UNLINK | OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE, kill_threads, &idle_threads_to_kill); ast_debug(3, "Destroying %d active threads in threadpool %s\n", active_threads_to_zombify, ast_taskprocessor_name(pool->tps)); ao2_callback_data(pool->active_threads, OBJ_UNLINK | OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE, zombify_threads, pool, &active_threads_to_zombify); }
/*! * \internal * \brief For an endpoint iterate over and qualify all aors/contacts */ static int cli_qualify_contacts(void *data) { char *aors; char *aor_name; RAII_VAR(struct qualify_data *, qual_data, data, qualify_data_destroy); struct ast_sip_endpoint *endpoint = qual_data->endpoint; int cli_fd = qual_data->cli_fd; const char *endpoint_name = ast_sorcery_object_get_id(endpoint); if (ast_strlen_zero(endpoint->aors)) { ast_cli(cli_fd, "Endpoint %s has no AoR's configured\n", endpoint_name); return 0; } aors = ast_strdupa(endpoint->aors); while ((aor_name = strsep(&aors, ","))) { struct ast_sip_aor *aor; struct ao2_container *contacts; aor = ast_sip_location_retrieve_aor(aor_name); if (!aor) { continue; } contacts = ast_sip_location_retrieve_aor_contacts(aor); if (contacts) { ast_cli(cli_fd, "Sending qualify to endpoint %s\n", endpoint_name); ao2_callback_data(contacts, OBJ_NODATA, cli_on_contact, &cli_fd, endpoint); ao2_ref(contacts, -1); } ao2_ref(aor, -1); } return 0; }