/*                                                                      tab:4
 *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By
 *  downloading, copying, installing or using the software you agree to
 *  this license.  If you do not agree to this license, do not download,
 *
 */
/*                                                                      tab:4
 * "Copyright (c) 2000-2003 The Regents of the University  of California.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
/*                                                                      tab:4
 * Copyright (c) 2003 Intel Corporation
 * All rights reserved Contributions to the above software program by Intel
 * Corporation is program is licensed subject to the BSD License, available at
 * http://www.opensource.org/licenses/bsd-license.html
 *
 */
/*
 * Authors:	Mark Yarvis, Nandu Kushalnagar, Jasmeet Chhabra
 *
 */

#define AODV_RREQ 1
#define AODV_RREP 2
#define AODV_RRER 3
#define AODV_RREP_ACK 4
#define SAODV_RREQ_SINGLE_SIGNATURE_EXTENSION 64
#define SAODV_RREP_SINGLE_SIGNATURE_EXTENSION 65
#define SAODV_RREQ_DOUBLE_SIGNATURE_EXTENSION 66
#define SAODV_RREP_DOUBLE_SIGNATURE_EXTENSION 67
#define SAODV_RERR_SIGNATURE_EXTENSION 68
#define SAODV_RERR_ack_SIGNATURE_EXTENSION 69
#define SAODV_HELLO 70
#define SAKM_DADD 64
#define SAKM_NADD 65
#define SAKM_NADD_ACK 66

#define DEFAULT_TTL 25 
#define DEFAULT_MAX_HOP_COUNT 25
 
 
// active message id's are used to distinguish single-hop messages
enum {
   AM_ID_FLOOD = 2,  // FLOOD data packet

   AM_ID_DSDV = 3,        // DSDV data packet
   AM_ID_DSDV_SOI = 4,    // DSDV data packet with source sphere id

   AM_ID_DSDV_RUPDATE_HOPS = 5,    // DSDV rupdate with hop count metric
   AM_ID_DSDV_RUPDATE_QUALITY = 6, // DSDV rupdate with quality metric
   AM_ID_DSDV_RUPDATE_SOI = 7,     // DSDV rupdate with SoI metric
   AM_ID_DSDV_RUPDATE_CLUSTER = 9, // DSDV rupdate with clustering

   AM_ID_DSDV_RUPDATE_REQ = 8,  // DSDV rupdate request

   AM_ID_AODV = 9,         // AODV data packet


   AM_ID_AODV_RREQ = 10,   // AODV route request
   AM_ID_AODV_RREPLY = 11,   // AODV route reply  
   AM_ID_AODV_RERR = 12,   // AODV route reply  

   AM_ID_AODV_RREQ_HOPS = 13,
   AM_ID_AODV_RREPLY_HOPS = 14,
   AM_ID_AODV_RERR_HOPS = 15,
   
   AM_ID_AODV_DADD = 16, 
   AM_ID_AODV_NADD = 17, 
   AM_ID_AODV_NADD_ACK = 18,
   AM_ID_AODV_DADD_HOPS = 19,
   AM_ID_AODV_NADD_HOPS = 20,
   AM_ID_AODV_NADD_ACK_HOPS = 21
};

// application id's are used to distinguish multi-hop messages
enum {
   APP_ID_SETTINGS = 2,
   APP_ID_TRACEROUTE = 3,
   APP_ID_TRACEROUTE_SOI = 4,
   APP_ID_SOURCEROUTE =5,
   APP_ID_AODV_TEST = 6
};

typedef struct {
   wsnAddr src;
   uint8_t seq;
   uint8_t data[1]; // start of payload; size is not known at compile time
} SHop_Msg;

typedef SHop_Msg *SHop_MsgPtr;

typedef struct {
   wsnAddr src;
   wsnAddr dest;
   uint8_t app;
   wsnAddr length;
} MHop_Header;

typedef struct {
   MHop_Header mhop;
   uint8_t seq;
   uint8_t ttl;
   uint8_t data[1]; // start of payload; size is not known at compile time
} Flood_Msg;

typedef Flood_Msg *Flood_MsgPtr;

typedef struct {
   MHop_Header mhop;
   uint8_t seq;
   uint8_t ttl;
   uint8_t data[1]; // start of payload; size is not known at compile time
} DSDV_Msg;

