/*----------------------------------------------------------------------------* * NAME * uartTxDataCallback * * DESCRIPTION * This is an internal callback function (of type uart_data_out_fn) that * will be called by the UART driver when data transmission over the UART * is finished. See DebugInit in the Firmware Library documentation for * details. * * RETURNS * Nothing *----------------------------------------------------------------------------*/ static void uartTxDataCallback(void) { /* This has been added so that the UART port is open for sending the data */ /* One may add another queue to handle the Tx Data separately */ /* Send any pending data waiting to be sent */ sendPendingData(); }
/*----------------------------------------------------------------------------* * NAME * SendDataToUart * * DESCRIPTION * Sends the received data over UART. * * RETURNS * Nothing * *----------------------------------------------------------------------------*/ extern void SendDataToUart(uint8 *data, uint16 size) { /* We initially attempt to directly write to the UART and from there on * we send the data using callback mechanism, whenever the UART is ready * to accept more incoming data. This is to avoid data loss. The data is * buffered and sent to UART using callback mechanism. */ if(!g_trigger_write_callback) { UartWrite(data, size); g_trigger_write_callback = TRUE; return; } /* Queue the incoming data to the queue. will be written when UART is ready */ if(g_trigger_write_callback) { /* First copy all the bytes received into the byte queue */ BQSafeQueueBytes((const uint8 *)data, size,RECV_QUEUE_ID); /*Send Pending Data */ sendPendingData(); } }
void SocketThread::run() { { queryTime.restart(); if(isLogEnabled)logThread->writeLog("SocketThread Started"); sslSocket=new QSslSocket; connect(this,SIGNAL(sendToApiSignal(QByteArray, QByteArray)),this,SLOT(sendToApiSlot(QByteArray, QByteArray))); connect(this,SIGNAL(reconnectApiSignal()),this,SLOT(reconnectApiSlot())); connect(sslSocket,SIGNAL(readyRead()),SLOT(readSocket())); secondTimer=new QTimer; connect(secondTimer,SIGNAL(timeout()),this,SLOT(secondSlot())); if(useSSL)sslSocket->connectToHostEncrypted(hostName, 443); else sslSocket->connectToHost(hostName, 80); sslSocket->waitForConnected(); if(isLogEnabled) { logThread->writeLog("SSL Socket state:"+sslSocket->errorString().toAscii()+". Supported: "+QByteArray::number(sslSocket->supportsSsl())); } secondTimer->start(100); sendPendingData(); } exec(); }
void Gosu::CommSocket::update() { sendPendingData(); if (!connected()) return; for (;;) { char buffer[1024]; int received = ::recv(pimpl->socket.handle(), buffer, sizeof buffer, 0); if (received > 0 && received <= static_cast<int>(sizeof buffer)) { // Data arrived and fit into the buffer. pimpl->appendBuffer(buffer, received, onReceive); } else if (received == 0) { // The other side has gracefully closed the connection. disconnect(); return; } else if (received == SOCKET_ERROR) { switch (lastSocketError()) { // Arriving data didn't fit into the buffer. case GOSU_SOCK_ERR(EMSGSIZE): pimpl->appendBuffer(buffer, sizeof buffer, onReceive); break; // There simply was no data. case GOSU_SOCK_ERR(EWOULDBLOCK): return; // Connection was reset or is invalid. case GOSU_SOCK_ERR(ENETDOWN): case GOSU_SOCK_ERR(ENOTCONN): case GOSU_SOCK_ERR(ENETRESET): case GOSU_SOCK_ERR(ECONNABORTED): case GOSU_SOCK_ERR(ETIMEDOUT): case GOSU_SOCK_ERR(ECONNRESET): #ifndef GOSU_IS_WIN // UNIX specific, rare error case GOSU_SOCK_ERR(EPIPE): #endif disconnect(); return; // Everything else is unexpected. default: throwLastSocketError(); } } else assert(false); } }
void SocketStreamHandle::writeReady() { // We no longer have buffered data, so stop waiting for the socket to be writable. if (!bufferedAmount()) { stopWaitingForSocketWritability(); return; } sendPendingData(); }
void SocketStreamHandle::writeStreamCallback(CFStreamEventType type) { switch(type) { case kCFStreamEventNone: break; case kCFStreamEventOpenCompleted: break; case kCFStreamEventHasBytesAvailable: ASSERT_NOT_REACHED(); break; case kCFStreamEventCanAcceptBytes: { // Possibly, a spurious event from CONNECT handshake. if (!CFWriteStreamCanAcceptBytes(m_writeStream.get())) return; if (m_connectingSubstate == WaitingForCredentials) break; if (m_connectingSubstate == WaitingForConnect) { m_connectingSubstate = Connected; m_state = Open; RefPtr<SocketStreamHandle> protect(this); // The client can close the handle, potentially removing the last reference. m_client->didOpen(this); break; } ASSERT(m_state == Open); ASSERT(m_connectingSubstate == Connected); sendPendingData(); break; } case kCFStreamEventErrorOccurred: { #ifndef BUILDING_ON_TIGER RetainPtr<CFErrorRef> error(AdoptCF, CFWriteStreamCopyError(m_writeStream.get())); reportErrorToClient(error.get()); #else CFStreamError error = CFWriteStreamGetError(m_writeStream.get()); m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error. #endif break; } case kCFStreamEventEndEncountered: // FIXME: Currently, we handle closing in read callback, but these can come independently (e.g. a server can stop listening, but keep sending data). break; } }
void SocketThread::readSocket() { QByteArray currentAllData=sslSocket->readAll(); while(currentAllData.size()) { QByteArray currentData; int lrlnlrln=currentAllData.indexOf("\r\n\r\n"); if(lrlnlrln>-1){currentData=currentAllData.left(lrlnlrln-1);currentAllData.remove(0,lrlnlrln+4);} else {currentData=currentAllData;currentAllData.clear();} if(currentData.size()<2)continue; if(currentData.startsWith("HTTP")) { if(currentData.startsWith("HTTP/1.1 50")&&!currentData.startsWith("HTTP/1.1 500")){emit apiDown();waitingNewData=false;return;} if(waitingNewData) { checkDataAndSend(&dataBuffer); if(isLogEnabled&&dataBuffer.size())logThread->writeLog("Ignored Corrupt Data: "+dataBuffer); dataBuffer.clear(); waitingNewData=false; } continue; } if(currentData.right(2)=="\r\n")currentData.remove(currentData.size()-2,2); int firstlRlN=currentData.indexOf("\r\n"); if(firstlRlN>-1&¤tData.size()>=firstlRlN+2)currentData.remove(0,firstlRlN+2); checkDataAndSend(¤tData); if(!currentData.isEmpty()) { dataBuffer.append(currentData); waitingNewData=true; checkDataAndSend(&dataBuffer); if(dataBuffer.isEmpty()) { waitingNewData=false; sendPendingData(); } } } }
void SocketStreamHandle::writeStreamCallback(CFStreamEventType type) { switch(type) { case kCFStreamEventNone: break; case kCFStreamEventOpenCompleted: break; case kCFStreamEventHasBytesAvailable: ASSERT_NOT_REACHED(); break; case kCFStreamEventCanAcceptBytes: { // Possibly, a spurious event from CONNECT handshake. if (!CFWriteStreamCanAcceptBytes(m_writeStream.get())) return; if (m_connectingSubstate == WaitingForCredentials) break; if (m_connectingSubstate == WaitingForConnect) { m_connectingSubstate = Connected; m_state = Open; m_client->didOpenSocketStream(this); break; } ASSERT(m_state == Open); ASSERT(m_connectingSubstate == Connected); sendPendingData(); break; } case kCFStreamEventErrorOccurred: { RetainPtr<CFErrorRef> error(AdoptCF, CFWriteStreamCopyError(m_writeStream.get())); reportErrorToClient(error.get()); break; } case kCFStreamEventEndEncountered: // FIXME: Currently, we handle closing in read callback, but these can come independently (e.g. a server can stop listening, but keep sending data). break; } }
// private methods void SocketStreamHandle::processMessageOnMainThread(StreamMessage msg) { switch (msg) { case DidOpen: ASSERT(m_state == Open); if (m_client) m_client->didOpenSocketStream(this); break; case DidFail: ASSERT(m_curl_code != CURLE_OK); LOG_CONNECT(Network, "SocketStreamHandleCurl: DidFail, error %d (%s), curl error buffer: %s [%p][thread=%d]\n", m_curl_code, curl_easy_strerror(m_curl_code), m_curl_error_buffer, this, GetCurrentThreadId()); if (m_client) m_client->didFailSocketStream(this, SocketStreamError(m_curl_code, m_url.isEmpty() ? String() : m_url.string())); break; case DidReceiveData: didReceiveData(); break; case DidSelectForWrite: { deref(); // this balances the ref() when spinning up the send wait thread. // LOG(Network, "SocketStreamHandleCurl: DidSelectForWrite [%p][thread=%d]\n", this, GetCurrentThreadId()); if (!m_platformCloseRequested) { if (m_curl_code == CURLE_OK) { sendPendingData(); } else if (m_client) { m_client->didFailSocketStream(this, SocketStreamError(m_curl_code, m_url.isEmpty() ? String() : m_url.string())); } } } break; case DidClose: disconnect(); break; case DidStopRecvLoop: deref(); // this balances the ref() in the constructor. break; } deref(); }
void SocketStreamHandleServer::progressTimerFired() { switch (m_progressState) { case EError: if (m_client) m_client->didFailSocketStream(reinterpret_cast<SocketStreamHandle*>(this), SocketStreamError(-1)); break; case EConnectingDest: break; #if 0 case EConnectingProxy: { char buf[1024] = {0}; fd_set rd; FD_ZERO(&rd); FD_SET(m_socket, &rd); struct timeval tv = {0}; if (wkcNetSelectPeer(m_socket+1, &rd, NULL, NULL, &tv)==0) { m_progressTimer.startOneShot(0.1); break; } int len = wkcNetRecvPeer(m_socket, buf, sizeof(buf), 0); if (len<=0) { m_progressTimer.startOneShot(0.1); break; } String result(buf); if (result.find("Connection Established", 0, false)) { m_progressState = EConnected; m_progressTimer.startOneShot(0.1); } else { m_progressState = EError; m_progressTimer.startOneShot(0.1); } break; } #endif case EConnected: m_state = Open; m_progressState = EReady; if (m_client) m_client->didOpenSocketStream(reinterpret_cast<SocketStreamHandle*>(this)); m_progressTimer.startOneShot(0.1); break; case EReady: { char buf[1024] = {0}; do { fd_set rd, wd; FD_ZERO(&rd); FD_ZERO(&wd); FD_SET(m_socket, &rd); FD_SET(m_socket, &wd); struct timeval tv = {0}; int ret = wkcNetSelectPeer(m_socket+1, &rd, &wd, NULL, &tv); if (ret == 0 || (!FD_ISSET(m_socket, &rd) && !bufferedAmount())) break; if (FD_ISSET(m_socket, &rd)) { int len = wkcNetRecvPeer(m_socket, buf, sizeof(buf), 0); if (len<=0) break; if (m_client) m_client->didReceiveSocketStreamData(reinterpret_cast<SocketStreamHandle*>(this), buf, len); } if (bufferedAmount()) { if (FD_ISSET(m_socket, &wd)) { if (!sendPendingData()) { m_progressState = EError; break; } } } } while (1); m_progressTimer.startOneShot(0.1); break; } case ERequestClose: if (m_client) m_client->didCloseSocketStream(reinterpret_cast<SocketStreamHandle*>(this)); m_state = Closed; break; default: break; } }
void SocketThread::secondSlot() { checkSocketConnected(); if(queryTime.elapsed()>800)sendPendingData(); }
void SocketStreamHandle::notifyReadyToSendData() { sendPendingData(); }