/*! * \brief close connection with eibnetmux socket server * * \param conn connection handle as returned by enmx_open() */ void enmx_close( ENMX_HANDLE conn ) { sConnectionInfo **connInfo, *temp; SOCKET_CMD_HEAD cmd_head; pth_event_t ev_wakeup; time_t secs; temp = NULL; for( connInfo = &enmx_connections; *connInfo != NULL; connInfo = &(*connInfo)->next ) { if( (*connInfo)->socket == conn ) { temp = *connInfo; *connInfo = (*connInfo)->next; break; } } if( temp != NULL ) { cmd_head.cmd = SOCKET_CMD_EXIT; cmd_head.address = 0xffff; secs = time( NULL ) + TIMEOUT; switch( temp->mode ) { case ENMX_MODE_STANDARD: while( write( conn, &cmd_head, sizeof( cmd_head )) == -1 ) { if( errno == EAGAIN ) { if( secs <= time( NULL )) { break; } usleep( 10 * 1000 ); continue; } } break; case ENMX_MODE_PTH: ev_wakeup = pth_event( PTH_EVENT_TIME, pth_time( secs, 0 )); pth_write_ev( conn, &cmd_head, sizeof( cmd_head ), ev_wakeup ); // either the request has been sent or timeout reached // in any case, we've finished pth_event_free( ev_wakeup, PTH_FREE_ALL ); break; } if( temp->hostname ) free( temp->hostname ); if( temp->name ) free( temp->name ); free( temp ); } close( conn ); }
void TPUARTLayer2Driver::Run (pth_sem_t * stop1) { struct message m; int l; pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1); pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal); while (pth_event_status (stop) != PTH_STATUS_OCCURRED) { pth_event_concat (stop, input, NULL); l = pth_read_ev (fd, &m, sizeof (m), stop); if (l >= 0) { LPDU *l1; if (m.length > sizeof (m.data)) m.length = sizeof (m.data); t->TracePacket (0, this, "Recv", m.length, m.data); if (vmode && mode == 0) { L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU; l2->pdu.set (m.data, m.length); outqueue.put (l2); pth_sem_inc (&out_signal, 1); } if (mode == 0) l1 = LPDU::fromPacket (CArray (m.data, m.length)); else { l1 = new L_Busmonitor_PDU; ((L_Busmonitor_PDU *) l1)->pdu.set (m.data, m.length); } outqueue.put (l1); pth_sem_inc (&out_signal, 1); } pth_event_isolate (stop); if (!inqueue.isempty ()) { LPDU *l1 = inqueue.top (); CArray c = l1->ToPacket (); unsigned len = c (); if (len > sizeof (m.data)) len = sizeof (m.data); memcpy (m.data, c.array (), len); m.length = len; if (ver) m.length--; t->TracePacket (0, this, "Send", m.length, m.data); l = pth_write_ev (fd, &m, sizeof (m), stop); if (l >= 0) { if (vmode) { L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU; l2->pdu.set (c); outqueue.put (l2); pth_sem_inc (&out_signal, 1); } pth_sem_dec (&in_signal); delete inqueue.get (); } } } pth_event_free (stop, PTH_FREE_THIS); pth_event_free (input, PTH_FREE_THIS); }
void FT12LowLevelDriver::Run (pth_sem_t * stop1) { CArray last; int i; uchar buf[255]; pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1); pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal); pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (0, 100000)); while (pth_event_status (stop) != PTH_STATUS_OCCURRED) { pth_event_isolate (input); pth_event_isolate (timeout); if (mode == 0) pth_event_concat (stop, input, NULL); if (mode == 1) pth_event_concat (stop, timeout, NULL); i = pth_read_ev (fd, buf, sizeof (buf), stop); if (i > 0) { t->TracePacket (0, this, "Recv", i, buf); akt.setpart (buf, akt (), i); } while (akt.len () > 0) { if (akt[0] == 0xE5 && mode == 1) { pth_sem_dec (&in_signal); inqueue.get (); if (inqueue.isempty ()) pth_sem_set_value (&send_empty, 1); akt.deletepart (0, 1); mode = 0; repeatcount = 0; } else if (akt[0] == 0x10) { if (akt () < 4) break; if (akt[1] == akt[2] && akt[3] == 0x16) { uchar c1 = 0xE5; t->TracePacket (0, this, "Send Ack", 1, &c1); write (fd, &c1, 1); if ((akt[1] == 0xF3 && !recvflag) || (akt[1] == 0xD3 && recvflag)) { //right sequence number recvflag = !recvflag; } if ((akt[1] & 0x0f) == 0) { const uchar reset[1] = { 0xA0 }; CArray *c = new CArray (reset, sizeof (reset)); t->TracePacket (0, this, "RecvReset", *c); outqueue.put (c); pth_sem_inc (&out_signal, TRUE); } } akt.deletepart (0, 4); } else if (akt[0] == 0x68) { int len; uchar c1; if (akt () < 7) break; if (akt[1] != akt[2] || akt[3] != 0x68) { //receive error, try to resume akt.deletepart (0, 1); continue; } if (akt () < akt[1] + 6) break; c1 = 0; for (i = 4; i < akt[1] + 4; i++) c1 += akt[i]; if (akt[akt[1] + 4] != c1 || akt[akt[1] + 5] != 0x16) { len = akt[1] + 6; //Forget wrong short frame akt.deletepart (0, len); continue; } c1 = 0xE5; t->TracePacket (0, this, "Send Ack", 1, &c1); i = write (fd, &c1, 1); if ((akt[4] == 0xF3 && recvflag) || (akt[4] == 0xD3 && !recvflag)) { if (CArray (akt.array () + 5, akt[1] - 1) != last) { TRACEPRINTF (t, 0, this, "Sequence jump"); recvflag = !recvflag; } else TRACEPRINTF (t, 0, this, "Wrong Sequence"); } if ((akt[4] == 0xF3 && !recvflag) || (akt[4] == 0xD3 && recvflag)) { recvflag = !recvflag; CArray *c = new CArray; len = akt[1] + 6; c->setpart (akt.array () + 5, 0, len - 7); last = *c; outqueue.put (c); pth_sem_inc (&out_signal, TRUE); } akt.deletepart (0, len); } else //Forget unknown byte akt.deletepart (0, 1); } if (mode == 1 && pth_event_status (timeout) == PTH_STATUS_OCCURRED) mode = 0; if (mode == 0 && !inqueue.isempty ()) { const CArray & c = inqueue.top (); t->TracePacket (0, this, "Send", c); repeatcount++; i = pth_write_ev (fd, c.array (), c (), stop); if (i == c ()) { mode = 1; timeout = pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout, pth_time (0, 100000)); } } } pth_event_free (stop, PTH_FREE_THIS); pth_event_free (timeout, PTH_FREE_THIS); pth_event_free (input, PTH_FREE_THIS); }