typedef DSDV_Msg *DSDV_MsgPtr;

typedef struct {
   wsnAddr dest;
   uint8_t seq;
   uint8_t metric[1];  // space for the metric(s) and piggyback info
} DSDV_Rupdate_Msg;

typedef DSDV_Rupdate_Msg *DSDV_Rupdate_MsgPtr;


typedef struct {
   MHop_Header mhop;
   uint8_t seq;
   uint8_t ttl;
   uint8_t data[1]; // start of payload; size is not known at compile time
} AODV_Msg;

typedef AODV_Msg *AODV_MsgPtr;

typedef struct {
	uint8_t type;
	uint16_t jrgdu_and_reserved;
	uint8_t metric[1]; //also  known as hop count
	uint32_t rreqID;
	wsnAddr dest;
	uint32_t destSeq; // seq# last received from the destination by the source
	wsnAddr src;
	uint32_t srcSeq;   // seq# used for storing entries back to the source
	uint8_t data[1];  
} AODV_Rreq_Msg;

typedef struct{
	uint8_t type;
  	uint16_t jrgdu_and_reserved; 
	uint8_t metric[1]; //also  known as hop count
	uint32_t rreqID;
	wsnAddr dest;
	uint32_t destSeq; // seq# last received from the destination by the source
	wsnAddr src;
	uint32_t srcSeq;   // seq# used for storing entries back to the source  

	uint8_t type_extension;
	uint8_t length;
	uint8_t hash_function;
	uint8_t maxHopCount;
	uint32_t publicKey[2];
	uint8_t data[1];

}SAODV_Rreq_Msg;

typedef struct {
	uint8_t type;
	uint16_t jrgdu_and_reserved;
	uint8_t metric[1]; //also  known as hop count
	uint32_t rreqID;
	wsnAddr dest;
	uint32_t destSeq; // seq# last received from the destination by the source
	wsnAddr src;
	uint32_t srcSeq;   // seq# used for storing entries back to the source 
	uint8_t type_extension;
	uint8_t length;
	uint8_t hash_function;
	uint8_t maxHopCount;
	uint32_t publicKey[2];
	uint32_t topHash[5];
	uint32_t hash[5];  
	uint8_t signMethod;
	uint8_t h_and_reserved;
	uint8_t paddLength;
	
	uint32_t padding[1];
	uint32_t signature[5];

	uint8_t data[1];
} SAODV_Rreq_Single_Signature_Extension_Msg;

typedef struct {
	uint8_t type;
	uint16_t jrgdu_and_reserved;
	uint8_t metric[1]; //also  known as hop count
	uint32_t rreqID;
	wsnAddr dest;
	uint32_t destSeq; // seq# last received from the destination by the source
	wsnAddr src;
	uint32_t srcSeq;   // seq# used for storing entries back to the source 
	uint8_t type_extension; 
	uint8_t length;
	uint8_t hash_function;
	uint8_t maxHopCount;
	uint32_t publicKey[2];
	uint32_t reserved_and_PrefixSize;
	uint32_t topHash[5];
	uint32_t hash[5];
	uint8_t signMethod;
	uint8_t h_and_reserved;
	uint8_t paddLength;
	
	uint32_t padding[1];
	uint32_t signatureRREP[5];
	uint32_t signature[5];
	uint8_t data[1];   
} SAODV_Rreq_Double_Signature_Extension_Msg;

typedef AODV_Rreq_Msg* AODV_Rreq_MsgPtr;
typedef SAODV_Rreq_Msg* SAODV_Rreq_MsgPtr;
typedef SAODV_Rreq_Single_Signature_Extension_Msg* SAODV_Rreq_Single_Signature_MsgPtr;
typedef SAODV_Rreq_Double_Signature_Extension_Msg* SAODV_Rreq_Double_Signature_MsgPtr;

typedef struct {
  uint8_t type;
  uint16_t ra_reserved_and_prefix_size;
  uint8_t metric[1]; //also  known as hop count
  
  wsnAddr dest;
  uint16_t destSeq;
  wsnAddr src;
  uint32_t lifetime;
  

  uint8_t data[1];  
} AODV_Rreply_Msg;

