/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                 */
/* file: aUEI.h                                                    */
/*                                                                 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                 */
/* description: UEI processing utilities.                          */
/*                                                                 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                 */
/* Copyright (c) 2018 Acroname Inc. - All Rights Reserved          */
/*                                                                 */
/* This file is part of the BrainStem release. See the license.txt */
/* file included with this package or go to                        */
/* https://acroname.com/software/brainstem-development-kit         */
/* for full license details.                                       */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef _aUEI_H_
#define _aUEI_H_

#include "aDefs.h"
#include "aPacket.h"

/////////////////////////////////////////////////////////////////////
/// UEI Utilities.

/** \defgroup aUEI UEI Utilities
 * \ref aUEI "aUEI.h" Provides structs and utilities for working with UEIs.
 */

/// Typedef Enum #dataType 

/**
 * UEI datatype
 */
typedef enum {
    aUEI_VOID = 0, ///< Void datatype.
    aUEI_BYTE = 1, ///< Char datatype.
    aUEI_SHORT = 2, ///< Short datatype.
    aUEI_INT = 4, ///< Int datatype.
    aUEI_BYTES = 5, ///< Bytes datatype 
} dataType;

/// Typedef Struct #uei

/**
 * UEI data struct.
 */
typedef struct {
    uint8_t module; ///< Module address.
    uint8_t command; ///< Command code.
    uint8_t option; ///< option code & UEI operation.
    uint8_t specifier; ///< Entity index & response specifier.
    union { 
        uint8_t byteVal; ///< Char value union member.
        uint16_t shortVal; ///< Short value union member.
        uint32_t intVal; ///< Int value union member.
        struct {
            uint8_t* bufPtr;
            uint8_t sequenceNumber;
            bool continueBit;
            size_t bufLength;
            size_t* unloadedLength;
        } bytes;
    } v;
    
    dataType type; ///< Union dataType.
} uei;


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

    /// Retrieve a short from a UEI.

    /**
     * \param p Pointer to byte array containing short.
     * \return uint16_t The short value.
     */
    aLIBEXPORT uint16_t aUEI_RetrieveShort(const uint8_t* p);

    /// Store a short in a UEI.

    /**
     * \param p Pointer to uei shortVal.
     * \param v Short value to store.
     */
    void aUEI_StoreShort(uint8_t* p, uint16_t v);
    
    /// Retrieve an Int from a UEI.

    /**
     * \param p Pointer to byte array containing the Int.
     * \return uint32_t The integer value.
     */
    aLIBEXPORT uint32_t aUEI_RetrieveInt(const uint8_t* p);
    
    /// Store an Int in a UEI.

    /** 
     * \param p Pointer to the IntVal of a UEI.
     * \param v The value to store.
     */
    void aUEI_StoreInt(uint8_t* p, uint32_t v);
    
    /// Modifies a buffer of sequential ints from a starting location.
    /// This conversion is done in place. This is a destructive action.
    
    /**
     * \param buf Pointer to byte array containing the Ints.
     * \param len Number of sequential Ints to convert.
     */
    aLIBEXPORT void aUEI_ModifyIntBuffer(uint32_t* buf, const size_t len);
    
    /// Retrieve sequence number from a BrainStem Packet

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return uint8_t The sequence number.
     */
    aLIBEXPORT uint8_t aUEI_getBytesSequence(const aPacket* packet);

    /// Retrieve continue bit from a BrainStem Packet

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return bool The value if continue is set or not.
     */
    aLIBEXPORT bool aUEI_getBytesContinue(const aPacket* packet);

    /// Determine if packet is a full UEI Bytes packet

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return bool If the packet is considered full
     */
    aLIBEXPORT bool aUEI_getBytesFullPacket(const aPacket* packet);

    /// Determines if a BrainStem packet is a UEI payload

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return bool The value if the payload is UEI or not
     */
    aLIBEXPORT bool aUEI_isUEIPayload(const aPacket* packet);

    /// Determines if a BrainStem packet is NOT a UEI payload

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return bool The value if the payload is UEI or not
     */
    aLIBEXPORT bool aUEI_isNotUEIPayload(const aPacket* packet);

    /// Determines if a BrainStem packet is a stream payload

    /**
     * \param packet Pointer to a BrainStem packet.
     * \return bool The value if the payload is a stream payload or not
     */
    aLIBEXPORT bool aUEI_isStreamPacket(const aPacket* packet);

    
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif // _aReflex_H_
