// Send a packet void EthPutPacket(ETH *e, void *data, UINT size) { // Validate arguments if (e == NULL || data == NULL || size == 0) { return; } EthPutPackets(e, 1, &data, &size); }
// Stack main thread void NsMainThread(THREAD *thread, void *param) { NATIVE_STACK *a = (NATIVE_STACK *)param; // Validate arguments if (thread == NULL || param == NULL) { return; } while (true) { SOCKSET set; bool err = false; bool flush_tube; LIST *recv_packets; bool state_changed = false; InitSockSet(&set); AddSockSet(&set, a->Sock1); if (a->Halt) { break; } // Pass to the IPC by receiving from the bridge LABEL_RESTART: state_changed = false; flush_tube = false; while (true) { void *data; UINT size; size = EthGetPacket(a->Eth, &data); if (size == INFINITE) { // Device error err = true; break; } else if (size == 0) { // Can not get any more break; } else { // Pass the IPC socket TubeSendEx(a->Sock1->SendTube, data, size, NULL, true); Free(data); flush_tube = true; state_changed = true; } } if (flush_tube) { TubeFlush(a->Sock1->SendTube); } // Pass to the bridge by receiving from IPC recv_packets = NULL; while (true) { TUBEDATA *d = TubeRecvAsync(a->Sock1->RecvTube); if (d == NULL) { break; } if (recv_packets == NULL) { recv_packets = NewListFast(NULL); } Add(recv_packets, d); state_changed = true; } if (recv_packets != NULL) { UINT i; UINT num = LIST_NUM(recv_packets); void **data_array; UINT *size_array; data_array = Malloc(sizeof(void *) * num); size_array = Malloc(sizeof(UINT) * num); for (i = 0;i < num;i++) { TUBEDATA *d = LIST_DATA(recv_packets, i); data_array[i] = d->Data; size_array[i] = d->DataSize; } EthPutPackets(a->Eth, num, data_array, size_array); for (i = 0;i < num;i++) { TUBEDATA *d = LIST_DATA(recv_packets, i); // Because the data buffer has been already released, not to release twice d->Data = NULL; FreeTubeData(d); } Free(data_array); Free(size_array); ReleaseList(recv_packets); } if (IsTubeConnected(a->Sock1->SendTube) == false || IsTubeConnected(a->Sock1->RecvTube) == false) { err = true; } if (err) { // An error has occured Debug("Native Stack: Error !\n"); a->Halt = true; continue; } if (state_changed) { goto LABEL_RESTART; } Select(&set, 1234, a->Cancel, NULL); } Disconnect(a->Sock1); Disconnect(a->Sock2); }