typedef struct {
  uint8_t type;
  uint16_t ra_reserved_and_prefix_size;
  uint8_t metric[1]; 
  wsnAddr dest;
  uint16_t destSeq;
  wsnAddr src;
  uint32_t lifetime;
  uint8_t type_extension;
  uint8_t length;
  uint8_t hash_function;
  uint8_t maxHopCount;
  uint32_t topHash[5];
  uint8_t signMethod;
  uint16_t H_and_Reserved;
  uint8_t paddLength;
  uint32_t publicKey[2];
  uint32_t padding[1];
  uint32_t signature[2];
  uint8_t data[1];
} SAODV_Rreply_Msg;




typedef struct {
  uint8_t type;
  uint16_t ra_reserved_and_prefix_size;
  uint8_t metric[1];
  wsnAddr dest;
  uint16_t destSeq;
  wsnAddr src;
  uint32_t lifetime;
  uint8_t type_extension;
  uint8_t length;
  uint8_t hash_function;
  uint8_t maxHopCount;
  uint32_t topHash[5];
  uint32_t hash[5];
  uint8_t signMethod;
  uint16_t H_and_Reserved;
  uint8_t paddLength;
  uint32_t publicKey[2];
  uint32_t padding[1];
  uint32_t signature[2];
  uint8_t data[1];
} SAODV_Rreply_Single_Signature_Extension_Msg;

typedef struct {
  uint8_t type;
  uint16_t ra_reserved_and_prefix_size;
  uint8_t metric[1]; 
  wsnAddr dest;
  uint16_t destSeq;
  wsnAddr src;
  uint32_t lifetime;
  uint8_t type_extension;
  uint8_t length;
  uint8_t hash_function;
  uint8_t maxHopCount;
  uint32_t topHash[5];
  uint32_t hash[5];
  uint8_t signMethod;
  uint16_t H_and_Reserved;
  uint8_t paddLength;
  uint32_t publicKey[2];
  uint32_t padding[1];
  uint32_t signature[2];
  //uint32_t oldLifetime; Uncomment when TinyOs supports msg_size > 120
  uint32_t oldOriginatorIPAddress;
  uint8_t signMethod2;
  //uint8_t H_and_Reserved2; Uncomment when TinyOs supports msg_size > 120
  uint8_t paddLength2;
  uint32_t publicKey2[2];
  //uint32_t padding2[1];Uncomment when TinyOs supports msg_size > 120 
  uint32_t signature2[2];
  
  uint8_t data[1];
} SAODV_Rreply_Double_Signature_Extension_Msg;

typedef AODV_Rreply_Msg* AODV_Rreply_MsgPtr;
typedef SAODV_Rreply_Msg* SAODV_Rreply_MsgPtr;
typedef SAODV_Rreply_Single_Signature_Extension_Msg* SAODV_Rreply_Single_Signature_MsgPtr;
typedef SAODV_Rreply_Double_Signature_Extension_Msg* SAODV_Rreply_Double_Signature_MsgPtr;


typedef struct {
  uint8_t type;
  uint16_t n_and_reserved;
  uint8_t destCount;
  wsnAddr dest;
  uint16_t destSeq;
  wsnAddr dest2;
  uint32_t destSeq2;
  uint8_t data[1];
} AODV_Rerr_Msg;

typedef struct {
	uint8_t type;
	uint16_t n_and_reserved;
	uint8_t destCount;
	wsnAddr dest;
	uint32_t destSeq;
	wsnAddr dest2;
	uint32_t destSeq2;
	uint8_t type_extension;
	uint8_t length;
	uint16_t reserved;
	uint8_t signMethod;
	uint16_t h_and_reserved;
	uint8_t paddLength;
	uint32_t publicKey[2];
	uint32_t padding[1];
	uint32_t signature[5];
	uint8_t data[1];
} SAODV_Rerr_Signature_Extension_Msg;

typedef struct {
	uint8_t type;
	uint8_t reserved;
	uint8_t  type_extension;
	uint8_t length;
	uint16_t H_and_reserved;
	uint8_t paddLength;
	uint32_t publicKey[2];
	uint8_t padding[1];
	uint32_t signature[2];
	uint8_t data[1];
}SAODV_Rrep_Ack_Signature_Extension_Msg;

