static void publish_to_corosync(struct stasis_message *message) { struct ast_event *event; event = stasis_message_to_event(message); if (!event) { return; } if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) { /* If the event didn't originate from this server, don't send it back out. */ ast_event_destroy(event); return; } if (ast_event_get_type(event) == AST_EVENT_PING) { const struct ast_eid *eid; char buf[128] = ""; eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID); ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid); ast_log(LOG_NOTICE, "Sending event PING from this server with EID: '%s'\n", buf); } publish_event_to_corosync(event); }
/*! * \brief Send a message to the given application. * \param app App to send the message to. * \param message Message to send. */ void app_send(struct stasis_app *app, struct ast_json *message) { stasis_app_cb handler; char eid[20]; void *data; if (ast_json_object_set(message, "asterisk_id", ast_json_string_create( ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) { ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n", ast_json_string_get(ast_json_object_get(message, "type"))); } /* Copy off mutable state with lock held */ ao2_lock(app); handler = app->handler; data = ao2_bump(app->data); ao2_unlock(app); /* Name is immutable; no need to copy */ if (handler) { handler(data, app->name, message); } else { ast_verb(3, "Inactive Stasis app '%s' missed message\n", app->name); } ao2_cleanup(data); }
/*! \brief Publish a received device state \ref ast_event to \ref stasis */ static void publish_device_state_to_stasis(struct ast_event *event) { const char *device; enum ast_device_state state; unsigned int cachable; struct ast_eid *event_eid; ast_assert(ast_event_get_type(event) == AST_EVENT_DEVICE_STATE_CHANGE); device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE); state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE); cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE); event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID); if (ast_strlen_zero(device)) { return; } if (ast_publish_device_state_full(device, state, cachable, event_eid)) { char eid[18]; ast_eid_to_str(eid, sizeof(eid), event_eid); ast_log(LOG_WARNING, "Failed to publish device state message for %s from %s\n", device, eid); } }
/*! * \brief Send a message to the given application. * \param app App to send the message to. * \param message Message to send. */ void app_send(struct stasis_app *app, struct ast_json *message) { stasis_app_cb handler; char eid[20]; RAII_VAR(void *, data, NULL, ao2_cleanup); if (ast_json_object_set(message, "asterisk_id", ast_json_string_create( ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) { ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n", ast_json_string_get(ast_json_object_get(message, "type"))); } /* Copy off mutable state with lock held */ { SCOPED_AO2LOCK(lock, app); handler = app->handler; if (app->data) { ao2_ref(app->data, +1); data = app->data; } /* Name is immutable; no need to copy */ } if (!handler) { ast_verb(3, "Inactive Stasis app '%s' missed message\n", app->name); return; } handler(data, app->name, message); }
static void cpg_deliver_cb(cpg_handle_t handle, const struct cpg_name *group_name, uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) { struct ast_event *event; void (*publish_handler)(struct ast_event *) = NULL; enum ast_event_type event_type; if (msg_len < ast_event_minimum_length()) { ast_debug(1, "Ignoring event that's too small. %u < %u\n", (unsigned int) msg_len, (unsigned int) ast_event_minimum_length()); return; } if (!ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(msg, AST_EVENT_IE_EID))) { /* Don't feed events back in that originated locally. */ return; } event_type = ast_event_get_type(msg); if (event_type > AST_EVENT_TOTAL) { /* Egads, we don't support this */ return; } ast_rwlock_rdlock(&event_types_lock); publish_handler = event_types[event_type].publish_to_stasis; if (!event_types[event_type].subscribe || !publish_handler) { /* We are not configured to subscribe to these events or we have no way to publish it internally. */ ast_rwlock_unlock(&event_types_lock); return; } ast_rwlock_unlock(&event_types_lock); if (!(event = ast_malloc(msg_len))) { return; } memcpy(event, msg, msg_len); if (event_type == AST_EVENT_PING) { const struct ast_eid *eid; char buf[128] = ""; eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID); ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid); ast_log(LOG_NOTICE, "Got event PING from server with EID: '%s'\n", buf); } ast_debug(5, "Publishing event %s (%u) to stasis\n", ast_event_get_type_name(event), event_type); publish_handler(event); }
/*! \brief Publish cluster discovery to \ref stasis */ static void publish_cluster_discovery_to_stasis_full(struct corosync_node *node, int joined) { struct ast_json *json; struct ast_json_payload *payload; struct stasis_message *message; char eid[18]; const char *addr; ast_eid_to_str(eid, sizeof(eid), &node->eid); addr = ast_sockaddr_stringify_addr(&node->addr); ast_log(AST_LOG_NOTICE, "Node %u (%s) at %s %s the cluster\n", node->id, eid, addr, joined ? "joined" : "left"); json = ast_json_pack("{s: s, s: i, s: s, s: i}", "address", addr, "node_id", node->id, "eid", eid, "joined", joined); if (!json) { return; } payload = ast_json_payload_create(json); if (!payload) { ast_json_unref(json); return; } message = stasis_message_create(ast_cluster_discovery_type(), payload); if (!message) { ast_json_unref(json); ao2_ref(payload, -1); return; } stasis_publish(ast_system_topic(), message); ast_json_unref(json); ao2_ref(payload, -1); ao2_ref(message, -1); }
static void publish_to_corosync(struct stasis_message *message) { cs_error_t cs_err; struct iovec iov; struct ast_event *event; event = stasis_message_to_event(message); if (!event) { return; } if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) { /* If the event didn't originate from this server, don't send it back out. */ ast_event_destroy(event); return; } if (ast_event_get_type(event) == AST_EVENT_PING) { const struct ast_eid *eid; char buf[128] = ""; eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID); ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid); ast_log(LOG_NOTICE, "Sending event PING from this server with EID: '%s'\n", buf); } iov.iov_base = (void *)event; iov.iov_len = ast_event_get_size(event); ast_debug(5, "Publishing event %s (%u) to corosync\n", ast_event_get_type_name(event), ast_event_get_type(event)); /* The stasis subscription will only exist if we are configured to publish * these events, so just send away. */ if ((cs_err = cpg_mcast_joined(cpg_handle, CPG_TYPE_FIFO, &iov, 1)) != CS_OK) { ast_log(LOG_WARNING, "CPG mcast failed (%u)\n", cs_err); } }
/*! \brief Publish a received MWI \ref ast_event to \ref stasis */ static void publish_mwi_to_stasis(struct ast_event *event) { const char *mailbox; const char *context; unsigned int new_msgs; unsigned int old_msgs; struct ast_eid *event_eid; ast_assert(ast_event_get_type(event) == AST_EVENT_MWI); mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX); context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT); new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); old_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID); if (ast_strlen_zero(mailbox) || ast_strlen_zero(context)) { return; } if (new_msgs > INT_MAX) { new_msgs = INT_MAX; } if (old_msgs > INT_MAX) { old_msgs = INT_MAX; } if (ast_publish_mwi_state_full(mailbox, context, (int)new_msgs, (int)old_msgs, NULL, event_eid)) { char eid[18]; ast_eid_to_str(eid, sizeof(eid), event_eid); ast_log(LOG_WARNING, "Failed to publish MWI message for %s@%s from %s\n", mailbox, context, eid); } }
void ast_ari_asterisk_get_info(struct ast_variable *headers, struct ast_ari_asterisk_get_info_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); int show_all = args->only_count == 0; int show_build = show_all; int show_system = show_all; int show_config = show_all; int show_status = show_all; size_t i; int res = 0; for (i = 0; i < args->only_count; ++i) { if (strcasecmp("build", args->only[i]) == 0) { show_build = 1; } else if (strcasecmp("system", args->only[i]) == 0) { show_system = 1; } else if (strcasecmp("config", args->only[i]) == 0) { show_config = 1; } else if (strcasecmp("status", args->only[i]) == 0) { show_status = 1; } else { ast_log(LOG_WARNING, "Unrecognized info section '%s'\n", args->only[i]); } } json = ast_json_object_create(); if (show_build) { res |= ast_json_object_set(json, "build", ast_json_pack( "{ s: s, s: s, s: s," " s: s, s: s, s: s }", "os", ast_build_os, "kernel", ast_build_kernel, "machine", ast_build_machine, "options", AST_BUILDOPTS, "date", ast_build_date, "user", ast_build_user)); } if (show_system) { char eid_str[128]; ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default); res |= ast_json_object_set(json, "system", ast_json_pack("{ s: s, s: s }", "version", ast_get_version(), "entity_id", eid_str)); } if (show_config) { struct ast_json *config = ast_json_pack( "{ s: s, s: s," " s: { s: s, s: s } }", "name", ast_config_AST_SYSTEM_NAME, "default_language", ast_defaultlanguage, "setid", "user", ast_config_AST_RUN_USER, "group", ast_config_AST_RUN_GROUP); res |= ast_json_object_set(json, "config", config); if (ast_option_maxcalls) { res |= ast_json_object_set(config, "max_channels", ast_json_integer_create(ast_option_maxcalls)); } if (ast_option_maxfiles) { res |= ast_json_object_set(config, "max_open_files", ast_json_integer_create(ast_option_maxfiles)); } if (ast_option_maxload) { res |= ast_json_object_set(config, "max_load", ast_json_real_create(ast_option_maxload)); } } if (show_status) { res |= ast_json_object_set(json, "status", ast_json_pack("{ s: o, s: o }", "startup_time", ast_json_timeval(ast_startuptime, NULL), "last_reload_time", ast_json_timeval(ast_lastreloadtime, NULL))); } if (res != 0) { ast_ari_response_alloc_failed(response); return; } ast_ari_response_ok(response, ast_json_ref(json)); }