bool CTcpClient::Start(unsigned int IP, unsigned short Port) { m_IP = IP; m_Port = Port; m_Io.set(m_Loop); m_Async.set(m_Loop); m_Io.set<CTcpClient, &CTcpClient::__IoCallback>(this); m_Async.set<CTcpClient, &CTcpClient::__AsyncCallback>(this); m_Async.start(); m_Async.send(); if (!__Connect()) { return false; } CSigHandle::GetInstance(m_Loop); m_Loop.loop(); return true; }
static void __reader( void* threadinst ) { iOThread th = (iOThread)threadinst; iOLocoNet loconet = (iOLocoNet)ThreadOp.getParm( th ); iOLocoNetData data = Data(loconet); TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "ULNI reader started." ); do { byte msg[0x7F]; int msglen = 0; int index = 0; int garbage = 0; byte bucket[32]; byte c = 0; Boolean ok = True; Boolean ignore = False; if( data->serial == NULL ) { if( !__Connect(loconet) ) { ThreadOp.sleep(1000); continue; } } do { if( data->serial != NULL ) { int available = SerialOp.available(data->serial); if( available > 0 ) { ok = SerialOp.read(data->serial, (char*)&c, 1); if(c <= 0x80) { ThreadOp.sleep(10); bucket[garbage] = c; garbage++; } } else if( available == -1 || SerialOp.getRc(data->serial) > 0 ) { /* device error */ iOSerial serial = data->serial; data->serial = NULL; SerialOp.close( serial ); SerialOp.base.del( serial ); TraceOp.trc( "ulni", TRCLEVEL_EXCEPTION, __LINE__, 9999, "device error" ); } else { ThreadOp.sleep(10); } } else { ok = False; } } while (ok && data->run && c <= 0x80 && garbage < 10); if( !data->run || !ok ) { if( data->comm ) { data->comm = False; TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "stateChanged: run=%d ok=%d", data->run, ok ); LocoNetOp.stateChanged(loconet); } ThreadOp.sleep(10); continue; } if( !data->comm ) { data->comm = True; TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "stateChanged: comm=%d", data->comm ); LocoNetOp.stateChanged(loconet); } if( garbage > 0 ) { TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "garbage=%d", garbage ); TraceOp.dump ( "ulni", TRCLEVEL_BYTE, (char*)bucket, garbage ); } msg[0] = c; ignore = False; if( c == 0xE0 || c == 0xC0 ) { /* Uhli exceptions */ TraceOp.trc( "ulni", TRCLEVEL_WARNING, __LINE__, 9999, "undocumented message: start=0x%02X", msg[0] ); ThreadOp.sleep(0); continue; } else { switch (c & 0xf0) { case 0x80: msglen = 2; index = 1; break; case 0xa0: case 0xb0: msglen = 4; index = 1; break; case 0xc0: msglen = 6; index = 1; break; case 0xd0: msglen = 6; index = 1; break; case 0xe0: SerialOp.read(data->serial, (char*)&c, 1); msg[1] = c & 0x7F; index = 2; msglen = (c & 0x7F); break; default: TraceOp.trc( "ulni", TRCLEVEL_WARNING, __LINE__, 9999, "undocumented message: start=0x%02X", msg[0] ); ThreadOp.sleep(10); continue; } } TraceOp.trc( "ulni", TRCLEVEL_BYTE, __LINE__, 9999, "message 0x%02X length=%d", msg[0], msglen ); ok = False; if( msglen > 0 && msglen <= 0x7F && msglen >= index ) { ok = SerialOp.read(data->serial, (char*)&msg[index], msglen - index); } if( ok && msglen > 0 && !ignore ) { Boolean echoCatched = False; data->busy = (msg[0]==0x81) ? True:False; if( !data->subSendEcho ) { data->subSendEcho = MemOp.cmp(data->subSendPacket, msg, data->subSendLen ); echoCatched = data->subSendEcho; } if( msg[0] == OPC_GPOFF || msg[0] == OPC_GPON || (msg[0]!=0x81 && !echoCatched)) { byte* p = allocMem(msglen+1); p[0] = msglen; MemOp.copy( p+1, msg, min(msglen,127)); QueueOp.post( data->subReadQueue, (obj)p, normal); TraceOp.dump ( "ulni", TRCLEVEL_BYTE, (char*)msg, msglen ); } else if( msg[0]==0x81 ) { TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "CS busy" ); } ThreadOp.sleep(0); } else { TraceOp.trc( "ulni", TRCLEVEL_WARNING, __LINE__, 9999, ignore ? "ignoring unknown packet":"could not read rest of packet" ); if( msglen > 0 ) { TraceOp.dump ( "ulni", TRCLEVEL_BYTE, (char*)msg, msglen ); } ThreadOp.sleep(10); } } while( data->run ); TraceOp.trc( "ulni", TRCLEVEL_INFO, __LINE__, 9999, "ULNI reader stopped." ); }
void CTcpClient::__ErrorCallback() { m_pDataHandle->OnDisconnected(m_SocketClient, errno); sleep(1); __Connect(); }
void CTcpClient::__IoCallback(ev::io &watcher, int revents) { if (EV_ERROR & revents) { __ErrorCallback(); return; } if (revents & EV_READ) { char szBuffer[4096]; ssize_t nRead = recv(watcher.fd, szBuffer, sizeof(szBuffer), 0); if (nRead == 0) { m_pDataHandle->OnDisconnected(m_SocketClient, 0); sleep(1); __Connect(); return; } else if (nRead < 0) { if (errno == EAGAIN) { // ignore } else { m_pDataHandle->OnRecvError(m_SocketClient, errno); sleep(1); __Connect(); return; } } else { m_pDataHandle->OnDataReceived(m_SocketClient, szBuffer, nRead); } } if (revents & EV_WRITE) { if (m_WriteQueue.empty()) { m_Io.set(ev::READ); return; } COutputBuffer::Pointer pBuffer = m_WriteQueue.front(); ssize_t nWritten = write(watcher.fd, pBuffer->GetDataPos(), pBuffer->GetBytes()); if (nWritten < 0) { if (errno == EAGAIN) { // ignore return; } else { m_pDataHandle->OnSendError(m_SocketClient, errno); sleep(1); __Connect(); return; } } pBuffer->m_nPos += nWritten; if (pBuffer->GetBytes() == 0) { m_WriteQueue.pop(); } if (m_WriteQueue.empty()) { m_Io.set(ev::READ); } } }