// This function is going to use uIP's protosockets to handle the connection. // This means it must return int, because of the way the protosockets work. // In a nutshell, when a PSOCK_* macro needs to wait for something, it will // return from handle_connection so that other work can take place. When the // event is triggered, uip_callback() will call this function again and the // switch() statement (see below) will take care of resuming execution where // it left off. It *looks* like this function runs from start to finish, but // that's just an illusion to make it easier to code :-) int UIPClient::handle_connection(uip_tcp_appstate_t *s) { // All protosockets must start with this macro. Its internal implementation // is that of a switch() statement, so all code between PSOCK_BEGIN and // PSOCK_END is actually inside a switch block. (This means for example, // that you can't declare variables in the middle of it!) struct psock *p = &s->p; uip_userdata_t *u = (uip_userdata_t *) s->user; PSOCK_BEGIN(p); if (uip_newdata() && readyToReceive(s)) { PSOCK_READBUF_LEN(p, 0); //TODO check what happens when there's more new data incoming than space left in UIPClients buffer (most likely this is just discarded, isn't it?) dataReceived(s); } if (readyToSend(s)) { PSOCK_SEND(p, u->out_buffer, u->out_len); dataSent(s); } if (isClosed(s)) { // Disconnect. PSOCK_CLOSE(p); } // All protosockets must end with this macro. It closes the switch(). PSOCK_END(p); }
bool SpiPollingWriter::write(uint8_t *dataToSend,uint32_t numBytes,uint8_t *dataReceived) { // wait for ready to send while(numBytes--) { while(!readyToSend()) if(_peripheral.hasError()) return false; // send the byte SPI_I2S_SendData(_peripheral,*dataToSend++); if(_duplex) { // in duplex mode and we want data, wait for it to come while(SPI_I2S_GetFlagStatus(_peripheral,SPI_I2S_FLAG_RXNE)==RESET) if(_peripheral.hasError()) return false; // read the byte to clear RXNE and save/discard if(dataReceived!=NULL) *dataReceived++=SPI_I2S_ReceiveData(_peripheral); else SPI_I2S_ReceiveData(_peripheral); } } return true; }
/* Creates an ClientTCPRequest object where TCPSocket is the socket that will be used for data transfer */ ClientTCPRequest::ClientTCPRequest() : socket(new QTcpSocket(this)), data(new QString()), totalBytesSent(0), timer(NULL){ QTimer * timeoutTimer = new QTimer(); timeoutTimer->setInterval(8000); timeoutTimer->setSingleShot(true); timer = timeoutTimer; timer->start(); connect(timer, SIGNAL(timeout()), this, SLOT(connectionTimedOut())); connect(getSocket(), SIGNAL(connected()), this, SLOT(readyToSend())); connect(getSocket(), SIGNAL(bytesWritten(qint64)), this, SLOT(dataSent(qint64))); }
// send byte static void sendRaw(uint8_t byte) { if(length(&sendBuffer) < (SERIALBUFFER - 1)) { // put byte in send buffer, enable sending enque(&sendBuffer, byte); ATOMIC_BLOCK(ATOMIC_FORCEON) { if(sending == 0) { readyToSend(); } } }
/*! This should be called whenever readyToSend() might have become non-zero. It is merely calls QAsyncIO::ready() if readyToSend() is non-zero. */ void QDataSource::maybeReady() { if (readyToSend()) ready(); }