/*! \brief WebSocket connection handler. */ static void websocket_cb(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers) { struct ast_taskprocessor *serializer; struct transport_create_data create_data; struct ws_transport *transport; struct transport_read_data read_data; if (ast_websocket_set_nonblock(session)) { ast_websocket_unref(session); return; } if (ast_websocket_set_timeout(session, get_write_timeout())) { ast_websocket_unref(session); return; } serializer = create_websocket_serializer(); if (!serializer) { ast_websocket_unref(session); return; } create_data.ws_session = session; if (ast_sip_push_task_synchronous(serializer, transport_create, &create_data)) { ast_log(LOG_ERROR, "Could not create WebSocket transport.\n"); ast_websocket_unref(session); return; } transport = create_data.transport; read_data.transport = transport; while (ast_wait_for_input(ast_websocket_fd(session), -1) > 0) { enum ast_websocket_opcode opcode; int fragmented; if (ast_websocket_read(session, &read_data.payload, &read_data.payload_len, &opcode, &fragmented)) { break; } if (opcode == AST_WEBSOCKET_OPCODE_TEXT || opcode == AST_WEBSOCKET_OPCODE_BINARY) { ast_sip_push_task_synchronous(serializer, transport_read, &read_data); } else if (opcode == AST_WEBSOCKET_OPCODE_CLOSE) { break; } } ast_sip_push_task_synchronous(serializer, transport_shutdown, transport); ast_taskprocessor_unreference(serializer); ast_websocket_unref(session); }
static void websocket_session_dtor(void *obj) { struct ast_ari_websocket_session *session = obj; ast_websocket_unref(session->ws_session); session->ws_session = NULL; }
static void transport_dtor(void *arg) { struct ws_transport *wstransport = arg; if (wstransport->ws_session) { ast_websocket_unref(wstransport->ws_session); } if (wstransport->transport.ref_cnt) { pj_atomic_destroy(wstransport->transport.ref_cnt); } if (wstransport->transport.lock) { pj_lock_destroy(wstransport->transport.lock); } if (wstransport->transport.endpt && wstransport->transport.pool) { pjsip_endpt_release_pool(wstransport->transport.endpt, wstransport->transport.pool); } if (wstransport->rdata.tp_info.pool) { pjsip_endpt_release_pool(wstransport->transport.endpt, wstransport->rdata.tp_info.pool); } }