Esempio n. 1
0
/**
 *  Mark the connection as connected
 */
void ConnectionImpl::setConnected()
{
    // store connected state
    _state = state_connected;

    // we're going to call the handler, which can destruct the connection,
    // so we must monitor if the queue object is still valid after calling
    Monitor monitor(this);

    // inform handler
    _handler->onConnected(_parent);

    // empty the queue of messages
    while (monitor.valid() && !_queue.empty())
    {
        // get the next message
        OutBuffer buffer(std::move(_queue.front()));

        // remove it from the queue
        _queue.pop();

        // send it
        _handler->onData(_parent, buffer.data(), buffer.size());
    }

    // leap out if object is dead
    if (!monitor.valid()) return;

    // if the close method was called before, and no channel is waiting
    // for an answer, we can now safely send out the close frame
    if (_closed && _state == state_connected && !waiting()) sendClose();
}
Esempio n. 2
0
/**
 *  Mark the connection as connected
 */
void ConnectionImpl::setConnected()
{
    // store connected state
    _state = state_connected;

    // if the close method was called before, the frame was not
    // sent. append it to the end of the queue to make sure we
    // are correctly closed down.
    if (_closed && !sendClose()) return;

    // we're going to call the handler, which can destruct the connection,
    // so we must monitor if the queue object is still valid after calling
    Monitor monitor(this);

    // inform handler
    _handler->onConnected(_parent);

    // empty the queue of messages
    while (monitor.valid() && !_queue.empty())
    {
        // get the next message
        OutBuffer buffer(std::move(_queue.front()));

        // remove it from the queue
        _queue.pop();

        // send it
        _handler->onData(_parent, buffer.data(), buffer.size());
    }
}
Esempio n. 3
0
int
main( int argc, char **argv ) {
    int sendRate;
    rbudpSender_t *rbudpSender;

    if ( argc < 4 ) {
        printf( "Usage: sendfile <receiver> <sending rate (Kbps)> <MTU>\n" );
        exit( 1 );
    }

    sendRate = atoi( argv[2] );
    // QUANTAnet_rbudpSender_c *mysender = new QUANTAnet_rbudpSender_c (38000);
    rbudpSender = malloc( sizeof( rbudpSender_t ) );
    memset( rbudpSender, 0, sizeof( rbudpSender_t ) );

    // the constructor
    QUANTAnet_rbudpSender_c( rbudpSender, SEND_PORT );

    // mysender->init (argv[1]);
    initSender( rbudpSender, argv[1] );

    QUANTAnet_rbudpBase_c( &rbudpSender->rbudpBase );
    // mysender->sendfile (sendRate, atoi (argv[3]));
    rbSendfile( rbudpSender, sendRate, atoi( argv[3] ), ( char * ) 0 );

    // mysender->close ();
    sendClose( rbudpSender );
    return 1;
}
Esempio n. 4
0
/**
 *  Parse the buffer into a recognized frame
 *
 *  Every time that data comes in on the connection, you should call this method to parse
 *  the incoming data, and let it handle by the AMQP library. This method returns the number
 *  of bytes that were processed.
 *
 *  If not all bytes could be processed because it only contained a partial frame, you should
 *  call this same method later on when more data is available. The AMQP library does not do
 *  any buffering, so it is up to the caller to ensure that the old data is also passed in that
 *  later call.
 *
 *  @param  buffer      buffer to decode
 *  @return             number of bytes that were processed
 */
uint64_t ConnectionImpl::parse(const Buffer &buffer)
{
    // do not parse if already in an error state
    if (_state == state_closed) return 0;

    // number of bytes processed
    uint64_t processed = 0;

    // create a monitor object that checks if the connection still exists
    Monitor monitor(this);

    // keep looping until we have processed all bytes, and the monitor still
    // indicates that the connection is in a valid state
    while (processed < buffer.size() && monitor.valid())
    {
        // prevent protocol exceptions
        try
        {
            // try to recognize the frame
            ReceivedFrame receivedFrame(ReducedBuffer(buffer, processed), _maxFrame);
            if (!receivedFrame.complete()) return processed;

            // process the frame
            receivedFrame.process(this);

            // number of bytes processed
            uint64_t bytes = receivedFrame.totalSize();

            // add bytes
            processed += bytes;
        }
        catch (const ProtocolException &exception)
        {
            // something terrible happened on the protocol (like data out of range)
            reportError(exception.what());

            // done
            return processed;
        }
    }

    // leap out if the connection object no longer exists
    if (!monitor.valid() || !_closed || _state != state_connected) return processed;

    // the close() function was called, but if the close frame was not yet sent
    // if there are no waiting channels, we can do that right now
    if (!waitingChannels()) sendClose();

    // done
    return processed;
}
Esempio n. 5
0
/**
 *  Close the connection
 *  This will close all channels
 *  @return bool
 */
bool ConnectionImpl::close()
{
    // leap out if already closed or closing
    if (_closed) return false;

    // mark that the object is closed
    _closed = true;
    
    // if still busy with handshake, we delay closing for a while
    if (_state == state_handshake || _state == state_protocol) return true;

    // perform the close operation
    sendClose();
    
    // done
    return true;
}
Esempio n. 6
0
/**
 *  Close the connection
 *  This will close all channels
 *  @return bool
 */
