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; }
static int ami_show_registrations(struct mansession *s, const struct message *m) { int count = 0; struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), }; astman_send_listack(s, m, "Following are Events for each Inbound " "registration", "start"); ami_registrations_endpoints(&ami); astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count); astman_send_list_complete_end(s); return 0; } #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound" static pjsip_module registrar_module = { .name = { "Registrar", 9 }, .id = -1, .priority = PJSIP_MOD_PRIORITY_APPLICATION, .on_rx_request = registrar_on_rx_request, }; static int load_module(void) { const pj_str_t STR_REGISTER = { "REGISTER", 8 }; CHECK_PJSIP_MODULE_LOADED(); if (!(serializers = ao2_container_alloc( SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) { return AST_MODULE_LOAD_DECLINE; } if (ast_sip_register_service(®istrar_module)) { return AST_MODULE_LOAD_DECLINE; } if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) { ast_sip_unregister_service(®istrar_module); return AST_MODULE_LOAD_DECLINE; } ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM, ami_show_registrations); return AST_MODULE_LOAD_SUCCESS; } static int unload_module(void) { ast_manager_unregister(AMI_SHOW_REGISTRATIONS); ast_sip_unregister_service(®istrar_module); ao2_cleanup(serializers); return 0; }
static int ami_show_auths(struct mansession *s, const struct message *m) { struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), }; struct ao2_container *auths; auths = cli_get_auths(); if (!auths) { astman_send_error(s, m, "Could not get Auths\n"); return 0; } if (!ao2_container_count(auths)) { astman_send_error(s, m, "No Auths found\n"); ao2_ref(auths, -1); return 0; } astman_send_listack(s, m, "A listing of Auths follows, presented as AuthList events", "start"); ao2_callback(auths, OBJ_NODATA, format_ami_authlist_handler, &ami); astman_send_list_complete_start(s, m, "AuthListComplete", ami.count); astman_send_list_complete_end(s); ao2_ref(auths, -1); return 0; } static struct ao2_container *cli_get_container(const char *regex) { RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup); struct ao2_container *s_container; container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "auth", regex); if (!container) { return NULL; } s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, ast_sorcery_object_id_sort, ast_sorcery_object_id_compare); if (!s_container) { return NULL; } if (ao2_container_dup(s_container, container, 0)) { ao2_ref(s_container, -1); return NULL; } return s_container; }
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 void 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; } astman_send_listack(s, m, "Parked calls will follow", "start"); 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) { ao2_ref(curuser, -1); break; } parked_call_string = manager_build_parked_call_string(payload); if (!parked_call_string) { ao2_ref(curuser, -1); break; } 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_send_list_complete_start(s, m, "ParkedCallsComplete", total); astman_append(s, "Total: %d\r\n", total); astman_send_list_complete_end(s); }
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; }
static void manager_parking_status_all_lots(struct mansession *s, const struct message *m, const char *id_text) { struct parked_user *curuser; struct ao2_container *lot_container; struct ao2_iterator iter_lots; struct ao2_iterator iter_users; struct parking_lot *curlot; int total = 0; 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; } astman_send_listack(s, m, "Parked calls will follow", "start"); iter_lots = ao2_iterator_init(lot_container, 0); while ((curlot = ao2_iterator_next(&iter_lots))) { 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) { ao2_ref(curuser, -1); ao2_iterator_destroy(&iter_users); ao2_ref(curlot, -1); goto abort_list; } parked_call_string = manager_build_parked_call_string(payload); if (!parked_call_string) { ao2_ref(curuser, -1); ao2_iterator_destroy(&iter_users); ao2_ref(curlot, -1); goto abort_list; } 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); ao2_ref(curlot, -1); } abort_list: ao2_iterator_destroy(&iter_lots); astman_send_list_complete_start(s, m, "ParkedCallsComplete", total); astman_append(s, "Total: %d\r\n", total); astman_send_list_complete_end(s); }
/*! * \internal * \brief Get the requested mailboxes. * \since 12.1.0 * * \param s AMI session. * \param m AMI message. * * \retval 0 to keep AMI connection. * \retval -1 to disconnect AMI connection. */ static int mwi_mailbox_get(struct mansession *s, const struct message *m) { char id_text[256]; const char *id; const char *mailbox_id = astman_get_header(m, "Mailbox"); const struct ast_mwi_mailbox_object *mailbox; struct ao2_container *mailboxes; unsigned count; struct ao2_iterator iter; if (ast_strlen_zero(mailbox_id)) { astman_send_error(s, m, "Missing mailbox parameter in request"); return 0; } if (*mailbox_id == '/') { struct ast_str *regex_string; regex_string = ast_str_create(strlen(mailbox_id) + 1); if (!regex_string) { astman_send_error(s, m, "Memory Allocation Failure"); return 0; } /* Make "/regex/" into "regex" */ if (ast_regex_string_to_regex_pattern(mailbox_id, ®ex_string) != 0) { astman_send_error_va(s, m, "Mailbox regex format invalid in: %s", mailbox_id); ast_free(regex_string); return 0; } mailboxes = ast_mwi_mailbox_get_by_regex(ast_str_buffer(regex_string)); ast_free(regex_string); } else { mailboxes = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, NULL); if (mailboxes) { mailbox = ast_mwi_mailbox_get(mailbox_id); if (mailbox) { if (!ao2_link(mailboxes, (void *) mailbox)) { ao2_ref(mailboxes, -1); mailboxes = NULL; } ast_mwi_mailbox_unref(mailbox); } } } if (!mailboxes) { astman_send_error(s, m, "Mailbox container creation failure"); return 0; } astman_send_listack(s, m, "Mailboxes will follow", "start"); id = astman_get_header(m, "ActionID"); if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } else { id_text[0] = '\0'; } /* Output mailbox list. */ count = 0; iter = ao2_iterator_init(mailboxes, AO2_ITERATOR_UNLINK); for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) { ++count; astman_append(s, "Event: MWIGet\r\n" "Mailbox: %s\r\n" "OldMessages: %u\r\n" "NewMessages: %u\r\n" "%s" "\r\n", ast_mwi_mailbox_get_id(mailbox), ast_mwi_mailbox_get_msgs_old(mailbox), ast_mwi_mailbox_get_msgs_new(mailbox), id_text); } ao2_iterator_destroy(&iter); ao2_ref(mailboxes, -1); astman_send_list_complete_start(s, m, "MWIGetComplete", count); astman_send_list_complete_end(s); return 0; }