typedef AODV_Rerr_Msg* AODV_Rerr_MsgPtr; 
typedef SAODV_Rerr_Signature_Extension_Msg* SAODV_Rerr_Signature_Extension_MsgPtr; 
typedef SAODV_Rrep_Ack_Signature_Extension_Msg* SAODV_Rrep_Signature_Extension_MsgPtr; 

typedef struct {
	uint8_t type;
	uint8_t length;
	uint16_t h_and_reserved;
	wsnAddr duplicated_node_ip_address[1];
 	uint32_t duplicated_node_public_key[2];
	uint8_t data[1];
} SAKM_Dadd_Msg;

typedef SAKM_Dadd_Msg* SAKM_Dadd_MsgPtr; 

typedef struct {
	uint8_t type;
	uint8_t length;
	uint16_t reserved;
	uint8_t signMethod;
	uint16_t h_and_reserved;
	uint8_t paddLength;
	uint32_t oldpublicKey[2];
	uint32_t padding[1];
	uint8_t signMethod2;
	uint16_t h_and_reserved2;
	uint8_t paddLength2;
	uint32_t publicKey[2];
	uint32_t padding2[1];
	uint32_t signature_old_key[5];
	uint32_t signature_new_key[5];
	wsnAddr old_ip;
	wsnAddr new_ip;
	uint8_t data[1];
} SAKM_Nadd_Msg;

typedef SAKM_Nadd_Msg* SAKM_Nadd_MsgPtr; 

typedef struct{
	uint8_t type;
	uint8_t length;
	uint16_t reserved;
	uint32_t old_ip;
	uint32_t new_ip;
	uint8_t signMethod;
	uint16_t h_and_reserved;
	uint8_t paddLength;
	uint32_t publicKey[2];
	uint32_t padding[1];
	uint32_t signature[5];
	uint8_t data[1];
}SAKM_Nadd_ack_Msg;

typedef SAKM_Nadd_ack_Msg* SAKM_Nadd_ack_MsgPtr;


enum {
   SHOP_HEADER_LEN = offsetof(SHop_Msg, data),
   FLOOD_HEADER_LEN = offsetof(Flood_Msg, data),
   DSDV_HEADER_LEN = offsetof(DSDV_Msg, data),
   AODV_HEADER_LEN = offsetof(AODV_Msg, data), //temp stuff
   AODV_RREQ_HEADER_LEN   = offsetof(AODV_Rreq_Msg, data),
   SAODV_RREQ_HEADER_LEN   = offsetof(SAODV_Rreq_Msg, data),
   AODV_RREPLY_HEADER_LEN = offsetof(SAODV_Rreply_Msg, data),
   AODV_RERR_HEADER_LEN = offsetof(AODV_Rerr_Msg, data),
   SAODV_RREQ_SINGLE_HEADER_LEN   = offsetof(SAODV_Rreq_Single_Signature_Extension_Msg, data),
   SAODV_RREQ_DOUBLE_HEADER_LEN   = offsetof(SAODV_Rreq_Double_Signature_Extension_Msg, data),
   SAODV_RREPLY_SINGLE_HEADER_LEN = offsetof(SAODV_Rreply_Single_Signature_Extension_Msg, data),
   SAODV_RREPLY_DOUBLE_HEADER_LEN = offsetof(SAODV_Rreply_Double_Signature_Extension_Msg, data),
   SAODV_RERR_HEADER_LEN = offsetof(SAODV_Rerr_Signature_Extension_Msg, data),
   SAODV_RREP_ACK_HEADER_LEN=offsetof(SAODV_Rrep_Ack_Signature_Extension_Msg, data),
   DSDV_RUPDATE_HEADER_LEN = offsetof(DSDV_Rupdate_Msg, metric),
   SAKM_DADD_HEADER_LEN=offsetof(SAKM_Dadd_Msg, data),
   SAKM_NADD_HEADER_LEN=offsetof(SAKM_Nadd_Msg, data),
   SAKM_NADD_ACK_HEADER_LEN=offsetof(SAKM_Nadd_ack_Msg, data)
   //   AODV_RUPDATE_HEADER_LEN = offsetof(AODV_Rupdate_Msg, metric) //temp stuff
};




/*


enum {
   
   
};


*/
