// *******************************************************************
// * green-power-server.h
// *
// *
// * Copyright 2014 by Silicon Laboratories. All rights reserved.           *80*
// *******************************************************************
#ifndef _SILABS_GREEN_POWER_SERVER_H_
#define _SILABS_GREEN_POWER_SERVER_H_

#ifndef EMBER_AF_PLUGIN_GREEN_POWER_SERVER_CUSTOMIZED_GPD_TRANSLATION_TABLE_SIZE
#define EMBER_AF_PLUGIN_GREEN_POWER_SERVER_CUSTOMIZED_GPD_TRANSLATION_TABLE_SIZE (20)
#endif

#ifndef EMBER_AF_PLUGIN_GREEN_POWER_SERVER_TRANSLATION_TABLE_SIZE
#define EMBER_AF_PLUGIN_GREEN_POWER_SERVER_TRANSLATION_TABLE_SIZE 30
#endif

#define EMBER_AF_PLUGIN_GREEN_POWER_SERVER_ADDITIONALINFO_TABLE_SIZE EMBER_AF_PLUGIN_GREEN_POWER_SERVER_TRANSLATION_TABLE_SIZE

#define EMBER_AF_GREEN_POWER_SERVER_TRANSLATION_TABLE_ENTRY_ZCL_PAYLOAD_LEN (7)

// Key Types for MIC Calculations
#define EMBER_AF_GREEN_POWER_GP_SHARED_KEY 0
#define EMBER_AF_GREEN_POWER_GP_INDIVIDUAL_KEY 1
// defines macros for Gpd To Zcl Cmd Mapping Payload Src
#define  EMBER_AF_GREEN_POWER_ZCL_PAYLOAD_SRC_PRECONFIGURED 1
#define  EMBER_AF_GREEN_POWER_ZCL_PAYLOAD_SRC_NA 2
#define  EMBER_AF_GREEN_POWER_ZCL_PAYLOAD_SRC_GPD_CMD 4

#define GP_TRANSLATION_TABLE_STATUS_SUCCESS 0x00
#define GP_TRANSLATION_TABLE_STATUS_FAILED 0xFF
#define GP_TRANSLATION_TABLE_STATUS_FULL   0xFE
#define GP_TRANSLATION_TABLE_STATUS_EMPTY  0xFD
#define GP_TRANSLATION_TABLE_STATUS_ENTRY_EMPTY 0xFC
#define GP_TRANSLATION_TABLE_STATUS_ENTRY_NOT_EMPTY 0xFB
#define GP_TRANSLATION_TABLE_STATUS_PARAM_DOES_NOT_MATCH 0xFA
#define GP_TRANSLATION_TABLE_STATUS_CUSTOMIZED_TABLE_FULL  0xF9

#define GREEN_POWER_SERVER_TRANSLATION_TABLE_SUB_TABLE_DEFAULT_SIZE (70)
#define GREEN_POWER_SERVER_TRANSLATION_TABLE_SUB_TABLE_SIZE (EMBER_AF_PLUGIN_GREEN_POWER_SERVER_CUSTOMIZED_GPD_TRANSLATION_TABLE_SIZE + GREEN_POWER_SERVER_TRANSLATION_TABLE_SUB_TABLE_DEFAULT_SIZE)

typedef uint8_t emGpTableType;
enum {
  NO_ENTRY,
  DEFAULT_TABLE_ENTRY,
  CUSTOMIZED_TABLE_ENTRY,
}; //EmGpTableType

enum {
  ADD_PAIRED_DEVICE = 1,
  DELETE_PAIRED_DEVICE = 1,
  TRANSLATION_TABLE_UPDATE = 2,
  ADD_PAIRED_SWITCH_DEVICE = 2,
}; //IncommingReqType

typedef struct {
  uint8_t applicationId;
  uint8_t additionalInfoBlockPresent;
} GpTranslationTableOptionField;

typedef struct {
  bool inCommissioningMode;
  bool proxiesInvolved;
  uint8_t endpoint;
} EmberAfGreenPowerServerCommissioningState;

typedef struct {
  uint8_t       switchType;
  uint8_t       nbOfIdentifiedContacts;
  uint8_t       nbOfTTEntriesNeeded;
  uint8_t       indicativeBitmask;
}EmGpSwitchTypeData;

typedef struct {
  // used by generic switch and multi-sensor, for example
  //at present 3 entries comapct attrubte reporting, vector press & vector Release
  EmberGpTranslationTableAdditionalInfoBlockOptionRecordField additionalInfoBlock[EMBER_AF_PLUGIN_GREEN_POWER_SERVER_ADDITIONALINFO_TABLE_SIZE];
  uint8_t validEntry[EMBER_AF_PLUGIN_GREEN_POWER_SERVER_ADDITIONALINFO_TABLE_SIZE];
  uint8_t totlaNoOfEntries;
}EmberGpTranslationTableAdditionalInfoBlockField;

