/*! * \brief Register for all of the apps given. * \param session Session info struct. * \param app_name Name of application to register. */ static int session_register_app(struct event_session *session, const char *app_name) { SCOPED_AO2LOCK(lock, session); ast_assert(session->ws_session != NULL); ast_assert(session->websocket_apps != NULL); if (ast_strlen_zero(app_name)) { return -1; } if (ast_str_container_add(session->websocket_apps, app_name)) { ast_ari_websocket_session_write(session->ws_session, ast_ari_oom_json()); return -1; } stasis_app_register(app_name, app_handler, session); return 0; }
/*! * \brief Creates an \ref event_session object and registers its apps with Stasis. * * \internal * * \param ser HTTP TCP/TLS Server Session (\ref ast_tcptls_session_instance). * \param args The Stasis [app] parameters as parsed from the HTTP request * (\ref ast_ari_events_event_websocket_args). * \param session_id The id for the websocket session that will be created for this * event session. * * \retval 0 on success * \retval -1 on failure */ static int event_session_alloc(struct ast_tcptls_session_instance *ser, struct ast_ari_events_event_websocket_args *args, const char *session_id) { RAII_VAR(struct event_session *, session, NULL, ao2_cleanup); size_t size, i; /* The request must have at least one [app] parameter */ if (args->app_count == 0) { return event_session_allocation_error_handler( session, ERROR_TYPE_MISSING_APP_PARAM, ser); } size = sizeof(*session) + strlen(session_id) + 1; /* Instantiate the event session */ session = ao2_alloc(size, event_session_dtor); if (!session) { return event_session_allocation_error_handler(session, ERROR_TYPE_OOM, ser); } strncpy(session->session_id, session_id, size - sizeof(*session)); /* Instantiate the hash table for Stasis apps */ session->websocket_apps = ast_str_container_alloc(APPS_NUM_BUCKETS); if (!session->websocket_apps) { return event_session_allocation_error_handler(session, ERROR_TYPE_OOM, ser); } /* Instantiate the message queue */ if (AST_VECTOR_INIT(&session->message_queue, MESSAGES_INIT_SIZE)) { return event_session_allocation_error_handler(session, ERROR_TYPE_OOM, ser); } /* Register the apps with Stasis */ for (i = 0; i < args->app_count; ++i) { const char *app = args->app[i]; if (ast_strlen_zero(app)) { return event_session_allocation_error_handler( session, ERROR_TYPE_INVALID_APP_PARAM, ser); } if (ast_str_container_add(session->websocket_apps, app)) { return event_session_allocation_error_handler(session, ERROR_TYPE_OOM, ser); } if (stasis_app_register(app, stasis_app_message_handler, session)) { ast_log(LOG_WARNING, "Stasis registration failed for application: '%s'\n", app); return event_session_allocation_error_handler( session, ERROR_TYPE_STASIS_REGISTRATION, ser); } } /* Add the event session to the local registry */ if (!ao2_link(event_session_registry, session)) { return event_session_allocation_error_handler(session, ERROR_TYPE_OOM, ser); } return 0; }