#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include  "ipos.h"
#include  "rfmdef.h"
#include   "rfmstruct.h"
#include   "mesgparser.h"

#define   ACTIVATION_STATUS   0x20
#define   FIRMWARE_VERSION    0x40
#define   ABORT_CAUSE         0x80


//#define  TEST

int encodeMsgHeader(iposrfm_msg_hdr msgHdr, U8 **msg) ;
int decodeMsgHeader(U8 *msg, iposrfm_msg_hdr *msgHdr) ;

int encodeCtrlHeader(iposrfm_ctrl_hdr ctrlHdr, U8 **msg) ;
int decodeCtrlHeader(U8 *msg, iposrfm_ctrl_hdr *ctrlHdr) ;

int encodeFirmwareVersion(iposrfm_firmware_ver fw_ver, U8 **msg) ;
int decodeFirmwareVersion(U8 **msg, iposrfm_firmware_ver *fw_ver) ;

int encodeVersionInfo(iposrfm_ver_info verInfo, U8 **msg) ;
int decodeVersionInfo(U8 **msg, iposrfm_ver_info *verInfo) ;

int encodeActivationInfo(iposrfm_activation_info actInfo, U8 **msg) ;
int decodeActivationInfo(U8 *msg, iposrfm_activation_info *actInfo) ;

int encodeTransferInfo(iposrfm_transfer_info transferInfo, U8 **msg) ;
int decodeTransferInfo(U8 *msg, iposrfm_transfer_info *transferInfo) ;

int encodeFileSaveInfo(iposrfm_file_save_info filesaveInfo, U8 **msg) ;
int decodeFileSaveInfo(U8 **msg, iposrfm_file_save_info *actInfo) ;

int encodeFileInfo(iposrfm_file_info fileInfo, U8 **msg) ;
int decodeFileInfo(U8 *msg, iposrfm_file_info *fileInfo) ;



/**
 **  Function to get number of set bits in a byte.
 **
 **  Arguments :
 **      inpbyte   : INPUT
 **                  Input byte.
 **  Return value :
 **      num  : number of set bits in a byte.
 **
 **/


int num_of_info_elements(U8 inpbyte) 
{
  int num = 0 ;
  int i ;

  for (i=0; i<8;i++) {
    if (inpbyte & 1)
      num++ ;
  inpbyte = inpbyte >> 1 ;
  } /* for */

/*  printf("number of 1s : %d\n", num) ; */

  return num ;
} /* num_of_info_elements() */


/** 
 **    Encoding Message Header
 ** 
 **   This function 
 **      -> gets the structure containing message header
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_msg_hdr
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/


int encodeMsgHeader(iposrfm_msg_hdr msgHdr, U8 **msg)
{
   
  int size = 0 ;

  /* Mesg header - Protocol Type */
  **msg = msgHdr.pt ;
  *msg += 1 ;
  size++ ;

  /* Mesg header - Message Type */
  **msg = msgHdr.msgType ;
  *msg += 1 ;
  size++ ;
    
  /* Mesg header - Length */
  **msg = msgHdr.length ;
  *msg += 1 ;
  size++ ;

  return size ;
} /* encodeMsgHeader() */


/** 
 **    Decoding Message Header
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into message 
 **         header structure.
 **      -> returns number of bytes decoded.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       msgHdr      : OUTPUT
 **                     TYPE : iposrfm_msg_hdr
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 **
 **
 **/


int decodeMsgHeader(U8 *msg, iposrfm_msg_hdr *msgHdr)
{
  int size = 0 ;
  
  /* msg header - protocol type */
  msgHdr->pt = *msg ;
  msg++ ;
  size++ ;

  /* msg header - message type */
  msgHdr->msgType = *msg ;
  msg++ ;
  size++ ;

  /* msg header - length of the message */
  msgHdr->length = *msg ;
  msg++ ;
  size++ ;

  return size ;

} /* decodeMsgHeader() */


/** 
 **    Encoding Control Header
 ** 
 **   This function 
 **      -> gets the structure containing control header
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_ctrl_hdr
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/


int encodeCtrlHeader(iposrfm_ctrl_hdr ctrlHdr, U8 **msg)
{
  
  int size = 0 ;

  /* Mesg header - Protocol Type */
  **msg = ctrlHdr.genericHdr.pt ;
  *msg += 1 ;
  size++ ;

  /* Mesg header - Message Type */
  **msg = ctrlHdr.genericHdr.msgType ;
  *msg += 1 ;
  size++ ;
    
  /* Mesg header - Length */
  **msg = ctrlHdr.genericHdr.length ;
  *msg += 1 ;
  size++ ;

  /* User Id */
  **msg = ctrlHdr.uid ;
  *msg += 1 ;
  size++ ;

  /* Ack */
  **msg = ctrlHdr.ack ;
  *msg += 1 ;
  size++ ;

  return size ;
} /* encodeCtrlHeader() */


/** 
 **    Decoding Control Header
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into control
 **         header structure.
 **      -> returns number of bytes decoded.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       msgHdr      : OUTPUT
 **                     TYPE : iposrfm_ctrl_hdr
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 **
 **
 **/

int decodeCtrlHeader(U8 *msg, iposrfm_ctrl_hdr *ctrlHdr)
{
  int size = 0 ;
  
  /* msg header - protocol type */
  ctrlHdr->genericHdr.pt = *msg ;
  msg++ ;
  size++ ;

  /* msg header - message type */
  ctrlHdr->genericHdr.msgType = *msg ;
  msg++ ;
  size++ ;

  /* msg header - length of the message */
  ctrlHdr->genericHdr.length = *msg ;
  msg++ ;
  size++ ;

  /* User Id */
  ctrlHdr->uid = *msg ;
  msg++ ;
  size++ ;

  /* Ack */
  ctrlHdr->ack = *msg ;
  msg++ ;
  size++ ;

  return size ;

} /* decodeCtrlHeader() */



/** 
 **    Encoding Firmware Version structure.
 **      typedef  struct
 **      {
 ** 
 **       U16    verId;       version ID
 **       U8    lenStr;       version string length
 **         U8    verStr[MAX_VER_STRING];
 **
 **      }  iposrfm_firmware_ver;
 ** 
 **   This function 
 **      -> gets iposrfm_firmware_ver structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_firmware_ver
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/

int encodeFirmwareVersion(iposrfm_firmware_ver fw_ver, U8 **msg)
{
  int size=0 ;

  /* Version ID */
  **msg = (fw_ver.verId & 0xFF00)>>8 ;  //MSB
  *msg += 1 ;

  **msg = fw_ver.verId & 0xFF ;    //LSB
  *msg += 1 ;
  size += 2 ;

  /* version string length */
  **msg = fw_ver.lenStr ;
  *msg += 1 ;
  size++ ;

  /* Version String */
  memcpy(*msg,fw_ver.verStr,fw_ver.lenStr) ;
  *msg += fw_ver.lenStr ;
  size += fw_ver.lenStr ;

  return size ;

} /* encodeFirmwareVersion() */


/** 
 **    Decoding Firmware Version structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         firmware version structure.
 **      -> returns the version Id that is decoded.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_firmware_ver
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 **
 **
 **/