typedef struct {
  bool            validEntry;
  uint8_t         gpdCommand;
  uint8_t         endpoint;
  uint16_t        zigbeeProfile;
  uint16_t        zigbeeCluster;
  uint8_t         serverClient;
  uint8_t         zigbeeCommandId;
  uint8_t         payloadSrc;

  // This is a Zigbee string.
  // If the Length sub-field of the ZigBee Command payload field is set to 0x00,
  // the Payload sub-field is not present, and the ZigBee command is sent without payload.
  //
  // If the Length sub-field of the ZigBee Command payload field is set to 0xff,
  // the Payload sub-field is not present, and the payload from the triggering
  // GPD command is to be copied verbatim into the ZigBee command.  If the Length
  // sub-field of the ZigBee Command payload field is set to 0xfe, the Payload
  //sub-field is not present, and the pay-load from the triggering GPD command
  //needs to be parsed. For all other values of the Length sub-field,
  //the Payload sub-field is present, has a length as defined in the Length
  //sub-field and specifies the pay-load to be used.
  uint8_t zclPayloadDefault[EMBER_AF_GREEN_POWER_SERVER_TRANSLATION_TABLE_ENTRY_ZCL_PAYLOAD_LEN];
} EmberAfGreenPowerServerGpdSubTranslationTableEntry;

typedef struct {
  bool            infoBlockPresent;
  uint8_t         gpdCommand;
  uint8_t         zbEndpoint;
  uint8_t         offset;
  emGpTableType   entry;
  EmberGpAddress  gpAddr;
  EmberGpApplicationId gpApplicationId;
  uint8_t         additionalInfoOffset;
} EmGpCommandTranslationTableEntry;

typedef struct {
  EmGpCommandTranslationTableEntry TableEntry[EMBER_AF_PLUGIN_GREEN_POWER_SERVER_TRANSLATION_TABLE_SIZE];
  uint8_t totalNoOfEntries;
}EmGpCommandTranslationTable;

typedef struct {
  uint8_t       endpoint;
  uint8_t       gpdCommand;
  uint16_t      zigbeeProfile;
} EmberAfGreenPowerServerMultiSensorTranslation;

typedef struct {
  EmGpSwitchTypeData  SwitchType;
  EmberAfGreenPowerServerGpdSubTranslationTableEntry genericSwitchDefaultTableEntry;
} EmberAfGreenPowerServerDefautGenericSwTranslation;

// print to cli the customized translation table entries
void emberAfPluginGreenPowerServerTablePrint(void);
void emberAfPluginGreenPowerServerClearSinkTable(void);
EmGpCommandTranslationTable * emGpTransTableGetTranslationTable(void);
uint8_t emGpTransTableGetFreeEntryIndex(void);
void emGpTransTableClearTranslationTable(void);
uint8_t emGpTransTableGetTranslationTableEntry (uint8_t entryIndex,
                                                EmberAfGreenPowerServerGpdSubTranslationTableEntry *TranslationTableEntry);
uint8_t emGpTransTableDeletePairedDevicefromTranslationTableEntry(bool infoBlockPresent,
                                                                  uint8_t gpApplicationId,
                                                                  uint32_t  gpdSrcId,
                                                                  uint8_t *SourceId,
                                                                  uint8_t gpdEndpoint,
                                                                  uint8_t gpdCommandId,
                                                                  uint8_t ZbEndpoint,
                                                                  uint16_t zigbeeProfile,
                                                                  uint16_t zigbeeCluster,
                                                                  uint8_t  zigbeeCommandId);
uint8_t emGpTransTableAddPairedDeviceToTranslationTable(uint8_t IncomingReqType,
                                                        bool infoBlockPresent,
                                                        uint8_t gpApplicationId,
                                                        uint32_t  gpdSrcId,
                                                        uint8_t *SourceId,
                                                        uint8_t gpdEndpoint,
                                                        uint8_t gpdCommandId,
                                                        uint8_t ZbEndpoint,
                                                        uint16_t zigbeeProfile,
                                                        uint16_t zigbeeCluster,
                                                        uint8_t  zigbeeCommandId,
                                                        uint8_t payloadLength,
                                                        uint8_t* payload,
                                                        uint8_t payloadSrc,
                                                        uint8_t additionalInfoLength,
                                                        EmberGpTranslationTableAdditionalInfoBlockOptionRecordField* AdditionalInfoBlock,
                                                        uint8_t* outNewTTEntryIndex);
uint8_t emGpTransTableFindMatchingTranslationTableEntry(uint8_t levelOfScan,
                                                        bool infoBlockPresent,
                                                        uint8_t gpApplicationId,
                                                        uint32_t gpdSrcId,
                                                        uint8_t *SourceId,
                                                        uint8_t gpdEndpoint,
                                                        uint8_t gpdCommandId,
                                                        uint8_t ZbEndpoint,
                                                        uint8_t * GpdCmdPayload,
                                                        uint8_t *OutIndex,
                                                        uint8_t startSearchIndex);
