static struct event_session *session_create( struct ast_ari_websocket_session *ws_session) { RAII_VAR(struct event_session *, session, NULL, ao2_cleanup); session = ao2_alloc(sizeof(*session), session_dtor); session->ws_session = ws_session; session->websocket_apps = ast_str_container_alloc(APPS_NUM_BUCKETS); if (!session->websocket_apps) { return NULL; } ao2_ref(session, +1); return session; }
/*! * \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; }