int decodeFirmwareVersion(U8 **msg, iposrfm_firmware_ver *fw_ver)
{
   int size = 0 ;

   /* Version ID */
   fw_ver->verId = (U16) (**msg << 8) | (U16) (*(*msg+1) & 0xFF)  ;
   *msg += 2 ;
   size += 2 ;

   /* version string length */
   fw_ver->lenStr = **msg ;
   *msg += 1 ;
   size++ ;

   /* Version String */
   memcpy(fw_ver->verStr, *msg, fw_ver->lenStr) ; 
   *msg += fw_ver->lenStr ;
   size += fw_ver->lenStr ;

   return size ;
} /* decodeFirmwareVersion() */


/** 
 **    Encoding Version Info structure.
 **      typedef  struct
 **      {
 **       U8  numFirmware;        number of firmware versions in the CPE
 **         U8  activeVer;             the indentifier for the active version
 **         iposrfm_firmware_ver version[MAX_CPE_VERS]; all versions in CPE
 **
 **       }   iposrfm_ver_info;
 ** 
 **   This function 
 **      -> gets iposrfm_ver_info structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer (encoded)
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_ver_info
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/

int encodeVersionInfo(iposrfm_ver_info verInfo, U8 **msg)
{
  int size = 0 ;
  int i ;
  int ret_val ;

  **msg = verInfo.numFirmware ;
  *msg  += 1 ;
  size++ ;

  **msg = verInfo.activeVer ;
  *msg += 1 ;
  size++ ;

  for (i=0; i<verInfo.numFirmware; i++) {
    ret_val = encodeFirmwareVersion(verInfo.version[i],msg) ;
  size += ret_val ;
  } /* for */

  return size ;
} /* encodeVersionInfo() */



/** 
 **    Decoding Version Info structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         version info structure.
 **      -> returns the number of versions in CPE.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_ver_info
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 **
 **
 **/

int decodeVersionInfo(U8 **msg, iposrfm_ver_info *verInfo)
{
  int i ;
  int size = 0 ;
     
  /* number of firmware versions in the CPE */
  verInfo->numFirmware = **msg ;
  *msg += 1 ;
  size++ ;

  /* the indentifier for the active version */
  verInfo->activeVer = **msg ;
  *msg += 1 ;
  size++ ;

  for (i=0; i<verInfo->numFirmware; i++) {
    size += decodeFirmwareVersion(msg, &verInfo->version[i]) ;
  } /* for */

  return size ;
} /* decodeVersionInfo() */


/** 
 **    Encoding Activation Info structure.
 **      typedef  struct
 **      {
 **        U8  activationOption;         activation: immediate or delayed
 **        iposrfm_firmware_ver  version;   the version to be activated
 **      }  iposrfm_activation_info;
 ** 
 **   This function 
 **      -> gets iposrfm_activation_info structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer (encoded)
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_activation_info
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/


int encodeActivationInfo(iposrfm_activation_info actInfo, U8 **msg)
{
  int size = 0 ;
  int ret_val ;
  

  /* Activation Option : Immediate or delayed */
  **msg = actInfo.activationOption ;
  *msg  += 1 ;
  size++ ;

  /* the version to be activated  */
  ret_val = encodeFirmwareVersion(actInfo.version,msg) ;
  size += ret_val ;

  return size ;
} /* encodeActivationInfo() */


/** 
 **    Decoding Activation Info structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         activation info structure.
 **      -> returns the activation Option.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_activation_info
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 **
 **
 **/


int decodeActivationInfo(U8 *msg, iposrfm_activation_info *actInfo)
{
  int size = 0 ;
     
  /* Activation Option : Immediate or delayed */
  actInfo->activationOption = *msg ;
  msg++ ;
  size++ ;
  
  /* the version to be activated  */
  size += decodeFirmwareVersion(&msg, &actInfo->version) ;
  
  return size ;
} /* decodeActivationInfo() */


/** 
 **    Encoding File Info structure.
 **    typedef struct
 **    {
 **   iposrfm_firmware_ver  verTransfer;  the version to be transfered
 **    U32  fileLength;               the length of the file to be transfered 
                        in bytes
 **   U32  checkSum;               the checsum of the file
 **    }iposrfm_file_info;
 **
 ** 
 **   This function 
 **      -> gets iposrfm_file_info structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer (encoded)
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_file_info
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/

int encodeFileInfo(iposrfm_file_info fileInfo, U8 **msg)
{
  int size = 0 ;
  int ret_val ;

  /* the version to be transferred  */
  ret_val = encodeFirmwareVersion(fileInfo.verTransfer,msg) ;
  size += ret_val ;

  /* length of the file to be transferred (in bytes) */
  **msg = (U8) ((fileInfo.fileLength & 0xFF000000)>> 24) ;  //MSB
  *msg += 1 ;   

  **msg = (U8) ((fileInfo.fileLength & 0xFF0000) >> 16) ;
  *msg += 1 ;

  **msg = (U8) ((fileInfo.fileLength & 0xFF00) >> 8) ;
  *msg += 1 ;

  **msg = (U8) (fileInfo.fileLength & 0xFF) ;    //LSB
  *msg += 1 ;
  size += 4 ;


  /* checksum of the file */
  **msg = (U8) ((fileInfo.checkSum & 0xFF000000)>> 24) ;  //MSB
  *msg += 1 ;   

  **msg = (U8) ((fileInfo.checkSum & 0xFF0000) >> 16) ;
  *msg += 1 ;

  **msg = (U8) ((fileInfo.checkSum & 0xFF00) >> 8) ;
  *msg += 1 ;

  **msg = (U8) (fileInfo.checkSum & 0xFF) ;    //LSB
  *msg += 1 ;
  size += 4 ;

  return size ;
} /* encodeFileInfo() */


 /** 
 **    Decoding File Info structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         file info structure.
 **      -> returns size of decoded message
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_activation_info
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 ** 
 **
 **   Return value :
 **            size of decoded message
 **/



int decodeFileInfo(U8 *msg, iposrfm_file_info *fileInfo)
{
  int size = 0 ;
      
  /* Version to be transferred  */
  size += decodeFirmwareVersion(&msg, &fileInfo->verTransfer) ;

  /* Length of the file that is to be transferred (in bytes) */
  fileInfo->fileLength = (U32) ( ((U32) *(msg+3)) |
                               (((U32) *(msg+2)) << 8) |
                   (((U32) *(msg+1)) << 16) |
                   (((U32) *msg) << 24) ) ;

  msg += 4 ;
  size += 4 ;

  /*  Checksum of the file*/
  fileInfo->checkSum = (U32) ( ((U32) *(msg+3)) |
                               (((U32) *(msg+2)) << 8) |
                   (((U32) *(msg+1)) << 16) |
                   (((U32) *msg) << 24) ) ;
  msg += 4 ;
  size += 4 ;

  
  return size ;
  
} /* decodeFileInfo() */


/** 
 **    Encoding Transfer Info structure.
 **    typedef  struct
 **    {
 **      U32    dataBlockSent;          number of dataBlock sent
 **      U32    byteSent;            number of bytes sent
 **    }  iposrfm_transfer_info;
 **
 ** 
 **   This function 
 **      -> gets iposrfm_transfer_info structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer (encoded)
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_file_info
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/


/* file transfer complete information */

/* Encoding iposrfm_transfer_info structure */

