// handle next frame void EZRoboNetDevice::receivedNewFrame(EZFrame* frame) { // copying payload bytes into the packet int i; int startindex = MAX_FRAME_PAYLOAD_LENGTH * FramesReceived; for (i=0; i<frame->PayloadLength; i++) CurrentPacket[startindex+i] = frame->Payload[i]; // frame payload copied // increasing number of received frames FramesReceived++; // sending ackjnowledgement sendAcknowledge(PacketSenderID); // disposing frame disposeFrame(frame); // now changing state if (FramesReceived==TotalFrames) state = stPacketReady; else { state = stReceiving; // marking time for next frame arrival possible timeout FrameReceptionStartTime = millis(); } }
// call this method upon first data reception void EZRoboNetDevice::receivedNewPacket(EZFrame* frame) { // caspturing time of first reception ReceptionStartTime = millis(); // retrieving sender id PacketSenderID = frame->SenderID; // calculating total packet length uint16_t packetlength = frame->Payload[3]+256*frame->Payload[4]+5; CurrentPacketLength = packetlength; // calculating total number of frames required for full packet transmission TotalFrames = packetlength / MAX_FRAME_PAYLOAD_LENGTH + 1; // allocating memory space for the packet being received CurrentPacket = (byte*)malloc(packetlength); // now filling initial space in CurrentPacket int i; for (i=0; i<frame->PayloadLength; i++) CurrentPacket[i] = frame->Payload[i]; // done copying // disposing frame disposeFrame(frame); // increasing number of frames received FramesReceived++; // sending an acknowledgement packet sendAcknowledge(PacketSenderID); if (FramesReceived<TotalFrames) { // need to receive more state = stReceiving; // marrking time of acknowledgement FrameReceptionStartTime = millis(); } else { state = stPacketReady; FramesReceived = 0; TotalFrames = 0; } }
// type number 13 void handler_SendOutput( struct Oblify *oblify ) { DEBUG_PRINT(("handler_SendOutput\n")); char *notification = NULL; char *notificationID = NULL; seperateNotification( oblify->payload , ¬ification , ¬ificationID ); if (oblify->payloadSize > 0 && oblify->flag != 4) { DEBUG_PRINT(("set notificationID %s\n" , notificationID)); oblify->type = Acknowledge; oblify->deviceID = deviceID; oblify->flag = 1 << 2; char *temp = (char *)malloc( sizeof(char) * strlen( notificationID ) + 3 ); if (temp == NULL) { perror( "malloc temp" ); exit( 1 ); } strlcat( temp , "13;" , 4 ); strlcat( temp , notificationID , sizeof(notificationID)); oblify->payload = temp; oblify->payloadSize = (unsigned short)strlen( notificationID ) + 3; sendPacketFromOblify( *oblify , 35813 ); //notifyWithGermanVoiceURL(notification , "oblify" , "state information" , localURL , notificationID); //notifyWithSoundURL( notification , "oblify" , "state information" , localURL , notificationID ); //notifyWithGermanVoice(notification, "oblify", "state information",notificationID); if (strncmp( &lastNotificationID , notificationID , strlen( notificationID )) == 0) { }else { notifyWithBritishVoice( notification , "oblify" , "state information" , notificationID ); lastNotificationID = *notificationID; } //notifyWithSound(notification, "oblify", "state information",notificationID); //notifyWithoutSound(notification, "oblify", "state information",notificationID); //notifyWithSound(notification, "oblify", "state information",notificationID); }else if (oblify->flag & 4) { removeNotification( notificationID ); DEBUG_PRINT(("remove notificationID %s\n" , notificationID)); sendAcknowledge( oblify , notificationID ); //seperateNotification( oblify->payload , ¬ification , ¬ificationID ); }else { notifyWithoutSound( "Device just finished..." , "oblify" , "state information" , "1" ); DEBUG_PRINT(("error sendoutput\n")); } if (notification != NULL) free( notification ); if (notificationID != NULL) free( notificationID ); // sigabort }
// processEvents consults with the state and initiates packet handling // additionally, if a timeout occurs, it re-initiates or terminates transmission // does NOT RESET the flags! Also, initiates a packet transmission void EZRoboNetDevice::processEvents() { if (state == stPacketReady) { // the packet is assembled and ready // increase number of packets received if (ReceivedPacketsNum<2) { ReceivedPacketsNum++; ReceivedPackets[ReceivedPacketsNum-1] = bytes2Packet(CurrentPacket); } else // raise overflow flag PacketQueueOverflow = true; // disposing CurrentPacket free(CurrentPacket); // resetting the RoboNetDevice state = stIdle; PacketReceiverID = 0; TotalFrames = 0; FramesReceived = 0; } else if (state == stWaitingAcknowledge) { // waiting for acknowledge // checking time ellapsed unsigned long currentTime = millis(); unsigned long transmissionElapsed = currentTime - TransmissionStartTime; if (transmissionElapsed > PACKET_SENDING_TIMEOUT) { // transmission timedout // raising error flag Serial.println("Packet Sending Timedout!"); PacketSendTimeout = true; // quiting everything and resetting free(CurrentPacket); PacketSenderID = 0; PacketReceiverID = 0; TotalFrames = 0; FramesSent = 0; FramesReceived = 0; state = stIdle; } else { unsigned long elapsed = currentTime - FrameTransmissionStartTime; if (elapsed > FRAME_ACKNOWLEDGE_TIMEOUT) { // timeout occured Serial.println("Acknowledge timeout!"); // attempting to resend the frame state = stSending; // sending again sendNextFrame(); } } } else if (state == stReceiving) { // receiving a packet unsigned long currentTime = millis(); unsigned long receptionElapsed = currentTime - ReceptionStartTime; if (receptionElapsed > PACKET_SENDING_TIMEOUT) { // packet's timedout // raising error flag PacketReceiveTimeout = true; // disposing packet free(CurrentPacket); // resetting PacketReceiverID = 0; PacketSenderID = 0; TotalFrames = 0; FramesSent = 0; FramesReceived = 0; state = stIdle; } else { // checking time elapsed since last acknowledgement unsigned long elapsed = currentTime - FrameReceptionStartTime; if (elapsed > FRAME_ACKNOWLEDGE_TIMEOUT) { // next frame timedout // sending a new acknowledgement sendAcknowledge(PacketReceiverID); // reseting time FrameReceptionStartTime = millis(); state = stReceiving; } } } else if (state==stIdle) { if (OutboundPacketsNum>0) { // outbound queue is not empty. must initiate transmission // removing a packet from the outbound queue EZPacket* outpacket = OutboundPackets[0]; OutboundPacketsNum--; OutboundPackets[0] = NULL; // shifting the Outbound queue to the left int i; for (i=1; i<=OutboundPacketsNum; i++) { OutboundPackets[i-1] = OutboundPackets[i]; OutboundPackets[i] = NULL; } // outbound queue shifted // Now, sending packet sendPacket(outpacket); } } }
// handling internal state according to input and triggering appropriate actions void EZRoboNetDevice::transitionAction(EZFrame* frame) { switch(state) { case stIdle: // not in process process of receiving or sending switch(frame->Ftype) { case t_Ping: // received a ping frame. will acknowledge to sender... sendAcknowledge(frame->SenderID); disposeFrame(frame); state = stIdle; // state remains idle break; case t_Acknowledge: // acknowledgement frame. should ignore at this state state = stIdle; break; case t_Data: // A Data frame. Must initiate Packet reception PacketSenderID = frame->SenderID; TotalFrames = 0; FramesReceived = 0; // initialized reception globals // now calling to new packet reception method receivedNewPacket(frame); // state should change inside receivedNewPacket... break; } break; case stSending: // in the process of sending a packet. ignore incoming... disposeFrame(frame); // frame bye-bye // normally, flow should never enter this case clause break; case stReceiving: // in the process of receiving frames switch(frame->Ftype) { case t_Ping: // just reply and go back to wait for the next frame in the sequence sendAcknowledge(frame->SenderID); disposeFrame(frame); state = stReceiving; break; case t_Data: // Data frame arrived. See if we can fill the packet some more if (PacketSenderID==frame->SenderID) {// received a frame from the original sender receivedNewFrame(frame); } else { // packet does not originate fron the current sender // disposing inetercepted frame //Serial.println(frame->SenderID, DEC); disposeFrame(frame); state = stReceiving; // still waiting for a new frame } break; case t_Acknowledge: // acknowledgment packet arrived // do nothing. dispose the frame disposeFrame(frame); break; } break; case stWaitingAcknowledge: // expecting a frame reception acknowledgement switch(frame->Ftype) { case t_Ping: // casual ping. replying... sendAcknowledge(frame->SenderID); disposeFrame(frame); // state remains state = stWaitingAcknowledge; break; case t_Data: // data frame received // dispose the frame and wait for acknowledge disposeFrame(frame); state = stWaitingAcknowledge; break; case t_Acknowledge: // received and acknowledge frame if (frame->SenderID==PacketReceiverID) { Serial.println("Got Acknowledge"); // increasing number of sent frames FramesSent++; if (FramesSent==TotalFrames) {// all sent // disposing packet and reseting Serial.println("ALL Frames Sent!"); free(CurrentPacket); CurrentPacket = NULL; PacketReceiverID = 0; PacketSenderID = 0; CurrentPacketLength = 0; state = stIdle; } else { // need to send more frames state = stSending; sendNextFrame(); } } else state = stWaitingAcknowledge; // disposing frame disposeFrame(frame); break; } break; case stPacketReady: // a packet is ready to be handled switch(frame->Ftype) { case t_Ping: // ping frame sendAcknowledge(frame->SenderID); disposeFrame(frame); state = stPacketReady; break; case t_Acknowledge: // acknowledge frame // ignore disposeFrame(frame); state = stPacketReady; break; case t_Data: // a data frame // ignore until packeready state has been served disposeFrame(frame); state = stPacketReady; break; } break; } // end big state switch }
respData_t *receiveChainedFrame(struct file *filp,short rPcb, short rLen) { respData_t *data_rec=NULL; respData_t *header=NULL ; respData_t *respData=NULL; respData_t *apdbuff=NULL; NFC_DBG_MSG(KERN_ALERT "receiveChainedFrame -Enter\n"); // receive a chained frame as long as chaining is indicated in the PCB do { // receive the DATA field of the current frame NFC_DBG_MSG(KERN_ALERT "p61_dev_read - test4 count [0x%x] \n",rLen); data_rec = receiveFrame(filp,rPcb, rLen); // write it into an apduBuffer memory memcpy((apduBuffer+apduBufferidx),data_rec->data,data_rec->len); //update the index to next free slot apduBufferidx += data_rec->len; // send the acknowledge for the current frame udelay(1000); sendAcknowledge(filp); udelay(1000); // receive the header of the next frame header = receiveHeader(filp); rPcb = header->data[0]; rLen = (header->data[1] & 0xFF); }while ((rPcb & PH_SCAL_T1_CHAINING) == PH_SCAL_T1_CHAINING); // receive the DATA field of the last frame respData = receiveFrame(filp,rPcb, rLen); memcpy(apduBuffer+apduBufferidx,respData->data,respData->len); //update the index to next free slot apduBufferidx += respData->len; // return the entire received apdu apdbuff=(respData_t *)kmalloc(sizeof(respData_t),GFP_KERNEL); if(apdbuff == NULL) { NFC_ERR_MSG(KERN_ALERT "receiveChainedFrame 2-KMALLOC FAILED!!!\n"); return NULL; } apdbuff->data= (unsigned char*)kmalloc(apduBufferidx,GFP_KERNEL); if(apdbuff->data == NULL) { NFC_ERR_MSG(KERN_ALERT "receiveChainedFrame 3-KMALLOC FAILED!!!\n"); return NULL; } memcpy(apdbuff->data,apduBuffer,apduBufferidx); apdbuff->len=apduBufferidx; NFC_DBG_MSG(KERN_ALERT "receiveChainedFrame -Exit\n"); return apdbuff; }