uint8_t emGpTransTableRemoveTranslationTableEntryUpdateCommand(uint8_t Index,
                                                               bool infoBlockPresent,
                                                               uint8_t gpApplicationId,
                                                               uint32_t  gpdSrcId,
                                                               uint8_t *SourceId,
                                                               uint8_t gpdCommandId,
                                                               uint8_t gpdEndpoint,
                                                               uint8_t ZbEndpoint,
                                                               uint16_t zigbeeProfile,
                                                               uint16_t zigbeeCluster,
                                                               uint8_t  zigbeeCommandId,
                                                               uint8_t payloadLength,
                                                               uint8_t* payload,
                                                               uint8_t payloadSrc,
                                                               uint8_t additionalInfoLength,
                                                               EmberGpTranslationTableAdditionalInfoBlockOptionRecordField* AdditionalInfoBlock);
uint8_t emGpTransTableReplaceTranslationTableEntryUpdateCommand(uint8_t Index,
                                                                bool infoBlockPresent,
                                                                uint8_t gpApplicationId,
                                                                uint32_t  gpdSrcId,
                                                                uint8_t *SourceId,
                                                                uint8_t gpdCommandId,
                                                                uint8_t gpdEndpoint,
                                                                uint8_t ZbEndpoint,
                                                                uint16_t zigbeeProfile,
                                                                uint16_t zigbeeCluster,
                                                                uint8_t  zigbeeCommandId,
                                                                uint8_t payloadLength,
                                                                uint8_t* payload,
                                                                uint8_t payloadSrc,
                                                                uint8_t additionalInfoLength,
                                                                EmberGpTranslationTableAdditionalInfoBlockOptionRecordField* AdditionalInfoBlock);
uint8_t emGpTransTableAddTranslationTableEntryUpdateCommand(uint8_t Index,
                                                            bool infoBlockPresent,
                                                            uint8_t gpApplicationId,
                                                            uint32_t  gpdSrcId,
                                                            uint8_t *SourceId,
                                                            uint8_t gpdCommandId,
                                                            uint8_t gpdEndpoint,
                                                            uint8_t ZbEndpoint,
                                                            uint16_t zigbeeProfile,
                                                            uint16_t zigbeeCluster,
                                                            uint8_t  zigbeeCommandId,
                                                            uint8_t payloadLength,
                                                            uint8_t* payload,
                                                            uint8_t payloadSrc,
                                                            uint8_t additionalInfoLength,
                                                            EmberGpTranslationTableAdditionalInfoBlockOptionRecordField* AdditionalInfoBlock);
uint16_t emGpCopyAdditionalInfoBlockArrayToStructure(uint8_t * additionalInfoBlockIn,
                                                     EmberGpTranslationTableAdditionalInfoBlockOptionRecordField * additionalInfoBlockOut,
                                                     uint8_t gpdCommandId);
void emberAfPluginGreenPowerServerProxyTableRequest(uint8_t requestType, uint32_t gpdId);
void emberAfPluginGreenPowerServerSinkTablePrint(void);
void emGpPrintAdditionalInfoBlock(uint8_t gpdCommand, uint8_t addInfoOffset);
// security function prototypes
bool emGpKeyTcLkDerivation(EmberGpAddress * gpdAddr,
                           uint32_t gpdSecurityFrameCounter,
                           uint8_t mic[4],
                           const EmberKeyData * linkKey,
                           EmberKeyData * key,
                           bool directionIncomming);
bool emGpCalculateIncomingCommandMic(EmberGpAddress * gpdAddr,
                                     uint8_t keyType,
                                     uint8_t securityLevel,
                                     uint32_t gpdSecurityFrameCounter,
                                     uint8_t gpdCommandId,
                                     uint8_t * gpdCommandPayload,
                                     bool encryptedPayload,
                                     uint8_t mic[4],
                                     EmberKeyData * key);
bool emGpCalculateIncomingCommandDecrypt(EmberGpAddress * gpdAddr,
                                         uint32_t gpdSecurityFrameCounter,
                                         uint8_t payloadLength,
                                         uint8_t * payload,
                                         EmberKeyData * key);
// zigbee device functions
EmberStatus emSendZigDevMessage(EmberNodeId destination,
                                PGM_P format, ...);
void emZigDevPrepareZdoMessage(EmberApsFrame *apsFrame,
                               uint16_t clusterId,
                               EmberApsOption options,
                               uint8_t sequence);
// gp security test function
void emGpTestSecurity(void);
void emGpTransTableClearTranslationTable(void);
void emGpSetTranslationTableEntry(uint8_t index);
EmberAfGreenPowerServerGpdSubTranslationTableEntry* emGpGetCustomizedTable(void);
void emGpClearCustomizedTable(void);
void emGpSetCustomizedTableEntry(uint8_t index);
EmberGpTranslationTableAdditionalInfoBlockField * emGpGetAdditionalInfoTable(void);
void embGpClearAdditionalInfoBlockTable(void);
void emGpSetAdditionalInfoBlockTableEntry(uint8_t index);
#endif //_GREEN_POWER_SERVER_H_
