void WebSocketOpcode_handleReceive(struct libwebsocket *websocket, WebSocketOpcode *self, CSOUND *csound, size_t inputDataSize, void *inputData) { const struct libwebsocket_protocols *protocol = libwebsockets_get_protocol(websocket); OpcodeArgument *argument = &self->outputArguments[protocol->protocol_index]; if (protocol->protocol_index >= self->outputArgumentCount || argument->iRateVarSent == true) { return; } if (argument->bytesCount != inputDataSize && argument->argumentType != STRING_VAR) { csound->Message(csound, Str("websocket: received message from %s is not correct " "size for variable %s, message dumped"), protocol->name, argument->name); return; } if (argument->argumentType == STRING_VAR && argument->bytesCount > stringVarMaximumBytesCount) { csound->Message(csound, Str("websocket: received string message from %s is " "too large, message dumped"), protocol->name, argument->name); return; } int writtenItems = csoundWriteCircularBuffer(csound, argument->circularBuffer, inputData, argument->itemsCount); if (writtenItems == 0) { csound->Message(csound, Str("websocket: received message from %s dumped, " "buffer overrrun"), argument->name); } else { if (argument->argumentType == IRATE_VAR || argument->argumentType == IRATE_ARRAY) { argument->iRateVarSent = true; } } }
int ws_callback( struct libwebsocket_context *context ,struct libwebsocket *ws ,enum libwebsocket_callback_reasons reason ,void *user ,void *message ,size_t len ) { roxlu::WebSockets* websockets = roxlu::WebSockets::getInstance(); // get protocol handle. const struct libwebsocket_protocols* ws_protocol = libwebsockets_get_protocol(ws); int dx = (ws_protocol) ? ws_protocol->protocol_index : 0; roxlu::WebSocketProtocol* protocol = websockets->getProtocol(dx); // connection roxlu::WebSocketConnection** const conn_ptr = (roxlu::WebSocketConnection**)user; roxlu::WebSocketConnection* conn; // connection established & closed if(reason == LWS_CALLBACK_ESTABLISHED) { *conn_ptr = new roxlu::WebSocketConnection(websockets, protocol); } else if(reason == LWS_CALLBACK_CLOSED) { if(*conn_ptr != NULL) { delete *conn_ptr; } } switch(reason) { case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: { if(protocol != NULL) { return websockets->onAllow(protocol, (int)(long)user) ? 0 : 1; } else { return 0; } }; case LWS_CALLBACK_ESTABLISHED: case LWS_CALLBACK_CLOSED: case LWS_CALLBACK_SERVER_WRITEABLE: case LWS_CALLBACK_RECEIVE: case LWS_CALLBACK_BROADCAST: { conn = *(roxlu::WebSocketConnection**)user; if(conn && conn->ws != ws) { conn->ws = ws; } return websockets->onCallback(conn, reason, (char*)message, len); }; default:return 0; }; return 1; }
void WebSocketOpcode_handleServerWritable(struct libwebsocket *websocket, WebSocketOpcode *self, CSOUND *csound, void *messageBuffer) { const struct libwebsocket_protocols *protocol = libwebsockets_get_protocol(websocket); // If it's an output argument just return if (protocol->protocol_index < self->outputArgumentCount) { usleep(100); return; } int inputIndex = protocol->protocol_index - self->outputArgumentCount; OpcodeArgument *argument = &self->inputArguments[inputIndex]; int readItems = 0; if (argument->bytesWritten == 0) { readItems = csoundReadCircularBuffer(csound, argument->circularBuffer, argument->readBuffer, argument->itemsCount); } if (readItems != 0 || argument->bytesWritten != 0) { WebSocketOpcode_writeMessage(self, argument, messageBuffer, websocket); if (argument->argumentType == IRATE_VAR || argument->argumentType == IRATE_ARRAY) { argument->iRateVarSent = true; } } usleep(100); if (argument->iRateVarSent == false) { libwebsocket_callback_on_writable(self->webSocket->context, websocket); } }
static int Websocket_callback(struct libwebsocket_context *context, struct libwebsocket *websocket, enum libwebsocket_callback_reasons reason, void *user, void *inputData, size_t inputDataSize) { WebSocketOpcode *self = libwebsocket_context_user(context); CSOUND *csound = self->csound; void *messageBuffer = (void *)&self->webSocket->messageBuffer[LWS_SEND_BUFFER_PRE_PADDING]; switch (reason) { case LWS_CALLBACK_ESTABLISHED: { const struct libwebsocket_protocols *protocol = libwebsockets_get_protocol(websocket); csound->Message(csound, Str("websocket: connection established for %s\n"), protocol->name); break; } case LWS_CALLBACK_SERVER_WRITEABLE: { WebSocketOpcode_handleServerWritable(websocket, self, csound, messageBuffer); break; } case LWS_CALLBACK_RECEIVE: { WebSocketOpcode_handleReceive(websocket, self, csound, inputDataSize, inputData); break; } default: { break; } } return OK; }
static int callback_lws_mirror(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { int n; struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user; switch (reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_info("callback_lws_mirror: LWS_CALLBACK_ESTABLISHED\n"); pss->ringbuffer_tail = ringbuffer_head; pss->wsi = wsi; break; case LWS_CALLBACK_PROTOCOL_DESTROY: lwsl_notice("mirror protocol cleaning up\n"); for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++) if (ringbuffer[n].payload) free(ringbuffer[n].payload); break; case LWS_CALLBACK_SERVER_WRITEABLE: if (close_testing) break; while (pss->ringbuffer_tail != ringbuffer_head) { n = libwebsocket_write(wsi, (unsigned char *) ringbuffer[pss->ringbuffer_tail].payload + LWS_SEND_BUFFER_PRE_PADDING, ringbuffer[pss->ringbuffer_tail].len, LWS_WRITE_TEXT); if (n < 0) { lwsl_err("ERROR %d writing to mirror socket\n", n); return -1; } if (n < ringbuffer[pss->ringbuffer_tail].len) lwsl_err("mirror partial write %d vs %d\n", n, ringbuffer[pss->ringbuffer_tail].len); if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) pss->ringbuffer_tail = 0; else pss->ringbuffer_tail++; if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) libwebsocket_rx_flow_allow_all_protocol( libwebsockets_get_protocol(wsi)); // lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); if (lws_send_pipe_choked(wsi)) { libwebsocket_callback_on_writable(context, wsi); break; } /* * for tests with chrome on same machine as client and * server, this is needed to stop chrome choking */ #ifdef _WIN32 Sleep(1); #else usleep(1); #endif } break; case LWS_CALLBACK_RECEIVE: if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) { lwsl_err("dropping!\n"); goto choke; } if (ringbuffer[ringbuffer_head].payload) free(ringbuffer[ringbuffer_head].payload); ringbuffer[ringbuffer_head].payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING); ringbuffer[ringbuffer_head].len = len; memcpy((char *)ringbuffer[ringbuffer_head].payload + LWS_SEND_BUFFER_PRE_PADDING, in, len); if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; else ringbuffer_head++; if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2)) goto done; choke: lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi); libwebsocket_rx_flow_control(wsi, 0); // lwsl_debug("rx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); done: libwebsocket_callback_on_writable_all_protocol( libwebsockets_get_protocol(wsi)); break; /* * this just demonstrates how to use the protocol filter. If you won't * study and reject connections based on header content, you don't need * to handle this callback */ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: dump_handshake_info(wsi); /* you could return non-zero here and kill the connection */ break; default: break; } return 0; }
static int callback_lws_mirror(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { int n; struct per_session_data__lws_mirror *pss = user; switch (reason) { case LWS_CALLBACK_ESTABLISHED: fprintf(stderr, "callback_lws_mirror: " "LWS_CALLBACK_ESTABLISHED\n"); pss->ringbuffer_tail = ringbuffer_head; pss->wsi = wsi; break; case LWS_CALLBACK_SERVER_WRITEABLE: if (close_testing) break; if (pss->ringbuffer_tail != ringbuffer_head) { n = libwebsocket_write(wsi, (unsigned char *) ringbuffer[pss->ringbuffer_tail].payload + LWS_SEND_BUFFER_PRE_PADDING, ringbuffer[pss->ringbuffer_tail].len, LWS_WRITE_TEXT); if (n < 0) { fprintf(stderr, "ERROR writing to socket"); exit(1); } if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) pss->ringbuffer_tail = 0; else pss->ringbuffer_tail++; if (((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) < (MAX_MESSAGE_QUEUE - 15)) libwebsocket_rx_flow_control(wsi, 1); libwebsocket_callback_on_writable(context, wsi); } break; case LWS_CALLBACK_BROADCAST: n = libwebsocket_write(wsi, in, len, LWS_WRITE_TEXT); if (n < 0) fprintf(stderr, "mirror write failed\n"); break; case LWS_CALLBACK_RECEIVE: if (ringbuffer[ringbuffer_head].payload) free(ringbuffer[ringbuffer_head].payload); ringbuffer[ringbuffer_head].payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING); ringbuffer[ringbuffer_head].len = len; memcpy((char *)ringbuffer[ringbuffer_head].payload + LWS_SEND_BUFFER_PRE_PADDING, in, len); if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; else ringbuffer_head++; if (((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10)) libwebsocket_rx_flow_control(wsi, 0); libwebsocket_callback_on_writable_all_protocol( libwebsockets_get_protocol(wsi)); break; /* * this just demonstrates how to use the protocol filter. If you won't * study and reject connections based on header content, you don't need * to handle this callback */ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: dump_handshake_info((struct lws_tokens *)(long)user); /* you could return non-zero here and kill the connection */ break; default: break; } return 0; }
static int callback_mqtt(struct libwebsocket_context *context, #endif struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { struct mosquitto_db *db; struct mosquitto *mosq = NULL; struct mosquitto__packet *packet; int count, i, j; const struct libwebsocket_protocols *p; struct libws_mqtt_data *u = (struct libws_mqtt_data *)user; size_t pos; uint8_t *buf; int rc; uint8_t byte; db = &int_db; switch (reason) { case LWS_CALLBACK_ESTABLISHED: mosq = context__init(db, WEBSOCKET_CLIENT); if(mosq){ p = libwebsockets_get_protocol(wsi); for (i=0; i<db->config->listener_count; i++){ if (db->config->listeners[i].protocol == mp_websockets) { for (j=0; db->config->listeners[i].ws_protocol[j].name; j++){ if (p == &db->config->listeners[i].ws_protocol[j]){ mosq->listener = &db->config->listeners[i]; mosq->listener->client_count++; } } } } if(!mosq->listener){ mosquitto__free(mosq); return -1; } #if !defined(LWS_LIBRARY_VERSION_NUMBER) mosq->ws_context = context; #endif mosq->wsi = wsi; #ifdef WITH_TLS if(in){ mosq->ssl = (SSL *)in; if(!mosq->listener->ssl_ctx){ mosq->listener->ssl_ctx = SSL_get_SSL_CTX(mosq->ssl); } } #endif u->mosq = mosq; }else{ return -1; } easy_address(libwebsocket_get_socket_fd(wsi), mosq); if(!mosq->address){ /* getpeername and inet_ntop failed and not a bridge */ mosquitto__free(mosq); u->mosq = NULL; return -1; } if(mosq->listener->max_connections > 0 && mosq->listener->client_count > mosq->listener->max_connections){ if(db->config->connection_messages == true){ log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address); } mosquitto__free(mosq); u->mosq = NULL; return -1; } mosq->sock = libwebsocket_get_socket_fd(wsi); HASH_ADD(hh_sock, db->contexts_by_sock, sock, sizeof(mosq->sock), mosq); break; case LWS_CALLBACK_CLOSED: if(!u){ return -1; } mosq = u->mosq; if(mosq){ if(mosq->sock != INVALID_SOCKET){ HASH_DELETE(hh_sock, db->contexts_by_sock, mosq); mosq->sock = INVALID_SOCKET; mosq->pollfd_index = -1; } mosq->wsi = NULL; #ifdef WITH_TLS mosq->ssl = NULL; #endif do_disconnect(db, mosq); } break; case LWS_CALLBACK_SERVER_WRITEABLE: if(!u){ return -1; } mosq = u->mosq; if(!mosq){ return -1; } db__message_write(db, mosq); if(mosq->out_packet && !mosq->current_out_packet){ mosq->current_out_packet = mosq->out_packet; mosq->out_packet = mosq->out_packet->next; if(!mosq->out_packet){ mosq->out_packet_last = NULL; } } if(mosq->current_out_packet && !lws_send_pipe_choked(mosq->wsi)){ packet = mosq->current_out_packet; if(packet->pos == 0 && packet->to_process == packet->packet_length){ /* First time this packet has been dealt with. * libwebsockets requires that the payload has * LWS_SEND_BUFFER_PRE_PADDING space available before the * actual data and LWS_SEND_BUFFER_POST_PADDING afterwards. * We've already made the payload big enough to allow this, * but need to move it into position here. */ memmove(&packet->payload[LWS_SEND_BUFFER_PRE_PADDING], packet->payload, packet->packet_length); packet->pos += LWS_SEND_BUFFER_PRE_PADDING; } count = libwebsocket_write(wsi, &packet->payload[packet->pos], packet->to_process, LWS_WRITE_BINARY); if(count < 0){ if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ return -1; } return 0; } #ifdef WITH_SYS_TREE g_bytes_sent += count; #endif packet->to_process -= count; packet->pos += count; if(packet->to_process > 0){ if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ return -1; } break; } #ifdef WITH_SYS_TREE g_msgs_sent++; if(((packet->command)&0xF6) == PUBLISH){ g_pub_msgs_sent++; } #endif /* Free data and reset values */ mosq->current_out_packet = mosq->out_packet; if(mosq->out_packet){ mosq->out_packet = mosq->out_packet->next; if(!mosq->out_packet){ mosq->out_packet_last = NULL; } } packet__cleanup(packet); mosquitto__free(packet); mosq->next_msg_out = mosquitto_time() + mosq->keepalive; } if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ return -1; } if(mosq->current_out_packet){ libwebsocket_callback_on_writable(mosq->ws_context, mosq->wsi); } break; case LWS_CALLBACK_RECEIVE: if(!u || !u->mosq){ return -1; } mosq = u->mosq; pos = 0; buf = (uint8_t *)in; G_BYTES_RECEIVED_INC(len); while(pos < len){ if(!mosq->in_packet.command){ mosq->in_packet.command = buf[pos]; pos++; /* Clients must send CONNECT as their first command. */ if(mosq->state == mosq_cs_new && (mosq->in_packet.command&0xF0) != CONNECT){ return -1; } } if(mosq->in_packet.remaining_count <= 0){ do{ if(pos == len){ return 0; } byte = buf[pos]; pos++; mosq->in_packet.remaining_count--; /* Max 4 bytes length for remaining length as defined by protocol. * Anything more likely means a broken/malicious client. */ if(mosq->in_packet.remaining_count < -4){ return -1; } mosq->in_packet.remaining_length += (byte & 127) * mosq->in_packet.remaining_mult; mosq->in_packet.remaining_mult *= 128; }while((byte & 128) != 0); mosq->in_packet.remaining_count *= -1; if(mosq->in_packet.remaining_length > 0){ mosq->in_packet.payload = mosquitto__malloc(mosq->in_packet.remaining_length*sizeof(uint8_t)); if(!mosq->in_packet.payload){ return -1; } mosq->in_packet.to_process = mosq->in_packet.remaining_length; } } if(mosq->in_packet.to_process>0){ if(len - pos >= mosq->in_packet.to_process){ memcpy(&mosq->in_packet.payload[mosq->in_packet.pos], &buf[pos], mosq->in_packet.to_process); mosq->in_packet.pos += mosq->in_packet.to_process; pos += mosq->in_packet.to_process; mosq->in_packet.to_process = 0; }else{ memcpy(&mosq->in_packet.payload[mosq->in_packet.pos], &buf[pos], len-pos); mosq->in_packet.pos += len-pos; mosq->in_packet.to_process -= len-pos; return 0; } } /* All data for this packet is read. */ mosq->in_packet.pos = 0; #ifdef WITH_SYS_TREE G_MSGS_RECEIVED_INC(1); if(((mosq->in_packet.command)&0xF5) == PUBLISH){ G_PUB_MSGS_RECEIVED_INC(1); } #endif rc = handle__packet(db, mosq); /* Free data and reset values */ packet__cleanup(&mosq->in_packet); mosq->last_msg_in = mosquitto_time(); if(rc && (mosq->out_packet || mosq->current_out_packet)) { if(mosq->state != mosq_cs_disconnecting){ mosq->state = mosq_cs_disconnect_ws; } libwebsocket_callback_on_writable(mosq->ws_context, mosq->wsi); } else if (rc) { do_disconnect(db, mosq); return -1; } } break; default: break; } return 0; }
static int callback_lws_mirror(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { int n; struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user; switch (reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_info("callback_lws_mirror: " "LWS_CALLBACK_ESTABLISHED\n"); pss->ringbuffer_tail = ringbuffer_head; pss->wsi = wsi; break; case LWS_CALLBACK_PROTOCOL_DESTROY: lwsl_notice("mirror protocol cleaning up\n"); for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++) if (ringbuffer[n].payload) free(ringbuffer[n].payload); break; case LWS_CALLBACK_SERVER_WRITEABLE: if (close_testing) break; while (pss->ringbuffer_tail != ringbuffer_head) { n = libwebsocket_write(wsi, (unsigned char *) ringbuffer[pss->ringbuffer_tail].payload + LWS_SEND_BUFFER_PRE_PADDING, ringbuffer[pss->ringbuffer_tail].len, LWS_WRITE_TEXT); if (n < 0) { lwsl_err("ERROR %d writing to mirror socket\n", n); return -1; } if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) pss->ringbuffer_tail = 0; else pss->ringbuffer_tail++; if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) { for (n = 0; n < num_wsi_choked; n++) libwebsocket_rx_flow_control(wsi_choked[n], 1); num_wsi_choked = 0; } // lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); if (lws_send_pipe_choked(wsi)) { libwebsocket_callback_on_writable(context, wsi); return 0; } } break; case LWS_CALLBACK_RECEIVE: cout << string((char *) in, len) << endl; if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) { lwsl_err("dropping!\n"); goto choke; } if (ringbuffer[ringbuffer_head].payload) free(ringbuffer[ringbuffer_head].payload); ringbuffer[ringbuffer_head].payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING); ringbuffer[ringbuffer_head].len = len; memcpy((char *)ringbuffer[ringbuffer_head].payload + LWS_SEND_BUFFER_PRE_PADDING, in, len); if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; else ringbuffer_head++; if (((ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2)) goto done; choke: if (num_wsi_choked < sizeof wsi_choked / sizeof wsi_choked[0]) { libwebsocket_rx_flow_control(wsi, 0); wsi_choked[num_wsi_choked++] = wsi; } // lwsl_debug("rx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); done: libwebsocket_callback_on_writable_all_protocol( libwebsockets_get_protocol(wsi)); break; default: break; } return 0; }
static int callback_rtl_ws(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { int f; int bw; int n, nn = 0; int do_write = 0; struct per_session_data__rtl_ws *pss = (struct per_session_data__rtl_ws *)user; char* buffer = NULL; char tmpbuffer[30]; memset(tmpbuffer, 0, 30); switch (reason) { case LWS_CALLBACK_ESTABLISHED: lwsl_info("protocol starting\n"); pss->id = latest_user_id++; pss->block_id = 0; printf("id: %d\n", pss->id); if (current_user_id == 0) current_user_id = pss->id; printf("cid: %d\n", current_user_id); if (current_user_id != pss->id) { return -1; } break; case LWS_CALLBACK_PROTOCOL_DESTROY: lwsl_notice("protocol cleaning up\n"); send_data = 0; if (current_user_id == pss->id) current_user_id = 0; break; case LWS_CALLBACK_SERVER_WRITEABLE: pthread_mutex_lock(&data_mutex); do_write = transfer.block_id > pss->block_id && should_write(); pss->block_id = transfer.block_id; pthread_mutex_unlock(&data_mutex); if (do_write) { memset(send_buffer, 0, LWS_SEND_BUFFER_PRE_PADDING + SEND_BUFFER_SIZE + LWS_SEND_BUFFER_POST_PADDING); n = sprintf(tmpbuffer, "f %u;b %u;", rtl_freq(), rtl_sample_rate()); memcpy(&send_buffer[LWS_SEND_BUFFER_PRE_PADDING], tmpbuffer, n); nn = write_spectrum_message(&send_buffer[LWS_SEND_BUFFER_PRE_PADDING+n], SEND_BUFFER_SIZE/2); // TODO: LWS_WRITE_BINARY n = libwebsocket_write(wsi, (unsigned char *) &send_buffer[LWS_SEND_BUFFER_PRE_PADDING], n+nn, LWS_WRITE_TEXT); } usleep(1); if (send_data) libwebsocket_callback_on_writable(context, wsi); break; case LWS_CALLBACK_RECEIVE: buffer = malloc(len+1); memset(buffer, 0, len+1); memcpy(buffer, in, len); printf("%s\n", buffer); if ((len >= strlen(FREQ_CMD)) && strncmp(FREQ_CMD, buffer, strlen(FREQ_CMD)) == 0) { f = atoi(&buffer[strlen(FREQ_CMD)])*1000; printf("Trying to tune to %d Hz...\n", f); rtl_tune(f); } else if ((len >= strlen(SAMPLE_RATE_CMD)) && strncmp(SAMPLE_RATE_CMD, buffer, strlen(SAMPLE_RATE_CMD)) == 0) { bw = atoi(&buffer[strlen(SAMPLE_RATE_CMD)])*1000; printf("Trying to set sample rate to %d Hz...\n", bw); rtl_set_sample_rate(bw); } else if ((len >= strlen(START_CMD)) && strncmp(START_CMD, buffer, strlen(START_CMD)) == 0) { send_data = 1; libwebsocket_callback_on_writable_all_protocol( libwebsockets_get_protocol(wsi)); } else if ((len >= strlen(STOP_CMD)) && strncmp(STOP_CMD, buffer, strlen(STOP_CMD)) == 0) { send_data = 0; } free(buffer); break; default: break; } return 0; }
static int callback_nyx_websockets(struct libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason, void *user,void *in,size_t len) { struct per_session_data_nyx *pss =(struct per_session_data_nyx*)user; int n; node *wsd_state = (node*)libwebsocket_context_user(context); //node *daemon = (node*)libwebsocket_context_user(context); //node *wsd_state = node_GetNode(get_value(daemon)); node *found_prot = NULL; node *state = NULL; node *block = NULL; //node *daemon = NULL; node *daemon_obj = NULL; node *session_uid = NULL; long lsession_uid = 0; node *sessions_num = NULL; node *sessions = NULL; long lsessions_num = 0; if(wsd_state) { state = node_GetItem(wsd_state,0); block = node_GetItem(wsd_state,1); //daemon = node_GetItem(wsd_state,2); node *protocols = node_GetItem(wsd_state,3); session_uid = node_GetItem(wsd_state,4); node *session_uid_value = node_GetItemByKey(session_uid,"value"); lsession_uid = node_GetSint32(session_uid_value); sessions_num = node_GetItem(wsd_state,5); sessions = node_GetItem(wsd_state,6); node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); lsessions_num = node_GetSint32(sessions_num_value); daemon_obj = node_GetItem(wsd_state,9); if(wsi) { node *protocols_items = node_GetItemByKey(protocols,"items"); const struct libwebsocket_protocols *prot = libwebsockets_get_protocol(wsi); if(prot && prot->name) { node_ItemIterationReset(protocols_items); while(node_ItemIterationUnfinished(protocols_items)) { node *proto = node_ItemIterate(protocols_items); if(!strcmp(get_obj_name(proto),prot->name)) { found_prot = proto; } } } } } switch(reason) { //case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: case LWS_CALLBACK_CLIENT_ESTABLISHED: printf("new session created:%d, num:%d\n",lsession_uid,lsessions_num); pss->session = NULL; break; case LWS_CALLBACK_HTTP: if(len < 1) { libwebsockets_return_http_status(context,wsi,HTTP_STATUS_BAD_REQUEST,NULL); return(-1); } if(lws_hdr_total_length(wsi,WSI_TOKEN_POST_URI)) return(0); if(found_prot) { //printf("found prot in http callback : uid:%d,num:%d (sess:%x)\n",lsession_uid+1,lsessions_num,pss->session); if(!pss->session) { lsession_uid++; node *session_uid_value = node_GetItemByKey(session_uid,"value"); node_SetSint32(session_uid_value,lsession_uid); lsessions_num++; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); pss->session = create_session(state,sessions,lsession_uid,get_obj_name(found_prot)); node *session_privates = node_GetItemByKey(pss->session,"privates"); set_obj_int(session_privates,"is_http",1); //printf("created new session :%d actual sessions num:%d\n",lsession_uid,lsessions_num); } node *parameters = create_obj("parameters"); node *base_class = get_base_class(state); node *prot_value = create_class_instance(base_class); set_obj_string(prot_value,"name","protocol"); set_obj_string(prot_value,"value",get_obj_name(found_prot)); node_AddItem(parameters,prot_value); inc_obj_refcount(prot_value); char *url = str_CreateEmpty(); url = str_AddChars(url,in,len); node *url_value = create_class_instance(base_class); set_obj_string(url_value,"name","url"); set_obj_string(url_value,"value",url); node_AddItem(parameters,url_value); inc_obj_refcount(url_value); free(url); node_AddItem(parameters,pss->session); inc_obj_refcount(pss->session); //node_AddItem(parameters,daemon_obj); node_AddItem(parameters,sessions); inc_obj_refcount(sessions); node *tmp_parent = node_GetParent(found_prot); node *bmembers = node_GetItemByKey(block,"members"); node_SetParent(found_prot,bmembers); node *ret_obj = execute_obj(state,found_prot,block,parameters,True,False);//,True);resolve node_SetParent(found_prot,tmp_parent); //dec_obj_refcount(msg_value); dec_obj_refcount(prot_value); //add_garbage(state,msg_value);//TODO check if "just survives" add_garbage(state,prot_value); dec_obj_refcount(url_value); add_garbage(state,url_value); dec_obj_refcount(pss->session); dec_obj_refcount(sessions); node *ret_obj_value = node_GetItemByKey(ret_obj,"value"); if( (node_GetType(ret_obj_value)==NODE_TYPE_STRING && strlen(node_GetString(ret_obj_value))) || (node_GetType(ret_obj_value)==NODE_TYPE_BINARY && node_GetBinaryLength(ret_obj_value)) ) { //printf("returning http message: [%s] :%d\n",node_GetString(ret_obj_value),strlen(node_GetString(ret_obj_value))); //node *ret_obj_copy = node_CopyTree(ret_obj,True,True); node *ret_obj_copy = copy_class(ret_obj); //reset_obj_refcount(ret_obj_copy); set_obj_string(ret_obj_copy,"name","message"); add_member(pss->session,ret_obj_copy); inc_obj_refcount(ret_obj_copy); } libwebsocket_callback_on_writable(context, wsi); } break; case LWS_CALLBACK_HTTP_BODY_COMPLETION: if(found_prot) { printf("found prot in http body complete : %d,num:%d\n",lsession_uid,lsessions_num); if(daemon_obj) { printf("body: found daemon_obj\n"); } } else printf("body closed: prot not found\n"); //lwsl_notice("LWS_CALLBACK_HTTP_BODY_COMPLETION\n"); libwebsockets_return_http_status(context,wsi,HTTP_STATUS_OK,NULL); return(-1); case LWS_CALLBACK_HTTP_FILE_COMPLETION: if(found_prot) { //printf("found prot in http file complete : %d,num:%d\n",lsession_uid,lsessions_num); lsessions_num--; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); delete_session(state,sessions,pss->session); pss->session = NULL; if(daemon_obj) { printf("http: found daemon_obj\n"); } } else printf("file closed: prot not found\n"); return(-1); case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: if(found_prot) { int n; static const char *token_names[] = { /*[WSI_TOKEN_GET_URI] =*/ "GET URI", /*[WSI_TOKEN_POST_URI] =*/ "POST URI", /*[WSI_TOKEN_OPTIONS] =*/ "Options", /*[WSI_TOKEN_HOST] =*/ "Host", /*[WSI_TOKEN_CONNECTION] =*/ "Connection", /*[WSI_TOKEN_KEY1] =*/ "key 1", /*[WSI_TOKEN_KEY2] =*/ "key 2", /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol", /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade", /*[WSI_TOKEN_ORIGIN] =*/ "Origin", /*[WSI_TOKEN_DRAFT] =*/ "Draft", /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge", /* new for 04 */ /*[WSI_TOKEN_KEY] =*/ "Key", /*[WSI_TOKEN_VERSION] =*/ "Version", /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin", /* new for 05 */ /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions", /* client receives these */ /*[WSI_TOKEN_ACCEPT] =*/ "Accept", /*[WSI_TOKEN_NONCE] =*/ "Nonce", /*[WSI_TOKEN_HTTP] =*/ "Http", "Accept:", "Accept_Request_Headers:", "If-None-Match:", "If-Modified-Since:", "Accept-Encoding:", "Accept-Language:", "Pragma:", "Cache-Control:", "Authorization:", "Cookie:", "Content-Length:", "Content-Type:", "Date:", "Range:", "Referer:", "Uri-Args:", /*[WSI_TOKEN_MUXURL] =*/ "MuxURL", }; //printf("found prot in http filter callback : uid:%d,num:%d (sess:%x)\n",lsession_uid+1,lsessions_num,pss->session); if(!pss->session) { lsession_uid++; node *session_uid_value = node_GetItemByKey(session_uid,"value"); node_SetSint32(session_uid_value,lsession_uid); lsessions_num++; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); pss->session = create_session(state,sessions,lsession_uid,get_obj_name(found_prot)); //node *session_privates = node_GetItemByKey(pss->session,"privates"); //set_obj_int(session_privates,"is_http",1); } //printf("filter sess:%x\n",pss->session); for(n=0;n<(int)(sizeof(token_names)/sizeof(token_names[0]));n++) { if (!lws_hdr_total_length(wsi, n)) continue; char *cookies = (char*)malloc(512); memset(cookies,0,512); lws_hdr_copy(wsi,cookies,511,n); //printf("header:%s = [%s]\n",token_names[n],cookies); //fflush(stdout); if(pss->session && !strcmp("Cookie:",token_names[n])) { //printf("cookie found:%s = [%s]\n",token_names[n],cookies); //fflush(stdout); node *base_class = get_base_class(state); node *cookie_value = create_class_instance(base_class); set_obj_string(cookie_value,"name","cookie"); set_obj_string(cookie_value,"value",cookies); add_member(pss->session,cookie_value); inc_obj_refcount(cookie_value); } free(cookies); } } break; case LWS_CALLBACK_HTTP_WRITEABLE: case LWS_CALLBACK_SERVER_WRITEABLE: { //node_PrintTree(pss->session); node *message = get_member(pss->session,"message"); node *session_privates = node_GetItemByKey(pss->session,"privates"); node *http_only = node_GetItemByKey(session_privates,"is_http"); while(message) { //node *session_id = get_member(pss->session,"id"); //node *session_id_value = node_GetItemByKey(session_id,"value"); node *message_value = node_GetItemByKey(message,"value"); unsigned char *me = NULL; unsigned long me_len = 0; if(node_GetType(message_value)==NODE_TYPE_STRING) { me = (unsigned char*)node_GetString(message_value); me_len = strlen((char*)me); } else if(node_GetType(message_value)==NODE_TYPE_BINARY) { me = (unsigned char*)node_GetBinary(message_value); me_len = node_GetBinaryLength(message_value); } //printf("sending message now: [%s] to: %d\n",me,node_GetSint32(session_id_value)); //fflush(stdout); unsigned char *buf = (unsigned char*)malloc(LWS_SEND_BUFFER_PRE_PADDING + me_len + LWS_SEND_BUFFER_POST_PADDING); memcpy(buf+LWS_SEND_BUFFER_PRE_PADDING,me,me_len); if(http_only) //n = libwebsocket_write(wsi, me, me_len, LWS_WRITE_HTTP); n = libwebsocket_write(wsi,buf+LWS_SEND_BUFFER_PRE_PADDING,me_len,LWS_WRITE_HTTP); else //n = libwebsocket_write(wsi, me, me_len, LWS_WRITE_TEXT); n = libwebsocket_write(wsi,buf+LWS_SEND_BUFFER_PRE_PADDING,me_len,LWS_WRITE_TEXT); free(buf); if(n<0) { printf("ERROR %d writing to socket, hanging up\n", n); return(1); } if(n<(long)me_len) { printf("Partial write\n"); return(-1); } //node_FreeTree(pss->message); remove_member(pss->session,message); dec_obj_refcount(message); //printf("removing message from queue:%x (%d)\n",message,get_obj_refcount(message)); add_garbage(state,message); message = get_member(pss->session,"message"); } if(http_only) { //if(lws_http_transaction_completed(wsi)) //{ //printf("removing http session num:%d\n",lsessions_num); lsessions_num--; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); delete_session(state,sessions,pss->session); pss->session = NULL; //printf("removed http\n"); return -1; //return(-1); //} //else // libwebsocket_callback_on_writable(context, wsi); } } break; case LWS_CALLBACK_ESTABLISHED: if(found_prot) { //printf("found prot in establish callback : uid:%d,num:%d (sess:%x)\n",lsession_uid+1,lsessions_num,pss->session); if(!pss->session) { lsession_uid++; node *session_uid_value = node_GetItemByKey(session_uid,"value"); node_SetSint32(session_uid_value,lsession_uid); lsessions_num++; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); pss->session = create_session(state,sessions,lsession_uid,get_obj_name(found_prot)); } if(daemon_obj) { node *connect_handler = get_member(daemon_obj,"connect_handler"); if(connect_handler) { connect_handler = resolve_object(state,connect_handler); node *parameters = create_obj("parameters"); node *base_class = get_base_class(state); node *prot_value = create_class_instance(base_class); set_obj_string(prot_value,"name","protocol"); set_obj_string(prot_value,"value",get_obj_name(found_prot)); node_AddItem(parameters,prot_value); inc_obj_refcount(prot_value); node_AddItem(parameters,pss->session); inc_obj_refcount(pss->session); node_AddItem(parameters,sessions); inc_obj_refcount(sessions); node *tmp_parent = node_GetParent(connect_handler); node *bmembers = node_GetItemByKey(block,"members"); node_SetParent(connect_handler,bmembers); node *ret_obj = execute_obj(state,connect_handler,block,parameters,True,False);//,True);resolve node_SetParent(connect_handler,tmp_parent); dec_obj_refcount(prot_value); add_garbage(state,prot_value); dec_obj_refcount(pss->session); dec_obj_refcount(sessions); node *ret_obj_value = node_GetItemByKey(ret_obj,"value"); if(node_GetType(ret_obj_value)==NODE_TYPE_STRING && strlen(node_GetString(ret_obj_value))) { } } } } break; case LWS_CALLBACK_CLOSED_HTTP: break; case LWS_CALLBACK_CLOSED: case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: if(found_prot) { //printf("found prot in closed callback : uid:%d,num:%d (sess:%x)\n",lsession_uid,lsessions_num,pss->session); if(daemon_obj) { //printf("closed: found daemon_obj\n"); node *disconnect_handler = get_member(daemon_obj,"disconnect_handler"); if(disconnect_handler) { //printf("disc found\n"); disconnect_handler = resolve_object(state,disconnect_handler); node *parameters = create_obj("parameters"); node *base_class = get_base_class(state); node *prot_value = create_class_instance(base_class); set_obj_string(prot_value,"name","protocol"); set_obj_string(prot_value,"value",get_obj_name(found_prot)); node_AddItem(parameters,prot_value); inc_obj_refcount(prot_value); node_AddItem(parameters,pss->session); inc_obj_refcount(pss->session); node_AddItem(parameters,sessions); inc_obj_refcount(sessions); node *tmp_parent = node_GetParent(disconnect_handler); node *bmembers = node_GetItemByKey(block,"members"); node_SetParent(disconnect_handler,bmembers); node *ret_obj = execute_obj(state,disconnect_handler,block,parameters,True,False);//,True);resolve node_SetParent(disconnect_handler,tmp_parent); dec_obj_refcount(prot_value); add_garbage(state,prot_value); dec_obj_refcount(pss->session); dec_obj_refcount(sessions); node *ret_obj_value = node_GetItemByKey(ret_obj,"value"); if(node_GetType(ret_obj_value)==NODE_TYPE_STRING && strlen(node_GetString(ret_obj_value))) { } } } lsessions_num--; node *sessions_num_value = node_GetItemByKey(sessions_num,"value"); node_SetSint32(sessions_num_value,lsessions_num); delete_session(state,sessions,pss->session); pss->session = NULL; //printf("disconnected\n"); } else { printf("closed connection without prot found\n"); if(pss->session) printf("but a session was found\n"); } break; case LWS_CALLBACK_RECEIVE: if(len>1024) { //TODO use some variable lwsl_err("Server received packet bigger than %u, hanging up\n", 1024); return(1); } if(found_prot) { node *parameters = create_obj("parameters"); node *base_class = get_base_class(state); node *prot_value = create_class_instance(base_class); set_obj_string(prot_value,"name","protocol"); set_obj_string(prot_value,"value",get_obj_name(found_prot)); node_AddItem(parameters,prot_value); inc_obj_refcount(prot_value); char *msg = str_CreateEmpty(); msg = str_AddChars(msg,in,len); node *msg_value = create_class_instance(base_class); set_obj_string(msg_value,"name","message"); set_obj_string(msg_value,"value",msg); node_AddItem(parameters,msg_value); inc_obj_refcount(msg_value); free(msg); /*node *session_value = create_class_instance(base_class); reset_obj_refcount(session_value); add_garbage(state,session_value); set_obj_string(session_value,"name","session_id"); set_obj_int(session_value,"value",lsession_uid); set_obj_int(session_value,"item_index",2); node_AddItem(parameters,session_value); */ node_AddItem(parameters,pss->session); inc_obj_refcount(pss->session); //node_AddItem(parameters,daemon_obj); //inc_obj_refcount(daemon_obj); node_AddItem(parameters,sessions); inc_obj_refcount(sessions); //printf("recv callback\n"); //fflush(stdout); node *tmp_parent = node_GetParent(found_prot); node *bmembers = node_GetItemByKey(block,"members"); node_SetParent(found_prot,bmembers); node *ret_obj = execute_obj(state,found_prot,block,parameters,True,False);//,True);resolve node_SetParent(found_prot,tmp_parent); //printf("recv callback finished\n"); //fflush(stdout); dec_obj_refcount(msg_value); dec_obj_refcount(prot_value); add_garbage(state,msg_value);//TODO check if "just survives" add_garbage(state,prot_value); dec_obj_refcount(pss->session); dec_obj_refcount(sessions); //dec_obj_refcount(daemon_obj); //printf("recv gc\n"); //fflush(stdout); //node *ret_obj_value = node_GetItemByKey(ret_obj,"value"); //char *me = node_GetString(ret_obj_value); //printf("returned string:[%s]\n",me); node *ret_obj_value = node_GetItemByKey(ret_obj,"value"); if(node_GetType(ret_obj_value)==NODE_TYPE_STRING && strlen(node_GetString(ret_obj_value))) { //printf("returning message: [%s] :%d\n",node_GetString(ret_obj_value),strlen(node_GetString(ret_obj_value))); //node *ret_obj_copy = node_CopyTree(ret_obj,True,True); node *ret_obj_copy = copy_class(ret_obj); //reset_obj_refcount(ret_obj_copy); set_obj_string(ret_obj_copy,"name","message"); add_member(pss->session,ret_obj_copy); inc_obj_refcount(ret_obj_copy); //set_obj_string(ret_obj,"name","message"); //add_member(pss->session,ret_obj); //inc_obj_refcount(ret_obj); } libwebsocket_callback_on_writable(context, wsi); } break; default: break; } return(0); }
int lws_client_callback(struct libwebsocket_context* context, struct libwebsocket *ws, enum libwebsocket_callback_reasons reason, void *user, void *data, size_t len){ const struct libwebsocket_protocols* lws_protocol = (ws == NULL ? NULL : libwebsockets_get_protocol(ws)); int idx = lws_protocol? lws_protocol->protocol_index : 0; Connection* conn; Reactor* reactor = NULL; Protocol* protocol; for (int i=0; i<(int)reactors.size(); i++){ if (reactors[i]->getContext() == context){ reactor = reactors[i]; protocol = reactor->protocol(idx); conn = ((Client*) reactor)->getConnection(); if (conn){ conn->context = context; } break; } else { } } ofLog( OF_LOG_VERBOSE, "[ofxLibwebsockets] " + getCallbackReason(reason) ); if (reason == LWS_CALLBACK_CLIENT_ESTABLISHED ){ libwebsocket_callback_on_writable(context, ws); } else if (reason == LWS_CALLBACK_CLOSED){ } switch (reason) { // cases we may use in the future case LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: case LWS_CALLBACK_PROTOCOL_INIT: // this may be useful, says we're OK to allocate protocol data case LWS_CALLBACK_WSI_CREATE: case LWS_CALLBACK_HTTP_BODY_COMPLETION: case LWS_CALLBACK_HTTP_FILE_COMPLETION: case LWS_CALLBACK_HTTP_WRITEABLE: case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: return 0; // check if we allow this connection (default is always yes) case LWS_CALLBACK_FILTER_HTTP_CONNECTION: case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: if (protocol != NULL){ return reactor->_allow(ws, protocol, (int)(long)user)? 0 : 1; } else { return 0; } // need to serve up an HTTP file case LWS_CALLBACK_HTTP: if ( reactor != NULL){ return reactor->_http(ws, (char*)data); } else { return 0; } // we're not really worried about these at the moment case LWS_CALLBACK_CLOSED_HTTP: case LWS_CALLBACK_ADD_POLL_FD: case LWS_CALLBACK_DEL_POLL_FD: case LWS_CALLBACK_CHANGE_MODE_POLL_FD: case LWS_CALLBACK_LOCK_POLL: case LWS_CALLBACK_UNLOCK_POLL: case LWS_CALLBACK_GET_THREAD_ID: case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: return 1; // catch-all for most important events: // LWS_CALLBACK_CLIENT_CONNECTION_ERROR // LWS_CALLBACK_CLIENT_ESTABLISHED // LWS_CALLBACK_RECEIVE // LWS_CALLBACK_CLIENT_RECEIVE // LWS_CALLBACK_CLIENT_RECEIVE_PONG // LWS_CALLBACK_CLIENT_WRITEABLE default: if ( reactor != NULL ){ //conn = *(Connection**)user; if (conn && conn->ws != ws && ws != NULL){ conn->ws = ws; conn->context = context; } return reactor->_notify(conn, reason, (char*)data, len); } else { return 0; } } return 1; // FAIL (e.g. unhandled case/break in switch) }
int lws_callback(struct libwebsocket_context* context, struct libwebsocket *ws, enum libwebsocket_callback_reasons reason, void *user, void *data, size_t len) { const struct libwebsocket_protocols* lws_protocol = (ws == NULL ? NULL : libwebsockets_get_protocol(ws)); int idx = lws_protocol? lws_protocol->protocol_index : 0; // valid connection w/o a protocol if ( ws != NULL && lws_protocol == NULL ){ // OK for now, returning 0 above } //bool bAllowAllProtocls = (ws != NULL ? lws_protocol == NULL : false); Connection* conn; Connection** conn_ptr = (Connection**)user; Server* reactor = NULL; Protocol* protocol = NULL; for (int i=0; i<(int)reactors.size(); i++){ if (reactors[i]->getContext() == context){ reactor = (Server*) reactors[i]; protocol = reactor->protocol( (idx > 0 ? idx : 0) ); break; } else { } } ofLog( OF_LOG_VERBOSE, "[ofxLibwebsockets] "+ getCallbackReason(reason) ); if (reason == LWS_CALLBACK_ESTABLISHED){ // server completed handshake, need to ask for next "writable" callback libwebsocket_callback_on_writable(context, ws); // now is when you can set the "user" data, // which we use to instantiate / refer to the ofxLibwebsockets::Connection if ( reactor != NULL ){ *conn_ptr = new Connection(reactor, protocol); } } else if (reason == LWS_CALLBACK_CLOSED){ //if (*conn_ptr != NULL) //delete *conn_ptr; } switch (reason) { // we may use these in the future! case LWS_CALLBACK_WSI_CREATE: case LWS_CALLBACK_WSI_DESTROY: case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: case LWS_CALLBACK_HTTP_BODY_COMPLETION: case LWS_CALLBACK_HTTP_FILE_COMPLETION: case LWS_CALLBACK_HTTP_WRITEABLE: case LWS_CALLBACK_CLOSED_HTTP: case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: return 0; case LWS_CALLBACK_FILTER_HTTP_CONNECTION: if (protocol != NULL ){ // return 0 == allow, 1 == block return reactor->_allow(ws, protocol, (int)(long)data) ? 0 : 1; } else { return 0; } case LWS_CALLBACK_PROTOCOL_INIT: return 0; case LWS_CALLBACK_HTTP: return reactor->_http(ws, (char*)data); // we're not really worried about this at the moment case LWS_CALLBACK_ADD_POLL_FD: case LWS_CALLBACK_DEL_POLL_FD: case LWS_CALLBACK_LOCK_POLL: case LWS_CALLBACK_UNLOCK_POLL: case LWS_CALLBACK_CHANGE_MODE_POLL_FD: case LWS_CALLBACK_PROTOCOL_DESTROY: case LWS_CALLBACK_GET_THREAD_ID: case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: return 0; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: case LWS_CALLBACK_ESTABLISHED: case LWS_CALLBACK_CLIENT_ESTABLISHED: case LWS_CALLBACK_CLOSED: case LWS_CALLBACK_SERVER_WRITEABLE: case LWS_CALLBACK_CLIENT_WRITEABLE: case LWS_CALLBACK_RECEIVE: // server receive case LWS_CALLBACK_CLIENT_RECEIVE: // client receive case LWS_CALLBACK_CLIENT_RECEIVE_PONG: if ( user != NULL ){ conn = *(Connection**)user; } if (conn != NULL && (conn->ws != ws || conn->ws == NULL) ){ conn->context = context; conn->ws = ws; conn->setupAddress(); } if (reactor){ return reactor->_notify(conn, reason, (char*)data, len); } else { return 0; } default: break; } return 0; }