void Shell::recvGet( const Eref& e, const Qinfo* q, PrepackedBuffer pb ) { if ( myNode_ == 0 ) { if ( gettingVector_ ) { ObjId tgt = q->src(); // unsigned int linearIndex = q->src().eref().index().value(); unsigned int linearIndex = tgt.element()->dataHandler()->linearIndex( tgt.dataId ); if ( linearIndex >= getBuf_.size() ) { if ( linearIndex >= getBuf_.capacity() ) getBuf_.reserve( linearIndex * 2 ); getBuf_.resize( linearIndex + 1 ); } assert ( linearIndex < getBuf_.size() ); double*& c = getBuf_[ linearIndex ]; c = new double[ pb.dataSize() ]; memcpy( c, pb.data(), pb.dataSize() * sizeof( double ) ); // cout << myNode_ << ":" << q->threadNum() << ": Shell::recvGet[" << linearIndex << "]= (" << pb.dataSize() << ", " << *c << ")\n"; } else { assert ( getBuf_.size() == 1 ); double*& c = getBuf_[ 0 ]; c = new double[ pb.dataSize() ]; memcpy( c, pb.data(), pb.dataSize() * sizeof( double ) ); handleAck( 0, OkStatus ); } ++numGetVecReturns_; } }
/*! * \fn void *waitForACK() * \brief Read a ACK message from USB */ void *waitForACK() { uint8_t ack[10] = {0}; while (1) { if (select(fd + 1, &set, NULL, NULL, &timeout) > 0) { read(fd, &ack[0], SIZE_ACK); handleAck(ack); } } return NULL; }
/** * add received packet to receive queue */ boolean Layer3::receive( void* payload ) { packet_t* packet = (packet_t*) payload; #ifdef DEBUG_NETWORK_ENABLE Serial.print(millis()); Serial.println(F(": L3::rcv")); printPacketInformation(packet); #endif //is this a beacon? if(packet->data.type == PACKET_BEACON) { return handleBeacon(packet); } //update the neighbour - this is no beacon. neighbourMgr.updateNeighbour(packet->data.source, packet->data.source, 0); //do we have to route the packet? - no broadcast routing. if(packet->data.destination != localAddress && packet->data.destination != CONFIG_L3_ADDRESS_BROADCAST) { return routePacket(packet); } //is this an ack? (it is for us!) if(packet->data.destination == localAddress && packet->data.type == PACKET_ACK) { return handleAck(packet); } //nope, store it here. boolean success = receiveQueuePush(packet); //is this a numbered packet? - send ACK if required. if(packet->data.type == PACKET_NUMBERED && packet->data.source != localAddress) { success &= sendAck(packet); } if(!success) { return false; } return true; }
static void *getBundles(void *parm) { RxThreadParms *parms = (RxThreadParms *) parm; char ownEid[64]; Sdr sdr = getIonsdr(); BpDelivery dlv; uvast profNum; Scalar seqNum; char type; unsigned int aduLength; int bytesRemaining; ZcoReader reader; unsigned char *buffer; int bytesToRead; int sdnvLength; unsigned char *cursor; isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%d", getOwnNodeNbr(), DTPC_RECV_SVC_NBR); if (bp_open(ownEid, &(parms->rxSap)) < 0) { putErrmsg("DTPC can't open own 'recv' endpoint.", ownEid); parms->running = 0; return NULL; } writeMemo("[i] dtpcd receiver thread has started."); while (parms->running) { if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0) { putErrmsg("dtpcd bundle reception failed.", NULL); parms->running = 0; continue; } switch (dlv.result) { case BpEndpointStopped: parms->running = 0; break; case BpPayloadPresent: CHKNULL(sdr_begin_xn(sdr)); /* Since the max length of a Sdnv is 10 bytes, * read 21 bytes to be sure that the Profile * and Sequence number Sdnvs plus the type * were read. */ aduLength = zco_source_data_length(sdr, dlv.adu); bytesRemaining = aduLength; if (aduLength < 21) /* Just in case we receive * a very small adu. */ { bytesToRead = aduLength; } else { bytesToRead = 21; } buffer = MTAKE(bytesToRead); if (buffer == NULL) { putErrmsg("Out of memory.",NULL); return NULL; } cursor = buffer; zco_start_receiving(dlv.adu, &reader); if (zco_receive_headers(sdr, &reader, bytesToRead, (char *) buffer) < 0) { putErrmsg("dtpcd can't receive ADU header.", itoa(bytesToRead)); sdr_cancel_xn(sdr); MRELEASE(buffer); parms->running = 0; continue; } type = *cursor; /* Get the type byte. */ cursor++; bytesRemaining--; sdnvLength = decodeSdnv(&profNum, cursor); cursor += sdnvLength; bytesRemaining -= sdnvLength; sdnvLength = sdnvToScalar(&seqNum, cursor); cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Mark remaining bytes as source data. */ zco_delimit_source(sdr, dlv.adu, cursor - buffer, bytesRemaining); zco_strip(sdr, dlv.adu); MRELEASE(buffer); if (sdr_end_xn(sdr) < 0) { putErrmsg("dtpcd can't handle bundle delivery.", NULL); parms->running = 0; continue; } switch (type) { case 0x00: /* Received an adu. */ switch (handleInAdu(sdr, &dlv, profNum, seqNum)) { case -1: putErrmsg("dtpcd can't handle inbound \ adu.", NULL); parms->running = 0; continue; case 1: if (parseInAdus(sdr) < 0) { putErrmsg("dtpcd can't parse \ inbound adus.", NULL); parms->running = 0; continue; } case 0: /* Intentional fall-through to * next case. */ default: if (dlv.ackRequested) { if (sendAck(parms->txSap, profNum, seqNum, &dlv) < 0) { putErrmsg("dtpcd can't \ send ack.", NULL); parms->running = 0; continue; } } break; } break; case 0x01: /* Received an ACK. */ if (handleAck(sdr, &dlv, profNum, seqNum) < 0) { putErrmsg("dtpcd can't handle ACK.", NULL); parms->running = 0; continue; } break; default: writeMemo("[?] Invalid item type. Corrupted \ item?"); break; } default: break; }