/////////////////////////////////////////////////////////////////////
//                                                                 //
// file: Link_CCA.h
//                                                                 //
/////////////////////////////////////////////////////////////////////
//                                                                 //
// Copyright (c) 2024 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 __Link_CCA_H__
#define __Link_CCA_H__

#include "CCA_Core.h"
#include "aPacket.h"

#ifdef CCA_PACK
    #pragma pack(push, CCA_PACK)
#endif
    /** CCA linkSpec structure - It contains the necessary information for connecting to a BrainStem
     *  module. */
    struct linkSpec_CCA {
        unsigned int type;/**< The transport type of this spec. */
        unsigned int serial_num;/**< The serial number of the module */
        unsigned int module;/**< The module address */
        unsigned int router;/**< The BrainStem network router address */
        unsigned int router_serial_num;/**< The BrainStem network router serial number */
        unsigned int model;/**< The model type */

        unsigned int usb_id;/**< The usb_id of the BrainStem module. */

        unsigned int ip_address;/**< The IP4 address of the module. */
        unsigned int ip_port;/**< The TCP port for socket connection on the module. */

        unsigned int baudrate;/**< The serial port baudrate */
        char port[100];/**< The serial port path or name */
    };

    /** StreamStatusEntry structure - It contains members of streaming entries
    * in the form of key value pairs. Keys are comprised of the devices module address,
    *  command, option, index, and subindex API values. */
    struct StreamStatusEntry_CCA {
        unsigned long long key; /**< The stream key (64bit).*/
        unsigned int value;     /**< The value associated with the key (32bit). */
    };

#ifdef CCA_PACK
    #pragma pack(pop)
#endif

/// \defgroup LinkEntity Link Entity
/// The Link class provides link level access to streaming information. 

#ifdef __cplusplus
extern "C" {
#endif

    //Function signature for streaming callbacks.
    /// \param p reference to streaming packet
    /// \param pRef User provided reference
    /// \return non zero error code on failure.
    /// Return value is not currently used.
    typedef unsigned char(*cStreamCallback_t)(const struct aPacket* p, void* pRef);

    /// Enables streaming for the supplied criteria.
    /// \param id Unique identifier for the internally created stem.
    /// \param result object, containing NO_ERROR or a non zero Error code.
    /// \param moduleAddress Address to filter on.
    /// \param cmd cmd to filter by (supports Wildcards)
    /// \param option option to filter by (supports Wildcards)
    /// \param index index to filter by (supports Wildcards)
    /// \param enable True - Enables streaming; False - disables streaming
    aLIBEXPORT void __stdcall link_enableStream(unsigned int* id,
                                                struct Result* result,
                                                const unsigned char moduleAddress,
                                                const unsigned char cmd,
                                                const unsigned char option,
                                                const unsigned char index,
                                                const bool enable);

    /// Get linkSpecifier
    /// \param id Unique identifier for the internally created stem.
    /// \param result object, containing NO_ERROR or a non zero Error code.
    /// \param spec - allocated linkspec struct will be filled with spec.
    aLIBEXPORT void __stdcall link_getLinkSpecifier(unsigned int* id, struct Result* result, struct linkSpec_CCA* spec);


    /// Registers a callback function based on a specific module, cmd, option, and index.
    /// \param id Unique identifier for the internally created stem.
    /// \param result object, containing NO_ERROR or a non zero Error code.
    /// \param cmd cmd to filter by (supports Wildcards)
    /// \param option option to filter by (supports Wildcards)
    /// \param index index to filter by (supports Wildcards)
    /// \param enable True - installs/updates callback and ref; False - uninstalls callback
    /// \param cb Callback to be executed when a new packet matching the criteria is received.
    /// \param pRef Pointer to user reference for use inside the callback function.
    /// \details ::aErrNotFound - Item not found (uninstalling only)
    /// \details ::aErrNone - success
    aLIBEXPORT void __stdcall link_registerStreamCallback(
                                  unsigned int* id,
                                  struct Result* result,
                                  const unsigned char moduleAddress,
                                  const unsigned char cmd,
                                  const unsigned char option,
                                  const unsigned char index,
                                  const bool enable,
                                  cStreamCallback_t cb,
                                  void* pRef);


    /// Gets all available stream values based on the search criteria.
    /// \param id Unique identifier for the internally created stem.
    /// \param result object, containing NO_ERROR or a non zero Error code.
    /// \param moduleAddress Address to filter on (supports Wildcards)
    /// \param cmd cmd to filter by (supports Wildcards)
    /// \param option option to filter by (supports Wildcards)
    /// \param index index to filter by (supports Wildcards)
    /// \param subindex subindex to filter by (supports Wildcards)
    /// \param buffer Buffer of user allocated memory to be filled with stream data
    ///     Note: Link::getStreamKeyElement should be used to decode the keys
    /// \param bufferLength Number of elements the buffer can hold.
    /// \details ::aErrParam if status or unloadedSize is null
    /// \details ::aErrNone - success
    aLIBEXPORT void __stdcall link_getStreamStatus(unsigned int* id,
                                                   struct Result* result,
                                                   const unsigned char moduleAddress,
                                                   const unsigned char cmd,
                                                   const unsigned char option,
                                                   const unsigned char index,
                                                   const unsigned char subindex,
                                                   struct StreamStatusEntry_CCA* buffer,
                                                   const unsigned int bufferLength);

    /// Convenience function to unpack a stream key.
    /// \param key The key to be unpacked
    /// \param element The element to unpack from the key.
    aLIBEXPORT void __stdcall link_getStreamKeyElement(struct Result* result,
                                                       const unsigned long long key,
                                                       const unsigned char element);
    
#ifdef __cplusplus
}
#endif
#endif