int encodeTransferInfo(iposrfm_transfer_info transferInfo, U8 **msg)
{
  int size = 0 ;
  
  /* Number of dataBlock sent */
  **msg = (U8) ((transferInfo.dataBlockSent & 0xFF000000)>> 24) ;  //MSB
  *msg += 1 ;   

  **msg = (U8) ((transferInfo.dataBlockSent & 0xFF0000) >> 16) ;
  *msg += 1 ;

  **msg = (U8) ((transferInfo.dataBlockSent & 0xFF00) >> 8) ;
  *msg += 1 ;

  **msg = (U8) (transferInfo.dataBlockSent & 0xFF) ;    //LSB
  *msg += 1 ;
  size += 4 ;
  
  /* Number of bytes sent */
  **msg = (U8) ((transferInfo.byteSent & 0xFF000000)>> 24) ;  //MSB
  *msg += 1 ;   

  **msg = (U8) ((transferInfo.byteSent & 0xFF0000) >> 16) ;
  *msg += 1 ;

  **msg = (U8) ((transferInfo.byteSent & 0xFF00) >> 8) ;
  *msg += 1 ;

  **msg = (U8) (transferInfo.byteSent & 0xFF) ;    //LSB
  *msg += 1 ;
  size += 4 ;

  return size ;
} /* encodeTransferInfo() */


 /** 
 **    Decoding Transfer Info structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         transfer info structure.
 **      -> returns the size of decoded message
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_transfer_info
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 ** 
 **
 **   Return value : int
 **             size of decoded message 
 **/

int decodeTransferInfo(U8 *msg, iposrfm_transfer_info *transferInfo)
{

  int size = 0 ;

  /* Number of dataBlock Sent */
  transferInfo->dataBlockSent = (U32) ( ((U32) *(msg+3)) |
                                      (((U32) *(msg+2)) << 8) |
                          (((U32) *(msg+1)) << 16) |
                          (((U32) *msg) << 24) ) ;
  
  msg += 4 ;
  size += 4 ;

  /* Number of bytes sent */
  transferInfo->byteSent = (U32) ( ((U32) *(msg+3)) |
                                 (((U32) *(msg+2)) << 8) |
                     (((U32) *(msg+1)) << 16) |
                     (((U32) *msg) << 24) ) ;

  msg += 4 ;
  size += 4 ;


  return size ;
} /* decodeTransferInfo() */


/** 
 **    Encoding File Save Info structure.
 **    typedef  struct
 **    {
 **      U32    dataBlockSent;          number of dataBlock sent
 **      U32    byteSent;            number of bytes sent
 **    }  iposrfm_file_save_info;
 **
 ** 
 **   This function 
 **      -> gets iposrfm_file_save_info structure
 **      -> Puts the contents of this structure into the message buffer
 **      -> returns number of bytes in the message header buffer (encoded)
 **
 **   Arguments :
 **       msgHdr      : INPUT
 **                     TYPE : iposrfm_file_save_info
 **                     this is the structure that is to be encoded.
 **
 **       msg         : OUTPUT
 **                     TYPE : U8 **
 **                     This is the buffer into which the message bytes 
 **                     are written.
 **
 **/


int encodeFileSaveInfo(iposrfm_file_save_info filesaveInfo, U8 **msg)
{
  int size = 0 ;
  int ret_val ;

  /* file save status : failed or success */
  **msg = filesaveInfo.fileSaveStatus ;
  *msg  += 1 ;
  size++ ;

  /* firmware version saved */
  ret_val = encodeFirmwareVersion(filesaveInfo.firmwareVerSaved, msg) ;
  size += ret_val ;

  /* firmware version replaced */
  ret_val = encodeFirmwareVersion(filesaveInfo.replacedFirmwareVer, msg) ;
  size += ret_val ;

  return size ;
} /* encodeFileSaveInfo() */


/** 
 **    Decoding File Save structure
 ** 
 **   This function 
 **      -> gets the pointer to the message buffer 
 **      -> Puts the contents of this message buffer into 
 **         file save info structure.
 **      -> returns the size of decoded message.
 **
 **   Arguments :
 **       msg         : INPUT
 **                     pointer to the message buffer.
 **
 **       fw_ver      : OUTPUT
 **                     TYPE : iposrfm_file_save_info
 **                     this is the structure into which the contents
 **                     of the message buffer is written.
 ** 
 **
 **   Return value :
 **            size of the decoded message 
 **/


int decodeFileSaveInfo(U8 **msg, iposrfm_file_save_info *filesaveInfo)
{

  int size = 0 ;

  /* file save status : failed or success */
  filesaveInfo->fileSaveStatus = **msg ;
  *msg += 1 ;
  size++ ;

  size += decodeFirmwareVersion(msg, &filesaveInfo->firmwareVerSaved) ;

  size += decodeFirmwareVersion(msg, &filesaveInfo->replacedFirmwareVer) ;

  return size ;

} /* decodeFileSaveInfo() */

  
  
/**
 ** Message structure Encoding function 
 **
 **   This function 
 **         -> is called by a function which needs to encode a message structure
 **        
 **   Arguments :
 **        pStructBuf   :   INPUT
 **                         TYPE : void *
 **                         
 **                         This is pointer to a structure that is to be encoded. 
 **                         The contents of this structure are placed in message buffer
 **
 **        msgType      :   INPUT
 **                         TYPE : U8
 **
 **        pMsgBuf      :   OUTPUT
 **                         TYPE : U8 *
 **                         The contents of input structure is placed in this message buffer
 **                         This message buffer is transmitted to the other end.
 **
 **
 **   Return value : int
 **           size    :   number of bytes encoded - size of message buffer that is to be 
 **                       transmitted.
 **
 **/

