APDU * Layer7_Individual::Request_Response (APDU * r) { APDU *a; CArray *c; l4->Send (r->ToPacket ()); pth_event_t t = pth_event (PTH_EVENT_RTIME, pth_time (6, 100)); while (pth_event_status (t) != PTH_STATUS_OCCURRED) { c = l4->Get (t); if (c) { if (c->len () == 0) { delete c; pth_event_free (t, PTH_FREE_THIS); return 0; } a = APDU::fromPacket (*c, this->t); delete c; if (a->isResponse (r)) { pth_event_free (t, PTH_FREE_THIS); return a; } delete a; pth_event_free (t, PTH_FREE_THIS); return 0; } } pth_event_free (t, PTH_FREE_THIS); return 0; }
void EMI1Layer2::Run (pth_sem_t * stop1) { 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, 0)); bool wait_confirm = false; while (pth_event_status (stop) != PTH_STATUS_OCCURRED) { if (!wait_confirm) pth_event_concat (stop, input, NULL); if (wait_confirm) pth_event_concat (stop, timeout, NULL); CArray *c = iface->Get_Packet (stop); pth_event_isolate(input); pth_event_isolate(timeout); if (!wait_confirm && !inqueue.isempty()) { pth_sem_dec (&in_signal); Send(inqueue.get()); if (noqueue) { pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout, pth_time (1, 0)); wait_confirm = true; } } if (wait_confirm && pth_event_status(timeout) == PTH_STATUS_OCCURRED) wait_confirm = false; if (!c) continue; if (c->len () == 1 && (*c)[0] == 0xA0 && (mode & BUSMODE_UP)) { TRACEPRINTF (t, 2, this, "Reopen"); busmode_t old_mode = mode; mode = BUSMODE_DOWN; if (Open ()) mode = old_mode; // restore VMONITOR } if (c->len () == 1 && (*c)[0] == 0xA0 && mode == BUSMODE_MONITOR) { TRACEPRINTF (t, 2, this, "Reopen Busmonitor"); mode = BUSMODE_DOWN; enterBusmonitor (); } if (c->len () && (*c)[0] == 0x4E) wait_confirm = false; if (c->len () && (*c)[0] == 0x49 && (mode & BUSMODE_UP)) { L_Data_PDU *p = EMI_to_L_Data (*c, this); if (p) { delete c; if (p->AddrType == IndividualAddress) p->dest = 0; TRACEPRINTF (t, 2, this, "Recv %s", p->Decode ()()); if (mode == BUSMODE_VMONITOR) { L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU (this); l2->pdu.set (p->ToPacket ()); l3->recv_L_Data (l2); } l3->recv_L_Data (p); continue; } } if (c->len () > 4 && (*c)[0] == 0x49 && mode == BUSMODE_MONITOR) { L_Busmonitor_PDU *p = new L_Busmonitor_PDU (this); p->status = (*c)[1]; p->timestamp = ((*c)[2] << 24) | ((*c)[3] << 16); p->pdu.set (c->array () + 4, c->len () - 4); delete c; TRACEPRINTF (t, 2, this, "Recv %s", p->Decode ()()); l3->recv_L_Data (p); continue; } delete c; } pth_event_free (stop, PTH_FREE_THIS); pth_event_free (input, PTH_FREE_THIS); pth_event_free (timeout, PTH_FREE_THIS); }