static int named_locks_hash(const void *obj, const int flags) { const struct ast_named_lock *lock = obj; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: return ast_str_hash(obj); case OBJ_SEARCH_OBJECT: return ast_str_hash(lock->key); default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } }
static int test_hash_cb(const void *obj, const int flags) { struct test_obj *test_obj = (struct test_obj *) obj; if (!test_obj || ast_strlen_zero(test_obj->c)) { return 0; } return ast_str_hash(test_obj->c); }
static int serializer_hash(const void *obj, const int flags) { const struct serializer *object; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; return ast_str_hash(key); case OBJ_SEARCH_OBJECT: object = obj; return ast_str_hash(object->aor_name); default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } }
static int codec_hash(const void *obj, int flags) { const struct ast_codec *codec; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; return ast_str_hash(key); case OBJ_SEARCH_OBJECT: codec = obj; return ast_str_hash(codec->name); default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } }
static int wait_bridge_hash_fn(const void *obj, const int flags) { const struct wait_bridge_wrapper *entry; const char *key; switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { case OBJ_KEY: key = obj; return ast_str_hash(key); case OBJ_POINTER: entry = obj; return ast_str_hash(entry->name); default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } }
static int mwi_sub_hash(const void *obj, const int flags) { const struct mwi_subscription *object; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: object = obj; key = object->id; break; default: ast_assert(0); return 0; } return ast_str_hash(key); }
/*! \brief hashing function for state objects */ static int transport_state_hash(const void *obj, const int flags) { const struct ast_sip_transport_state *object; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: object = obj; key = object->id; break; default: ast_assert(0); return 0; } return ast_str_hash(key); }
static int sched_qualifies_hash_fn(const void *obj, int flags) { const struct sched_data *object; const struct ast_sip_contact *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: object = obj; key = object->contact; break; default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } return ast_str_hash(ast_sorcery_object_get_id(key)); }
/*! \brief Hashing function for contact auto-expiration */ static int contact_expiration_hash(const void *obj, const int flags) { const struct contact_expiration *object; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: object = obj; key = ast_sorcery_object_get_id(object->contact); break; default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } return ast_str_hash(key); }
/*! * \brief AO2 hash function for \ref event_session objects. * * \details Computes hash value for the given \ref event_session, with respect to the * provided search flags. * * \internal * * \param obj Void pointer to the \ref event_session object. * \param flags The \ref search_flags to use when creating the hash key. * * \retval > 0 on success * \retval 0 on failure */ static int event_session_hash(const void *obj, const int flags) { const struct event_session *session; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: session = obj; key = session->session_id; break; default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } return ast_str_hash(key); }
static int recording_hash(const void *obj, int flags) { const struct stasis_app_recording *recording = obj; const char *id = flags & OBJ_KEY ? obj : recording->options->name; return ast_str_hash(id); }
static int group_hash_fn(const void *obj, const int flags) { const struct group *g = obj; return ast_str_hash(g->name); }
static int entry_hash_fn(const void *obj, const int flags) { const struct group_entry *e = obj; return ast_str_hash(e->name); }
static int distribute(void *data) { static pjsip_process_rdata_param param = { .start_mod = &distributor_mod, .idx_after_start = 1, }; pj_bool_t handled = PJ_FALSE; pjsip_rx_data *rdata = data; int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG; int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0; struct ast_sip_endpoint *endpoint; pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(), rdata, ¶m, &handled); if (!handled && is_request && !is_ack) { pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 501, NULL, NULL, NULL); } /* The endpoint_mod stores an endpoint reference in the mod_data of rdata. This * is the only appropriate spot to actually decrement the reference. */ endpoint = rdata->endpt_info.mod_data[endpoint_mod.id]; ao2_cleanup(endpoint); pjsip_rx_data_free_cloned(rdata); return 0; } struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata) { struct ast_sip_endpoint *endpoint = rdata->endpt_info.mod_data[endpoint_mod.id]; if (endpoint) { ao2_ref(endpoint, +1); } return endpoint; } static int suspects_sort(const void *obj, const void *arg, int flags) { const struct unidentified_request *object_left = obj; const struct unidentified_request *object_right = arg; const char *right_key = arg; int cmp; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_OBJECT: right_key = object_right->src_name; /* Fall through */ case OBJ_SEARCH_KEY: cmp = strcmp(object_left->src_name, right_key); break; case OBJ_SEARCH_PARTIAL_KEY: cmp = strncmp(object_left->src_name, right_key, strlen(right_key)); break; default: cmp = 0; break; } return cmp; } static int suspects_compare(void *obj, void *arg, int flags) { const struct unidentified_request *object_left = obj; const struct unidentified_request *object_right = arg; const char *right_key = arg; int cmp = 0; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_OBJECT: right_key = object_right->src_name; /* Fall through */ case OBJ_SEARCH_KEY: if (strcmp(object_left->src_name, right_key) == 0) { cmp = CMP_MATCH; } break; case OBJ_SEARCH_PARTIAL_KEY: if (strncmp(object_left->src_name, right_key, strlen(right_key)) == 0) { cmp = CMP_MATCH; } break; default: cmp = 0; break; } return cmp; } static int suspects_hash(const void *obj, int flags) { const struct unidentified_request *object; const char *key; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_KEY: key = obj; break; case OBJ_SEARCH_OBJECT: object = obj; key = object->src_name; break; default: /* Hash can only work on something with a full key. */ ast_assert(0); return 0; } return ast_str_hash(key); } static struct ao2_container *cli_unid_get_container(const char *regex) { struct ao2_container *s_container; s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, suspects_sort, suspects_compare); if (!s_container) { return NULL; } if (ao2_container_dup(s_container, unidentified_requests, 0)) { ao2_ref(s_container, -1); return NULL; } return s_container; } static int cli_unid_iterate(void *container, ao2_callback_fn callback, void *args) { ao2_callback(container, 0, callback, args); return 0; }
char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup); RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup); RAII_VAR(void *, object, NULL, ao2_cleanup); int is_container = 0; const char *cmd1; const char *cmd2; const char *object_id; char formatter_type[64]; struct ast_sip_cli_context context = { .indent_level = 0, .show_details = 0, .show_details_only_level_0 = 0, .recurse = 0, }; if (cmd == CLI_INIT) { return NULL; } cmd1 = e->cmda[1]; cmd2 = e->cmda[2]; object_id = a->argv[3]; if (!ast_ends_with(cmd2, "s")) { ast_copy_string(formatter_type, cmd2, sizeof(formatter_type)); is_container = 0; } else if (ast_ends_with(cmd2, "ies")) { /* Take the plural "ies" off of the object name and re[place with "y". */ int l = strlen(cmd2); snprintf(formatter_type, 64, "%*.*sy", l - 3, l - 3, cmd2); is_container = 1; } else { /* Take the plural "s" off of the object name. */ ast_copy_string(formatter_type, cmd2, strlen(cmd2)); is_container = 1; } if (!strcmp(cmd1, "show")) { context.show_details_only_level_0 = !is_container; context.recurse = 1; } else { is_container = 1; } if (cmd == CLI_GENERATE && (is_container || a->argc > 4 || (a->argc == 4 && ast_strlen_zero(a->word)))) { return CLI_SUCCESS; } context.output_buffer = ast_str_create(256); if (!context.output_buffer) { return CLI_FAILURE; } formatter_entry = ast_sip_lookup_cli_formatter(formatter_type); if (!formatter_entry) { ast_log(LOG_ERROR, "No formatter registered for object type %s.\n", formatter_type); ast_free(context.output_buffer); return CLI_FAILURE; } ast_str_append(&context.output_buffer, 0, "\n"); formatter_entry->print_header(NULL, &context, 0); ast_str_append(&context.output_buffer, 0, " =========================================================================================\n\n"); if (is_container || cmd == CLI_GENERATE) { container = formatter_entry->get_container(); if (!container) { ast_cli(a->fd, "No container returned for object type %s.\n", formatter_type); ast_free(context.output_buffer); return CLI_FAILURE; } } if (cmd == CLI_GENERATE) { ast_free(context.output_buffer); return complete_show_sorcery_object(container, formatter_entry, a->word, a->n); } if (is_container) { if (!ao2_container_count(container)) { ast_free(context.output_buffer); ast_cli(a->fd, "No objects found.\n\n"); return CLI_SUCCESS; } ao2_callback(container, OBJ_NODATA, formatter_entry->print_body, &context); } else { if (ast_strlen_zero(object_id)) { ast_free(context.output_buffer); ast_cli(a->fd, "No object specified.\n"); return CLI_FAILURE; } object = formatter_entry->retrieve_by_id(object_id); if (!object) { ast_free(context.output_buffer); ast_cli(a->fd, "Unable to find object %s.\n\n", object_id); return CLI_SUCCESS; } formatter_entry->print_body(object, &context, 0); } ast_str_append(&context.output_buffer, 0, "\n"); dump_str_and_free(a->fd, context.output_buffer); return CLI_SUCCESS; } static int formatter_sort(const void *obj, const void *arg, int flags) { const struct ast_sip_cli_formatter_entry *left_obj = obj; const struct ast_sip_cli_formatter_entry *right_obj = arg; const char *right_key = arg; int cmp = 0; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_OBJECT: right_key = right_obj->name; /* Fall through */ case OBJ_SEARCH_KEY: cmp = strcmp(left_obj->name, right_key); break; case OBJ_SEARCH_PARTIAL_KEY: cmp = strncmp(left_obj->name, right_key, strlen(right_key)); break; default: cmp = 0; break; } return cmp; } static int formatter_compare(void *obj, void *arg, int flags) { const struct ast_sip_cli_formatter_entry *left_obj = obj; const struct ast_sip_cli_formatter_entry *right_obj = arg; const char *right_key = arg; int cmp = 0; switch (flags & OBJ_SEARCH_MASK) { case OBJ_SEARCH_OBJECT: right_key = right_obj->name; /* Fall through */ case OBJ_SEARCH_KEY: if (strcmp(left_obj->name, right_key) == 0) {; cmp = CMP_MATCH | CMP_STOP; } break; case OBJ_SEARCH_PARTIAL_KEY: if (strncmp(left_obj->name, right_key, strlen(right_key)) == 0) { cmp = CMP_MATCH; } break; default: cmp = 0; break; } return cmp; } static int formatter_hash(const void *obj, int flags) { const struct ast_sip_cli_formatter_entry *left_obj = obj; if (flags & OBJ_SEARCH_OBJECT) { return ast_str_hash(left_obj->name); } else if (flags & OBJ_SEARCH_KEY) { return ast_str_hash(obj); } return -1; } struct ast_sip_cli_formatter_entry *ast_sip_lookup_cli_formatter(const char *name) { return ao2_find(formatter_registry, name, OBJ_SEARCH_KEY | OBJ_NOLOCK); } int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter) { ast_assert(formatter != NULL); ast_assert(formatter->name != NULL); ast_assert(formatter->print_body != NULL); ast_assert(formatter->print_header != NULL); ast_assert(formatter->get_container != NULL); ast_assert(formatter->iterate != NULL); ast_assert(formatter->get_id != NULL); ast_assert(formatter->retrieve_by_id != NULL); ao2_link(formatter_registry, formatter); return 0; }
static int str_hash(const void *obj, const int flags) { return ast_str_hash(obj); }
/*! \brief Hashing function used for aliases */ static int alias_hash_cb(const void *obj, const int flags) { const struct cli_alias *alias = obj; return ast_str_hash(alias->cli_entry.command); }
/* \brief Hash function for pvt cause code frames */ static int pvt_cause_hash_fn(const void *vpc, const int flags) { const struct ast_control_pvt_cause_code *pc = vpc; return ast_str_hash(ast_tech_to_upper(ast_strdupa(pc->chan_name))); }