コード例 #1
0
void vrpn_Imager_Stream_Buffer::mainloop(void)
{
    // Required from all servers
    server_mainloop();

    // See if we have a new image description from a logging thread.  If so,
    // fill in our values and send a description to any attached clients.
    const char *channelBuffer = NULL;
    if (d_shared_state.get_imager_description(d_nRows, d_nCols, d_nDepth,
                                              d_nChannels, &channelBuffer)) {
        int i;
        const char *bufptr = channelBuffer;
        for (i = 0; i < d_nChannels; i++) {
            d_channels[i].unbuffer(&bufptr);
        }
        delete[] const_cast<char *>(channelBuffer);
        send_description();
    }

    // See if we have any messages waiting in the queue from the logging thread.
    // If we do, get an initial count and then send that many messages to the
    // client.  Don't go looking again this iteration or we may never return --
    // the server is quite possibly packing frames faster than we can send them.
    // Note that the messages in the queue have already been transcoded for our
    // and sender ID.
    unsigned count = d_shared_state.get_logger_to_client_queue_size();
    if (count) {
        unsigned i;
        for (i = 0; i < count; i++) {
            // Read the next message from the queue.
            vrpn_HANDLERPARAM p;
            if (!d_shared_state.retrieve_logger_to_client_message(&p)) {
                fprintf(stderr, "vrpn_Imager_Stream_Buffer::mainloop(): Could "
                                "not retrieve message from queue\n");
                break;
            }

            // Decrement the in-buffer frame count whenever we see a begin_frame
            // message.  This will un-block the way for later frames to be
            // buffered.
            if (p.type == d_begin_frame_m_id) {
                d_shared_state.decrement_frames_in_queue();
            }

            // Pack and send the message to the client, then delete the buffer
            // associated with the message.  Send them all reliably.  Send them
            // all using our sender ID.
            if (d_connection->pack_message(p.payload_len, p.msg_time, p.type,
                                           d_sender_id, p.buffer,
                                           vrpn_CONNECTION_RELIABLE) != 0) {
                fprintf(stderr, "vrpn_Imager_Stream_Buffer::mainloop(): Could "
                                "not pack message\n");
                break;
            }
            delete[] const_cast<char *>(p.buffer);
        }
    }
}
コード例 #2
0
/**
 * Decodes and dispatches a received message to its handler.
 */
ProtocolError Protocol::handle_received_message(Message& message,
		CoAPMessageType::Enum& message_type)
{
	last_message_millis = callbacks.millis();
	pinger.message_received();
	uint8_t* queue = message.buf();
	message_type = Messages::decodeType(queue, message.length());
	token_t token = queue[4];
	message_id_t msg_id = CoAP::message_id(queue);
	ProtocolError error = NO_ERROR;
	//DEBUG("message type %d", message_type);
	switch (message_type)
	{
	case CoAPMessageType::DESCRIBE:
	{
		// 4 bytes header, 1 byte token, 2 bytes location path
		// 2 bytes optional single character location path for describe flags
		int descriptor_type = DESCRIBE_ALL;
		if (message.length()>8)
			descriptor_type = queue[8];
		error = send_description(token, msg_id, descriptor_type);
		break;
	}

	case CoAPMessageType::FUNCTION_CALL:
		return functions.handle_function_call(token, msg_id, message, channel,
				descriptor.call_function);

	case CoAPMessageType::VARIABLE_REQUEST:
	{
		char variable_key[13];
		variables.decode_variable_request(variable_key, message);
		return variables.handle_variable_request(variable_key, message,
				channel, token, msg_id,
				descriptor.variable_type, descriptor.get_variable);
	}
	case CoAPMessageType::SAVE_BEGIN:
		// fall through
	case CoAPMessageType::UPDATE_BEGIN:
		return chunkedTransfer.handle_update_begin(token, message, channel);

	case CoAPMessageType::CHUNK:
		return chunkedTransfer.handle_chunk(token, message, channel);
	case CoAPMessageType::UPDATE_DONE:
		return chunkedTransfer.handle_update_done(token, message, channel);

	case CoAPMessageType::EVENT:
		return subscriptions.handle_event(message, descriptor.call_event_handler, channel);

	case CoAPMessageType::KEY_CHANGE:
		return handle_key_change(message);

	case CoAPMessageType::SIGNAL_START:
		message.set_length(
				Messages::coded_ack(message.buf(), token,
						ChunkReceivedCode::OK, queue[2], queue[3]));
		callbacks.signal(true, 0, NULL);
		return channel.send(message);

	case CoAPMessageType::SIGNAL_STOP:
		message.set_length(
				Messages::coded_ack(message.buf(), token,
						ChunkReceivedCode::OK, queue[2], queue[3]));
		callbacks.signal(false, 0, NULL);
		return channel.send(message);

	case CoAPMessageType::HELLO:
		if (message.get_type()==CoAPType::CON)
			send_empty_ack(message, msg_id);
		descriptor.ota_upgrade_status_sent();
		break;

	case CoAPMessageType::TIME:
		handle_time_response(
				queue[6] << 24 | queue[7] << 16 | queue[8] << 8 | queue[9]);
		break;

	case CoAPMessageType::PING:
		message.set_length(
				Messages::empty_ack(message.buf(), queue[2], queue[3]));
		error = channel.send(message);
		break;

	case CoAPMessageType::EMPTY_ACK:
	case CoAPMessageType::ERROR:
	default:
		; // drop it on the floor
	}

	// all's well
	return error;
}