bool ConnectionImpl::close()
{
    // leap out if already closed or closing
    if (_closed) return false;

    // mark that the object is closed
    _closed = true;

    // after the send operation the object could be dead
    Monitor monitor(this);

    // number of channels that are waiting for an answer and that have further data
    int waiters = 0;

    // loop over all channels, and close them
    for (auto iter = _channels.begin(); iter != _channels.end(); iter++)
    {
        // close the channel
        iter->second->close();

        // we could be dead now
        if (!monitor.valid()) return true;

        // is this channel waiting for an answer?
        if (iter->second->waiting()) waiters++;
    }

    // if still busy with handshake, we delay closing for a while
    if (waiters > 0 || _state != state_connected) return true;

    // perform the close frame
    sendClose();

    // done
    return true;
}
Esempio n. 7
0
/**
 *  Mark the connection as connected
 */
void ConnectionImpl::setConnected()
{
    // store connected state
    _state = state_connected;

    // if the close operation was already called, we do that again now again
    // so that the actual messages to close down the connection and the channel 
    // are appended to the queue
    if (_closed && !sendClose()) return;
    
    // we're going to call the handler, which can destruct the connection,
    // so we must monitor if the queue object is still valid after calling
    Monitor monitor(this);
    
    // inform handler
    _handler->onConnected(_parent);
    
    // leap out if the connection no longer exists
    if (!monitor.valid()) return;
    
    // empty the queue of messages
    while (!_queue.empty())
    {
        // get the next message
        OutBuffer buffer(std::move(_queue.front()));

        // remove it from the queue
        _queue.pop();
        
        // send it
        _handler->onData(_parent, buffer.data(), buffer.size());
        
        // leap out if the connection was destructed
        if (!monitor.valid()) return;
    }
}
Esempio n. 8
0
bool I2CController::step(I2COp** result) {
	bool processing = true;

	*result = NULL;

	while (processing) {
		switch (state) {
		default:
		case I2C_STATE_ERROR:
			state = I2C_STATE_START;
			return true;
		case I2C_STATE_START_WAIT:
		case I2C_STATE_WRITE_ADDR_WAIT:
		case I2C_STATE_WRITE_DATA_WAIT:
		case I2C_STATE_READ_DATA_WAIT:
			if (intSet()) {
				state = (I2CState) (state + 1);
			} else {
				processing = false;
			}
			break;
		case I2C_STATE_START:
			if (pendingOps.getSize() > 0) {
				sendStart();
				state = I2C_STATE_START_WAIT;
			} else {
				processing = false;
			}
			break;
		case I2C_STATE_START_RESPONSE:
			switch (TW_STATUS) {
			case TW_REP_START:
			case TW_START:
				state = I2C_STATE_WRITE_ADDR;
				break;
			case TW_MT_ARB_LOST:
				state = I2C_STATE_START;
				break;
			default:
				state = I2C_STATE_ERROR;
				break;
			}
			break;
		case I2C_STATE_WRITE_ADDR:
			writeByte(
					(pendingOps.peek()->addr << 1)
							| (pendingOps.peek()->write ? TW_WRITE : TW_READ));
			state = I2C_STATE_WRITE_ADDR_WAIT;
			break;
		case I2C_STATE_WRITE_ADDR_RESPONSE:
			switch (TW_STATUS) {
			case TW_MT_SLA_ACK:
			case TW_MR_SLA_ACK:
				state = pendingOps.peek()->write ?
						I2C_STATE_WRITE_DATA : I2C_STATE_READ_DATA;
				break;
			case TW_MT_SLA_NACK:
			case TW_MR_SLA_NACK:
			case TW_MT_ARB_LOST:
				state = I2C_STATE_START;
				break;
			default:
				state = I2C_STATE_ERROR;
				break;
			}
			break;
		case I2C_STATE_WRITE_DATA:
			if (!pendingOps.getSize()) {
				state = I2C_STATE_START;
			} else if (!pendingOps.peek()->data.getSize()) {
				state = I2C_STATE_DATA_DONE;
			} else {
				writeByte(pendingOps.peek()->data.peek());
				state = I2C_STATE_WRITE_DATA_WAIT;
			}
			break;
		case I2C_STATE_WRITE_DATA_RESPONSE:
			switch (TW_STATUS) {
			case TW_MT_DATA_ACK:
				pendingOps.peek()->data.dequeue();
				state = I2C_STATE_WRITE_DATA;
				break;
			case TW_MT_DATA_NACK:
			case TW_MT_ARB_LOST:
				state = I2C_STATE_DATA_DONE;
				break;
			default:
				state = I2C_STATE_ERROR;
				break;
			}
			break;
		case I2C_STATE_READ_DATA:
			if (pendingOps.peek()->data.full()) {
				state = I2C_STATE_DATA_DONE;
			} else {
				requestByte(
						pendingOps.peek()->data.getSize()
								!= pendingOps.peek()->data.getBufferSize() - 1);
				state = I2C_STATE_READ_DATA_WAIT;
			}
			break;
		case I2C_STATE_READ_DATA_RESPONSE:
			switch (TW_STATUS) {
			case TW_MR_DATA_ACK:
				pendingOps.peek()->data.enqueue(readByte());
				state = I2C_STATE_READ_DATA;
				break;
			case TW_MR_DATA_NACK:
				pendingOps.peek()->data.enqueue(readByte());
				state = I2C_STATE_DATA_DONE;
				break;
			default:
				state = I2C_STATE_ERROR;
				break;
			}
			break;
		case I2C_STATE_DATA_DONE:
			pendingOps.dequeue(result);
		case I2C_STATE_CLOSE:
			if (!pendingOps.getSize())
				sendClose();
			if (state == I2C_STATE_DATA_DONE) {
				state = I2C_STATE_START;
				return true;
			} else {
				state = I2C_STATE_START;
				break;
			}
		}
	}
	return false;
}