Beispiel #1
0
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;
      }
    }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
    }
}
Beispiel #4
0
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
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);
}
Beispiel #11
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)
	}
Beispiel #12
0
	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;
	}