// 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;
  }
       
}
Exemple #3
0
// type number 13
void handler_SendOutput( struct Oblify *oblify )
{
	DEBUG_PRINT(("handler_SendOutput\n"));
	char *notification = NULL;
	char *notificationID = NULL;
	seperateNotification( oblify->payload , &notification , &notificationID );


	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 , &notification , &notificationID );
	}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;
}