int iposRFMStruct2Msg(void *pStructBuf, U8 msgType, U8 *pBuf, U8 *msgLen)
{
  int size = 0 ;
  int ret_val ;
  U8  ack;

  U8  **pMsgBuf;
  U8  *pMsg2;

  iposrfm_firmware_ver_req      *iposrfmfwVerReq ;
//iposrfm_data_block            *iposrfmdatablock ;
  iposrfm_activation_req        *iposrfmActReq ;
  iposrfm_file_transfer_req     *iposrfmFileTrnReq ;
  iposrfm_transfer_complete_req *iposrfmFileTrnCompReq ;
  iposrfm_transfer_abort_req    *iposrfmTrnAbortReq ;
  iposrfm_file_save_req         *iposrfmFileSaveReq ;
//iposrfm_data_ack              *iposrfmDataAck ;
  iposrfm_activation_resp       *iposrfmActResp ;
//iposrfm_transfer_abort_resp   *iposrfmTrnAbortResp ; 
  iposrfm_file_save_resp        *iposrfmFileSaveResp ;
  iposrfm_file_transfer_resp    *iposrfmfileTrnResp ;
  iposrfm_firmware_ver_resp     *iposrfmfwVerResp ;
  iposrfm_transfer_complete_resp *iposrfmTrnCompResp ;


  pMsg2=pBuf;
  pMsgBuf=&pMsg2;

  switch (msgType) {  
     case IPOSRFM_MSG_FIRMWARE_VER : {
           
       iposrfmfwVerReq = (iposrfm_firmware_ver_req *) pStructBuf ;
       ack=iposrfmfwVerReq->ctrlHdr.ack;
       if(ack==IPOSRFM_ACK_CMD)
       {
#ifdef  TEST
        printf("Coding FIRMWARE_VER_REQ\n");
#endif
        ret_val = encodeCtrlHeader(iposrfmfwVerReq->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

      } else {
#ifdef  TEST
        printf("Coding FIRMWARE_VER_RESP\n");
#endif

         iposrfmfwVerResp = (iposrfm_firmware_ver_resp *) pStructBuf ;
         ret_val = encodeCtrlHeader(iposrfmfwVerResp->ctrlHdr, pMsgBuf) ;
         size += ret_val ;

        /* Encoding info fields */

         **pMsgBuf = VERSION_INFO ;
         *pMsgBuf += 1 ;
         size++ ;

         /* space for length of the IE */
         *pMsgBuf += 1 ;
         size++ ;

         ret_val = encodeVersionInfo(iposrfmfwVerResp->verInfo, pMsgBuf) ;
         size += ret_val ;

         /* Length of the IE */
         *(*pMsgBuf-ret_val-1) = ret_val ;
       }

     break ;
    } /* case - IPOSRFM_MSG_FIRMWARE_VER */
          
    case IPOSRFM_MSG_FIRMWARE_ACTIVATE : {
      
      iposrfmActReq = (iposrfm_activation_req *) pStructBuf ;
      
      ack=iposrfmActReq->ctrlHdr.ack;
      if(ack==IPOSRFM_ACK_CMD)
      {
#ifdef  TEST        
        printf("Coding Firmware Activate message\n") ;
#endif
        ret_val = encodeCtrlHeader(iposrfmActReq->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

        **pMsgBuf = ACTIVATION_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeActivationInfo(iposrfmActReq->activationInfo, pMsgBuf) ;
        size += ret_val ;
               
        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;

      } else {
#ifdef  TEST
        printf("Coding Firmware Activate message Response\n") ;
#endif
        iposrfmActResp = (iposrfm_activation_resp *) pStructBuf ;

        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmActResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

        /* Encoding activation status - accept or reject */
        /* IE Type */
        **pMsgBuf = ACTIVATION_STATUS ;
        *pMsgBuf += 1 ;
        size++ ;

        /* IE Length */
        **pMsgBuf = 1 ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Value */
        **pMsgBuf = iposrfmActResp->activationStatus ;
        *pMsgBuf += 1 ;
        size++ ;

      } /* if */

      break ;
    } /* case - IPOSRFM_MSG_FIRMWARE_ACTIVATE */

    case IPOSRFM_MSG_FILE_TRANSFER : {
      
            
      iposrfmFileTrnReq = (iposrfm_file_transfer_req *) pStructBuf ;
      ack=iposrfmFileTrnReq->ctrlHdr.ack;
      
      if(ack==IPOSRFM_ACK_CMD)
      {
        
#ifdef  TEST
        printf("Coding File Transfer Req\n") ;
#endif
        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmFileTrnReq->ctrlHdr, pMsgBuf) ;
        size += ret_val ;
             
        /* Encoding firmware version */
        /* IE Type */
        **pMsgBuf = FIRMWARE_VERSION ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeFirmwareVersion(iposrfmFileTrnReq->firmwareReplaced, pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;

        /* IE Type */
        **pMsgBuf = FILE_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;
        
        ret_val = encodeFileInfo(iposrfmFileTrnReq->newFileInfo, pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;
      
      } else {

#ifdef  TEST
        printf("Coding File Transfer Response\n") ;
#endif

        iposrfmfileTrnResp = (iposrfm_file_transfer_resp *) pStructBuf ;

        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmfileTrnResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

        /* Encoding Firmware Version */
        /* IE Type */
        **pMsgBuf = FIRMWARE_VERSION ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeFirmwareVersion(iposrfmfileTrnResp->replacedFirmwareVer,pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;

      } /* if */
      break ;
    } /* case - IPOSRFM_MSG_FILE_TRANSFER */

    case IPOSRFM_MSG_FILE_TR_COMPLETE : {

      iposrfmFileTrnCompReq = (iposrfm_transfer_complete_req *) pStructBuf ;
      ack=iposrfmFileTrnCompReq->ctrlHdr.ack;    
      
      if(ack==IPOSRFM_ACK_CMD)
      {
        
#ifdef  TEST
        printf("Coding File Transfer Complete Req\n") ;
#endif
        /* Encoding ctrl Header */
        
      /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmFileTrnCompReq->ctrlHdr, pMsgBuf) ;
        size += ret_val ;
          
        /* Encoding Transfer Info */
        /* IE Type */
        **pMsgBuf = TRANSFER_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeTransferInfo(iposrfmFileTrnCompReq->transferInfo, pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;
      
      } else {

#ifdef  TEST
        printf("Coding File Transfer Complete Resp\n") ;
#endif
        iposrfmTrnCompResp = (iposrfm_transfer_complete_resp *) pStructBuf ;

        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmTrnCompResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;


        /* Encoding Transfer Info */
        /* IE Type */
        **pMsgBuf = TRANSFER_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeTransferInfo(iposrfmTrnCompResp->transferInfo, pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;

        /* Encoding File Info */
        /* IE Type */
        **pMsgBuf = FILE_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Space for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeFileInfo(iposrfmTrnCompResp->rcvedFile, pMsgBuf) ;
        size += ret_val ;

        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;

      } /* if */

      break ;

    } /* case - IPOSRFM_MSG_FILE_TR_COMPLETE */
                                   
    case IPOSRFM_MSG_FILE_TR_ABORT : {
      printf("File Transfer Abort\n") ;

      iposrfmTrnAbortReq = (iposrfm_transfer_abort_req *) pStructBuf ;
        
      /* Encoding ctrl Header */
      ret_val = encodeCtrlHeader(iposrfmTrnAbortReq->ctrlHdr, pMsgBuf) ;
      size += ret_val ;
             
      /* Encoding abort Cause */
      /* IE Type */
      **pMsgBuf = ABORT_CAUSE ;
      *pMsgBuf += 1 ;
      size++ ;

      /* Length */
      **pMsgBuf = 1 ;
      *pMsgBuf += 1 ;
      size++ ;

      **pMsgBuf = iposrfmTrnAbortReq->abortCause ;
      *pMsgBuf += 1 ;
      size++ ;

      break ;
    } /* case - IPOSRFM_MSG_FILE_TR_ABORT */
                                   
    case IPOSRFM_MSG_FILE_SAVE : {

      iposrfmFileSaveReq = (iposrfm_file_save_req *) pStructBuf ;
      ack=iposrfmFileSaveReq->ctrlHdr.ack;
      
      if(ack==IPOSRFM_ACK_CMD)
      {
        
#ifdef  TEST
        printf("Coding File Save Req\n") ;
#endif
        
        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmFileSaveReq->ctrlHdr, pMsgBuf) ;
        size += ret_val ;
             
        **pMsgBuf = FILESAVE_INFO ;
        *pMsgBuf += 1 ;
        size++ ;

        /* Location for length of the IE */
        *pMsgBuf += 1 ;
        size++ ;

        ret_val = encodeFileSaveInfo(iposrfmFileSaveReq->fileSave, pMsgBuf) ;
        size += ret_val ;
        
        /* Length of the IE */
        *(*pMsgBuf-ret_val-1) = ret_val ;
      
      } else {

#ifdef  TEST
        printf("Coding File Transfer Resp\n") ;
#endif

        iposrfmFileSaveResp = (iposrfm_file_save_resp *) pStructBuf ;

        ret_val = encodeCtrlHeader(iposrfmFileSaveResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

      } /* if */

      break;
  } /* case - IPOSRFM_MSG_FILE_SAVE */

#if 0
    case IPOSRFM_MSG_DATA_BLOCK : {
      printf("Data Block \n") ;

      iposrfmdatablock = (iposrfm_data_block *) pStructBuf ; 

      /* Encoding Message header */
      ret_val = encodeMsgHeader(iposrfmdatablock->genericHdr, pMsgBuf) ;
      size += ret_val ;

      /* Session ID */
      **pMsgBuf = SESSION_ID ;
      *pMsgBuf += 1 ;
      size++ ;

      **pMsgBuf = 1 ;
      *pMsgBuf += 1 ;
      size++ ;

      /* Session Id */
      **pMsgBuf = iposrfmdatablock->sid ;
      *pMsgBuf += 1 ;
      size++ ;

      /* Sequence Number */
      **pMsgBuf = SEQ_NUM ;
      *pMsgBuf += 1 ;
      size++ ;

      **PMsgBuf = 2 ;
      *pMsgBuf += 1 ;
      size++ ;

      **pMsgBuf = (iposrfmdatablock->seq & 0xFF00)>>8 ;  //MSB
      *pMsgBuf += 1 ;   
      **pMsgBuf = iposrfmdatablock->seq & 0xFF ;    //LSB
      *pMsgBuf += 1 ;
      size += 2 ;

      /* Data block */
      **pMsgBuf = DATA_BLOCK ;
      *pMsgBuf += 1 ;

      **pMsgBuf = iposrfmdatablock->genericHdr.length ;
      *pMsgBuf += 1 ;

      memcpy(*pMsgBuf,iposrfmdatablock->data,iposrfmdatablock->genericHdr.length) ;
      *pMsgBuf += iposrfmdatablock->genericHdr.length ;
      size += iposrfmdatablock->genericHdr.length ;
     
      
    break ;
     } /* case - IPOSRFM_MSG_DATA_BLOCK */  
                                   
    case IPOSRFM_MSG_ACK : {
      printf("MSG ACK\n") ;

          iposrfmDataAck = (iposrfm_data_ack *) pStructBuf ; 

        /* Encoding Message header */
      ret_val = encodeMsgHeader(iposrfmDataAck->genericHdr, pMsgBuf) ;
      size += ret_val ;    
      
      /* Session Id */
          **pMsgBuf = iposrfmDataAck->sid ;
      *pMsgBuf += 1 ;
      size++ ;

      /* Ack for start data block */
      **pMsgBuf = (iposrfmDataAck->ack1 & 0xFF00)>>8 ;  //MSB
      *pMsgBuf += 1 ;   
      **pMsgBuf = iposrfmDataAck->ack1 & 0xFF ;    //LSB
      *pMsgBuf += 1 ;
      size += 2 ;

      /* Ack for the last data block */
      **pMsgBuf = (iposrfmDataAck->ack2 & 0xFF00)>>8 ;  //MSB
      *pMsgBuf += 1 ;
      **pMsgBuf = iposrfmDataAck->ack2 & 0xFF ;    //LSB
      *pMsgBuf += 1 ;
      size += 2 ;
      
          **pMsgBuf = NO_INFO ; /* No info fields */
      *pMsgBuf += 1 ;
      size++ ;

      break ;
     } /* case - IPOSRFM_MSG_ACK */  
  
#endif

#if 0
        case IPOSRFM_MSG_FILE_SAVED : {
    
      iposrfmFileSaveResp = (iposrfm_file_save_resp *) pStructBuf ;

      ret_val = encodeCtrlHeader(iposrfmFileSaveResp->ctrlHdr, pMsgBuf) ;
      size += ret_val ;

      **pMsgBuf = NO_INFO ; /* No info fields */
      *pMsgBuf += 1 ;
      size++ ;

    break ;
                    } /* IPOSRFM_MSG_FILE_SAVED */

        case IPOSRFM_MSG_FIRMWARE_VER_RESP : {
          
      /* Encoding cntrl header */
      iposrfmfwVerResp = (iposrfm_firmware_ver_resp *) pStructBuf ;
      ret_val = encodeCtrlHeader(iposrfmfwVerResp->ctrlHdr, pMsgBuf) ;
      size += ret_val ;

           /* Encoding info fiels */

          **pMsgBuf = 0x00 ;
      **pMsgBuf |= VERSION_INFO ;
      *pMsgBuf += 1 ;
      size++ ;

          ret_val = encodeVersionInfo(iposrfmfwVerResp->verInfo, pMsgBuf) ;
      size += ret_val ;

      break ;
                  } /* IPOSRFM_MSG_VER_RESP */

        case IPOSRFM_MSG_ACTIVATION_RESP : {

          printf("Activation response \n") ;

            iposrfmActResp = (iposrfm_activation_resp *) pStructBuf ;
        
        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmActResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;
             
      /* Encoding activation status - accept or reject */
      **pMsgBuf = iposrfmActResp->activationStatus ;
      *pMsgBuf += 1 ;
      size++ ;

      **pMsgBuf = 0x00 ;
        **pMsgBuf |= NO_INFO ;
      *pMsgBuf += 1 ;
      size++ ;

      break ;
                       } /* IPOSRFM_MSG_ACTIVATION_RESP */
        case IPOSRFM_MSG_FILE_TR_RESP : {
            iposrfmfileTrnResp = (iposrfm_file_transfer_resp *) pStructBuf ;
        
        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmfileTrnResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;

      /* Encoding Firmware Version */
            ret_val = encodeFirmwareVersion(iposrfmfileTrnResp->replacedFirmwareVer,pMsgBuf) ;
          size += ret_val ;
      
      **pMsgBuf = 0x00 ;
        **pMsgBuf |= NO_INFO ;
      *pMsgBuf += 1 ;
      size++ ;

      break ;
                    } /* IPOSRFM_MSG_FILE_TR_RESP */

        case IPOSRFM_MSG_TRN_COMP_RESP : {
      printf("Transfer Complete response\n") ;

            iposrfmTrnCompResp = (iposrfm_transfer_complete_resp *) pStructBuf ;
        
        /* Encoding ctrl Header */
        ret_val = encodeCtrlHeader(iposrfmTrnCompResp->ctrlHdr, pMsgBuf) ;
        size += ret_val ;
             
      **pMsgBuf = 0x00 ;
        **pMsgBuf |= TRANSFER_INFO ;
            **pMsgBuf |= FILE_INFO ;
      *pMsgBuf += 1 ;
      size++ ;
      
            ret_val = encodeTransferInfo(iposrfmTrnCompResp->transferInfo, pMsgBuf) ;
      size += ret_val ;

      ret_val = encodeFileInfo(iposrfmTrnCompResp->rcvedFile, pMsgBuf) ;
      size += ret_val ;

      break ;
                     } /* IPOS_RFM_MSG_TRN_COMP_RESP */

        case IPOSRFM_MSG_TRN_ABORT_RESP : {
           
       iposrfmTrnAbortResp = (iposrfm_transfer_abort_resp *) pStructBuf ;
       ret_val = encodeCtrlHeader(iposrfmTrnAbortResp->ctrlHdr, pMsgBuf) ;
       size += ret_val ;

       **pMsgBuf = NO_INFO ; /* No info fields */
       *pMsgBuf += 1 ;
       size++ ;

      break ;
                      } /* IPOSRFM_MSG_TRN_ABORT_RESP */

#endif

  } /* switch */

//  size-=1;
  pBuf[IPOSRFM_MSGHDR_MSGLEN]=size;
    return size ;
} /* iposRFMStruct2Msg() */



/**
 ** Message Buffer Decoding function 
 **
 **   This function 
 **         -> is called by a function which needs to decode received message buffer.
 **        
 **   Arguments :
 **        pMsgBuf      :   INPUT
 **                         TYPE : U8 *
 **                         This is pointer to message buffer that is to be decoded.
 **
 **        msgType      :   OUTPUT
 **                         TYPE : U8 *
 **                         Type of received message
 **
 **        pStructBuf   :   OUTPUT
 **                         TYPE : void **
 **                         
 **                         This is void ** into which the decoded message(structure) shall
 **                         be stored.
 **                         
 **
 **
 **
 **/


/* Decoding */
int iposRFMMsg2Struct(U8 *pMsgBuf, void *pStructBuf, U8 *msgType)
{
  
  int                             size ;
//int                             info_fields ;
//U8                              infotypebyte ;
  int                             ret_val ;
  U8                              ack;
  int                             ieType ;
  int                             ieLen ;
  int                             decodedLen ;
  int                             msgLen ;


  iposrfm_firmware_ver_req        *fwverReqStruct ;
//iposrfm_data_block              *datablockStruct ;
//iposrfm_data_ack                *dataackStruct ;
  iposrfm_activation_req          *actReqStruct ;
  iposrfm_file_transfer_req        *fileTrnReqStruct ;
  iposrfm_transfer_complete_req    *fileTrnCompReqStruct ;
  iposrfm_transfer_abort_req      *fileTrnAbortReqStruct ;
  iposrfm_file_save_req            *fileSaveReqStruct ;
  iposrfm_activation_resp          *actRespStruct ;
//iposrfm_transfer_abort_resp     *trnAbortRespStruct ;
  iposrfm_file_save_resp          *fsRespStruct ;
  iposrfm_file_transfer_resp      *fileTrnRespStruct ;
  iposrfm_firmware_ver_resp       *fwverRespStruct ;
  iposrfm_transfer_complete_resp  *trnCompRespStruct ;
      
  *msgType = *(pMsgBuf+1) ;  /* Always 2nd byte in any message in message type */
  ack=pMsgBuf[IPOSRFM_MSGHDR_ACK];

  msgLen = pMsgBuf[IPOSRFM_MSGHDR_MSGLEN] ;

  decodedLen = 0 ;

  switch (*msgType) {  
   case IPOSRFM_MSG_FIRMWARE_VER : 
  {
    if(ack==IPOSRFM_ACK_CMD)
    {
#ifdef  TEST      
      printf("Decode Firmware Version request\n") ;
#endif
      fwverReqStruct = (iposrfm_firmware_ver_req *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(fwverReqStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

    } else {

#ifdef  TEST      
      printf("Decode Firmware Version response\n") ;
#endif

      fwverRespStruct = (iposrfm_firmware_ver_resp *) pStructBuf ;
      
      /* Decode Ctrl Header */
      size = decodeCtrlHeader(pMsgBuf, &(fwverRespStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

      while (decodedLen < msgLen) {

        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;
        ieLen = *pMsgBuf ;
        pMsgBuf += 1 ;
        
        decodedLen += 2 ;

        switch (ieType) {

        case VERSION_INFO : {
          /* Version Info */
          ret_val = decodeVersionInfo(&pMsgBuf, &(fwverRespStruct->verInfo)) ;

          if (ret_val != ieLen) {
            printf("decoded length and actual length not matching\n") ;
            return IPOS_ERROR ;
          } /* if */
          decodedLen += ret_val ;

          break ;
                            } /* VERSION_INFO */

        default :
          printf("Unexpected IE\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */

    } /* if */

    break ;
  } /* case - IPOSRFM_MSG_FIRMWARE_VER */
          
  case IPOSRFM_MSG_FIRMWARE_ACTIVATE : {
    
    if(ack==IPOSRFM_ACK_CMD)
    {
#ifdef  TEST      
      printf("Decode firmware activation req \n") ;
#endif

      actReqStruct = (iposrfm_activation_req *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(actReqStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

      while (decodedLen < msgLen) {
        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;
        ieLen = *pMsgBuf ;
        pMsgBuf += 1 ;
        decodedLen += 2 ;

        switch (ieType) {

        case ACTIVATION_INFO : {
          ret_val = decodeActivationInfo(pMsgBuf,&(actReqStruct->activationInfo)) ;

          if (ret_val != ieLen) {
            printf("decoded length and actual length not matching\n") ;
            return IPOS_ERROR ;
          } /* if */
          size += ret_val ;
          pMsgBuf += ret_val ;
          decodedLen += ret_val ;

          break ;
                               } /* ACTIVATION_INFO */

        default :
          printf("Unexpected IE\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */
        
    } else {

#ifdef  TEST      
      printf("Decode firmware activation resp \n") ;
#endif

      actRespStruct = (iposrfm_activation_resp *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(actRespStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

      while (decodedLen < msgLen) {

        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;
        ieLen = *pMsgBuf ;
        pMsgBuf += 1 ;
        decodedLen += 2 ;

        switch (ieType) {
        case ACTIVATION_STATUS : {
          /* Activation Status : accept or reject */
          actRespStruct->activationStatus = *pMsgBuf ;
          pMsgBuf++ ;
          decodedLen++ ;
          break ;
                                 } /* ACTIVATION_STATUS */


        default :
          printf("Unexpected ie\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */
    } /* if */
    break ;
  } /* case - IPOSRFM_MSG_FIRMWARE_ACTIVATE */

  case IPOSRFM_MSG_FILE_TRANSFER : {                   


    if(ack==IPOSRFM_ACK_CMD)
    {
#ifdef  TEST      
      printf("Decode file transfer req \n") ;
#endif

      fileTrnReqStruct = (iposrfm_file_transfer_req *) pStructBuf ;

      /* Ctrl Header */
      size = decodeCtrlHeader(pMsgBuf, &(fileTrnReqStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;


      while (decodedLen < msgLen) {
        

        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;
        ieLen  = *pMsgBuf ;
        pMsgBuf += 1 ;
        decodedLen += 2 ;

        switch (ieType) {

        case FILE_INFO : {
          ret_val = decodeFileInfo(pMsgBuf, &(fileTrnReqStruct->newFileInfo)) ;
          if (ret_val != ieLen) {
            printf("Decoded len and actual len are not matching\n") ;
            return IPOS_ERROR ;
          } /* if */
          size += ret_val ;
          pMsgBuf += ret_val ;
          decodedLen += ret_val ;

          break ;
                         } /* FILE INFO */

        case FIRMWARE_VERSION : {
          /* Firmware Version */
          ret_val = decodeFirmwareVersion(&pMsgBuf, &(fileTrnReqStruct->firmwareReplaced)) ;
          if (ret_val != ieLen) {
            printf("Decoded length and actual length are not matching\n") ;
            return IPOS_ERROR ;
          } /* if */
          size += ret_val ;
          decodedLen += ret_val ;
          break ;
                                } /* FIRMARE_VERSION */


        default :
          printf("Unexpected IE\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */

               
    } else {

#ifdef  TEST      
      printf("Decode file transfer resp \n") ;
#endif

      fileTrnRespStruct = (iposrfm_file_transfer_resp *) pStructBuf ;

  
      /* Decode Ctrl Header */
      size = decodeCtrlHeader(pMsgBuf, &(fileTrnRespStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

      while (decodedLen < msgLen) {
      
        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;
        ieLen = *pMsgBuf ;
        pMsgBuf += 1 ;
        decodedLen += 2 ;

        switch (ieType) {
          case FIRMWARE_VERSION : {
            /* Decode Firmware version - Firmware version replaced */
            ret_val = decodeFirmwareVersion(
                      &pMsgBuf, 
                      &(fileTrnRespStruct->replacedFirmwareVer)
                    ) ;
            if (ret_val != ieLen) {
              printf("decoded len and actual len are not matching\n") ;
              return IPOS_ERROR ;
            } /* if */
            decodedLen += ret_val ;
            break ;
                                   } /* FIRMWARE_VERSION */


          default :
            printf("Unexpected IE\n") ;
            return IPOS_ERROR ;

        } /* switch */

      } /* while */

    } /* if */
    break ;
    } /* case - IPOSRFM_MSG_FILE_TRANSFER */

    case IPOSRFM_MSG_FILE_TR_COMPLETE : {
      if(ack==IPOSRFM_ACK_CMD)
      {
  #ifdef  TEST      
        printf("Decode file transfer complete req \n") ;
  #endif

        fileTrnCompReqStruct = (iposrfm_transfer_complete_req *) pStructBuf ;

        /* Decode Ctrl Header */
        size = decodeCtrlHeader(pMsgBuf, &(fileTrnCompReqStruct->ctrlHdr)) ;
        pMsgBuf += size ;
        decodedLen += size ;

        while (decodedLen < msgLen) {

          ieType = *pMsgBuf ;
          pMsgBuf += 1 ;
          ieLen = *pMsgBuf ;
          pMsgBuf += 1 ;
          decodedLen += 2 ;

          switch (ieType) {

          case TRANSFER_INFO : {
            ret_val = decodeTransferInfo(
                        pMsgBuf, 
                        &(fileTrnCompReqStruct->transferInfo)
                      ) ;
            if (ret_val != ieLen) {
              printf("decoded length and actual length not matching\n") ;
              return IPOS_ERROR ;
            } /* if */
            pMsgBuf += ret_val ;
            size += ret_val ;
            decodedLen += ret_val ;

            break ;
                           } /* TRANSFER INFO */

          default :
            printf("Unexpected IE\n") ;
            return IPOS_ERROR ;

          } /* switch */

        } /* while */

    
      } else {
  #ifdef  TEST      
        printf("Decode file transfer complete resp \n") ;
  #endif

        trnCompRespStruct = (iposrfm_transfer_complete_resp *) pStructBuf ;

        /* Ctrl Header */
        size = decodeCtrlHeader(pMsgBuf, &(trnCompRespStruct->ctrlHdr)) ;
        pMsgBuf += size ;
        decodedLen += size ;

        while (decodedLen < msgLen) {

          ieType = *pMsgBuf ;
          pMsgBuf += 1 ;
          ieLen = *pMsgBuf ;
          pMsgBuf += 1 ;
          decodedLen += 2 ;

          switch (ieType) {

          case TRANSFER_INFO : {
            ret_val = decodeTransferInfo(
                        pMsgBuf, 
                        &(trnCompRespStruct->transferInfo)
                      ) ;

            if (ret_val != ieLen) {
              printf("decoded length and actual length not matching\n") ;
              return IPOS_ERROR ;
            } /* if */
            pMsgBuf += ret_val ;
            size += ret_val ;
            decodedLen += ret_val ;

            break ;
                           } /* TRANSFER INFO */

          
          case FILE_INFO : {
            ret_val = decodeFileInfo(
                        pMsgBuf, 
                        &(trnCompRespStruct->rcvedFile)
                      ) ;

            if (ret_val != ieLen) {
              printf("decoded length and actual length not matching\n") ;
              return IPOS_ERROR ;
            } /* if */
            pMsgBuf += ret_val ;
            size += ret_val ;
            decodedLen += ret_val ;

          break ;
                         } /* FILE INFO */
          
          default :
            printf("Unexpected IE\n") ;
            return IPOS_ERROR ;

          } /* switch */

        } /* while */
    
      } /* if */

      break ;
    } /* case - IPOSRFM_MSG_FILE_TR_COMPLETE */
                                   
    case IPOSRFM_MSG_FILE_TR_ABORT : {
      printf("File Transfer Abort\n") ;

      fileTrnAbortReqStruct = (iposrfm_transfer_abort_req *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(fileTrnAbortReqStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

      while (decodedLen < msgLen) {
        /* Abort Cause */
        ieType = *pMsgBuf ;
        pMsgBuf++ ;
        ieLen  = *pMsgBuf ;
        pMsgBuf++ ;
        decodedLen += 2 ;

        switch (ieType) {
        case ABORT_CAUSE : {
          fileTrnAbortReqStruct->abortCause = *pMsgBuf ;
          pMsgBuf++ ;
          decodedLen++ ;
          break ;
        } /* ABORT_CAUSE */

        default :
          printf("Unexpected IE\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */
      break ;
    } /* case - IPOSRFM_MSG_FILE_TR_ABORT */
                                   
    case IPOSRFM_MSG_FILE_SAVE : {


    if(ack==IPOSRFM_ACK_CMD)
    {
  #ifdef  TEST      
        printf("Decode file save req \n") ;
  #endif

      fileSaveReqStruct = (iposrfm_file_save_req *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(fileSaveReqStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;
        
      while (decodedLen < msgLen) {

        /* Decoding FileSaveInfo */
        ieType = *pMsgBuf ;
        pMsgBuf += 1 ;

        ieLen = *pMsgBuf ;
        pMsgBuf += 1 ;
        decodedLen += 2 ;

        switch (ieType) {
        case FILESAVE_INFO : {
          ret_val = decodeFileSaveInfo(&pMsgBuf, &(fileSaveReqStruct->fileSave)) ;
          if (ret_val != ieLen) {
            printf("decoded length and actual length not matching\n") ;
            return IPOS_ERROR ;
          } /* if */
          size += ret_val ;
          decodedLen += ret_val ;
          break ;
                             } /* FILESAVE_INFO */

        default :
          printf("Unexpected IE\n") ;
          return IPOS_ERROR ;

        } /* switch */

      } /* while */


        
    }  else {

  #ifdef  TEST      
      printf("Decode file save resp \n") ;
  #endif
      fsRespStruct = (iposrfm_file_save_resp *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(fsRespStruct->ctrlHdr)) ;
      pMsgBuf += size ;
      decodedLen += size ;

    } /* if */

    break ;
    } /* case - IPOSRFM_MSG_FILE_SAVE */

#if 0
    case IPOSRFM_MSG_DATA_BLOCK : {
      printf("Data Block \n") ;

      datablockStruct = (iposrfm_data_block *) pStructBuf ;

          /* Msg Header */
      size = decodeMsgHeader(pMsgBuf,&datablockStruct->genericHdr) ;
      pMsgBuf += size ;

      /* session id */
      datablockStruct->sid = *pMsgBuf ;
      pMsgBuf++ ;

      /* sequence number */
          datablockStruct->seq = (U16) (*pMsgBuf << 8) | (U16) (*(pMsgBuf+1) & 0xFF)  ;
      pMsgBuf += 2 ;

      /* data */
          memcpy(datablockStruct->data, pMsgBuf, datablockStruct->genericHdr.length) ; 
          pMsgBuf +=  datablockStruct->genericHdr.length ;

          if (*pMsgBuf == NO_INFO) {
//            printf("There are no info fields in this message...\n") ;
//      printf("End of message\n") ;
      pMsgBuf += 1 ;
      } /* if */

        break ;
     } /* case - IPOSRFM_MSG_DATA_BLOCK */  
                                   
    case IPOSRFM_MSG_ACK : {
      printf("MSG ACK\n") ;

      dataackStruct = (iposrfm_data_ack *) pStructBuf ;

          /* Msg Header */
      size = decodeMsgHeader(pMsgBuf,&dataackStruct->genericHdr) ;
      pMsgBuf += size ;

      /* session id */
      dataackStruct->sid = *pMsgBuf ;
      pMsgBuf++ ;

      /* Ack for starting data block */
          dataackStruct->ack1 = (U16) (*pMsgBuf << 8) | (U16) (*(pMsgBuf+1) & 0xFF)  ;
      pMsgBuf += 2 ;

      /* Ack for the last data block */
          dataackStruct->ack2 = (U16) (*pMsgBuf << 8) | (U16) (*(pMsgBuf+1) & 0xFF)  ;
      pMsgBuf += 2 ;

          if (*pMsgBuf == NO_INFO) {
  //          printf("There are no info fields in this message...\n") ;
//      printf("End of message\n") ;
      pMsgBuf += 1 ;
      } /* if */

    break ;
     } /* case - IPOSRFM_MSG_ACK */        

#endif

#if 0
        case IPOSRFM_MSG_FILE_SAVE : {

          fsRespStruct = (iposrfm_file_save_resp *) pStructBuf ;
      
          size = decodeCtrlHeader(pMsgBuf, &(fsRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

        info_fields = num_of_info_elements(*pMsgBuf) ;
//        printf("No. of info fields : %d\n", info_fields) ;
    
        if (info_fields == 0) {
//            printf("No info fields in this message\n") ;
//        printf("End of message\n") ;
      } /* if */
        pMsgBuf += 1 ;

      break ;
    } /* IPOSRFM_MSG_FILE_SAVED */

        case IPOSRFM_MSG_FIRMWARE_VER_RESP : {
            
      fwverRespStruct = (iposrfm_firmware_ver_resp *) pStructBuf ;
      
      /* Decode Ctrl Header */
          size = decodeCtrlHeader(pMsgBuf, &(fwverRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

        info_fields = num_of_info_elements(*pMsgBuf) ;


      if (info_fields == 0) {
//            printf("No info fields in this message\n") ;
//        printf("End of message\n") ;
      } else {
    
            infotypebyte = *pMsgBuf ;
        pMsgBuf += 1 ;

        if (infotypebyte & VERSION_INFO) {
              /* Decode Version Info  message field for the version information */
          ret_val = decodeVersionInfo(&pMsgBuf, &(fwverRespStruct->verInfo)) ;
            
      } /* if */
    
          } /* if */

        break ;
    } /* IPOSRFM_MSG_FIRMWARE_VER_RESP */


        case IPOSRFM_MSG_ACTIVATION_RESP : {

          printf("Activation response \n") ;
          
      actRespStruct = (iposrfm_activation_resp *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(actRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

      /* Activation Status : accept or reject */
      actRespStruct->activationStatus = *pMsgBuf ;
      pMsgBuf++ ;

        info_fields = num_of_info_elements(*pMsgBuf) ;
//        printf("No. of info fields : %d\n", info_fields) ;
    
        if (info_fields == 0) {
//            printf("No info fields in this message\n") ;
//        printf("End of message\n") ;
      } /* if */

        break ;
    } /* IPOSRFM_MSG_ACTIVATION_RESP */

        case IPOSRFM_MSG_FILE_TR_RESP : {
    
          fileTrnRespStruct = (iposrfm_file_transfer_resp *) pStructBuf ;

      /* Decode Ctrl Header */
          size = decodeCtrlHeader(pMsgBuf, &(fileTrnRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

          /* Decode Firmware version  - Firmware version replaced */
          ret_val = decodeFirmwareVersion(&pMsgBuf, &(fileTrnRespStruct->replacedFirmwareVer)) ;
      

      /* Decode INFO Fields */
        info_fields = num_of_info_elements(*pMsgBuf) ;
//        printf("No. of info fields : %d\n", info_fields) ;
    
        if (info_fields == 0) {
  //          printf("No info fields in this message\n") ;
//        printf("End of message\n") ;
      } /* if */
      
          break ;
    } /* IPOSRFM_MSG_FILE_TR_RESP */

        case IPOSRFM_MSG_TRN_COMP_RESP : {

        printf("Transfer Complete\n") ;

      trnCompRespStruct = (iposrfm_transfer_complete_resp *) pStructBuf ;

        /* Ctrl Header */
          size = decodeCtrlHeader(pMsgBuf, &(trnCompRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

         
        /* INFO FIELDS */
       info_fields = num_of_info_elements(*pMsgBuf) ;
//       printf("No. of info fields : %d\n", info_fields) ;
    
       if (info_fields == 0) {
  //         printf("No info fields in this message\n") ;
//       printf("End of message\n") ;
     } else {
    
           infotypebyte = *pMsgBuf ;
       pMsgBuf += 1 ;

          if (infotypebyte & TRANSFER_INFO) {
            ret_val = decodeTransferInfo(pMsgBuf, &(trnCompRespStruct->transferInfo)) ;
      pMsgBuf += ret_val ;
      } /* if */

      size += ret_val ;

          if (infotypebyte & FILE_INFO) {
            ret_val = decodeFileInfo(pMsgBuf, &(trnCompRespStruct->rcvedFile)) ;
            pMsgBuf += ret_val ;
      } /* if */

           size += ret_val ;

     } /* if */

    break ;
     } /* IPOS_RFM_MSG_TRN_COMP_RESP */

        case IPOSRFM_MSG_TRN_ABORT_RESP : {
          
          trnAbortRespStruct = (iposrfm_transfer_abort_resp *) pStructBuf ;

      size = decodeCtrlHeader(pMsgBuf, &(trnAbortRespStruct->ctrlHdr)) ;
          pMsgBuf += size ;

        info_fields = num_of_info_elements(*pMsgBuf) ;
//        printf("No. of info fields : %d\n", info_fields) ;
    
        if (info_fields == 0) {
//            printf("No info fields in this message\n") ;
//        printf("End of message\n") ;
      } /* if */
        pMsgBuf += 1 ;

          break ;
    } /* IPOSRFM_MSG_TRN_ABORT_RESP */
#endif

  } /* switch */

    return IPOS_SUCCESS ;

} /* iposRFMMsg2Struct() */
