25 #include "transport.h"
26 #include "transport_websocket.h"
28 #define log_error(obj, fmt, ...) aeap_error(obj, "websocket", fmt, ##__VA_ARGS__)
37 static int websocket_connect(
struct aeap_transport *
self,
const char *url,
38 const char *protocol,
int timeout)
44 .protocols = protocol,
49 transport->
ws = ast_websocket_client_create_with_options(&ws_options, &ws_result);
50 if (ws_result != WS_OK) {
51 log_error(
self,
"connect failure (%d)", (
int)ws_result);
63 ast_websocket_unref(transport->
ws);
79 static intmax_t websocket_read(
struct aeap_transport *
self,
void *buf, intmax_t size,
85 uint64_t bytes_read = 0;
86 uint64_t total_bytes_read = 0;
90 *rtype = AST_AEAP_DATA_TYPE_NONE;
92 if (ast_websocket_fd(transport->
ws) < 0) {
93 log_error(
self,
"unavailable for reading");
95 aeap_transport_disconnect(
self);
106 while (ast_websocket_wait_for_input(transport->
ws, -1) <= 0) {
108 if (errno == EINTR || errno == EAGAIN) {
113 log_error(
self,
"poll failure: %s", strerror(errno));
115 aeap_transport_disconnect(
self);
120 if (!transport->
ws) {
129 if (ast_websocket_read(transport->
ws, &payload, &bytes_read, &opcode,
131 log_error(
self,
"read failure (%d): %s", opcode, strerror(errno));
139 if (total_bytes_read + bytes_read > size) {
140 log_error(
self,
"attempted to read too many bytes into (%jd) sized buffer", size);
144 memcpy(buf + total_bytes_read, payload, bytes_read);
145 total_bytes_read += bytes_read;
151 log_error(
self,
"closed");
154 *rtype = AST_AEAP_DATA_TYPE_BINARY;
157 *rtype = AST_AEAP_DATA_TYPE_STRING;
160 if (total_bytes_read == size) {
161 log_error(
self,
"unable to write string terminator");
165 *((
char *)(buf + total_bytes_read)) =
'\0';
172 return total_bytes_read;
175 static intmax_t websocket_write(
struct aeap_transport *
self,
const void *buf, intmax_t size,
182 case AST_AEAP_DATA_TYPE_BINARY:
186 case AST_AEAP_DATA_TYPE_STRING:
195 log_error(
self,
"problem writing to websocket (closed)");
201 aeap_transport_disconnect(
self);
213 .disconnect = websocket_disconnect,
214 .destroy = websocket_destroy,
215 .read = websocket_read,
216 .write = websocket_write,
219 return &websocket_vtable;
231 transport->
ws = NULL;
233 ((
struct aeap_transport *)transport)->vtable = transport_websocket_vtable();
242 transport =
ast_calloc(1,
sizeof(*transport));
244 ast_log(LOG_ERROR,
"AEAP websocket: unable to create transport websocket");
248 if (transport_websocket_init(transport)) {
Asterisk main include file. File version handling, generic pbx functions.
struct ast_websocket * ws
ast_websocket_result
Result code for a websocket client.
Options used for a websocket client.
struct aeap_transport base
Support for WebSocket connections within the Asterisk HTTP server and client WebSocket connections to...
Asterisk external application transport virtual table.
int AST_OPTIONAL_API_NAME() ast_websocket_write(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t payload_size)
Write function for websocket traffic.
Structure definition for session.
#define ast_calloc(num, len)
A wrapper for calloc()
int(* connect)(struct aeap_transport *self, const char *url, const char *protocol, int timeout)
Connect a transport.
AST_AEAP_DATA_TYPE
Supported Asterisk external application data types.
Asterisk external application transport structure to be "derived" by specific transport implementatio...
ast_websocket_opcode
WebSocket operation codes.