Part of TI's mqtt

Dependents:   mqtt_V1 cc3100_Test_mqtt_CM3

server_plug.cpp

Committer:
dflet
Date:
2015-06-06
Revision:
0:547251f42a60

File content as of revision 0:547251f42a60:

/******************************************************************************
*
*   Copyright (C) 2014 Texas Instruments Incorporated
*
*   All rights reserved. Property of Texas Instruments Incorporated.
*   Restricted rights to use, duplicate or disclose this code are
*   granted through contract.
*
*   The program may not be used without the written permission of
*   Texas Instruments Incorporated or against the terms and conditions
*   stipulated in the agreement under which this program has been supplied,
*   and under no circumstances can it be used with non-TI connectivity device.
*
******************************************************************************/

#include "server_plug.h"
#include "server_core.h"
#include "server_util.h"

namespace mbed_mqtt {

#define MAX_PLUGINS            PG_MAP_MAX_ELEMS
#define PG_NAME_LEN            32

static struct plugin_desc {

        char                          *name;
        uint8_t                          index;
        uint8_t                          inuse;

        struct mqtt_server_app_cbs  app_cbs;

} plugins[MAX_PLUGINS];

#define PLUGIN(app_hnd) ((struct plugin_desc*) app_hnd)

static inline bool is_inuse(struct plugin_desc *plugin)
{
        return plugin->inuse? true : false;
}

static inline void inuse_set(struct plugin_desc *plugin, bool inuse)
{
        plugin->inuse = inuse? 0x01 : 0x00;
}

static struct plugin_desc *acl_pg = NULL;

static struct plugin_core_msg_cbs *msg_cbs, msg_cbacks = {NULL, NULL, NULL};

static inline struct plugin_desc *plugin_find(int32_t idx)
{
        return plugins + idx;
}

static void plugin_reset(struct plugin_desc *plugin)
{
        //plugin->app_cbs = NULL; ==> TBD
        inuse_set(plugin, false);

        return;
}

static struct plugin_desc *plugin_alloc(void)
{
        struct plugin_desc *plugin = NULL;;
        int32_t idx = 0;

        for(idx = 0; idx < MAX_PLUGINS; idx++) {
                plugin = plugins + idx;
                if(false == is_inuse(plugin)) {
                        inuse_set(plugin, true);
                        break;
                }
        }

        DBG_INFO("Plugin alloc %s\n\r",
                 (MAX_PLUGINS == idx)? "Failed" : "Success");

        return (MAX_PLUGINS != idx)? plugin : NULL;
}

#if  0
static void plugin_free(struct plugin_desc *plugin)
{
        plugin_reset(plugin);
}
#endif

uint16_t plugin_connect(const struct utf8_string *clientId,
                   const struct utf8_string *username,
                   const struct utf8_string *password,
                   void **app_usr)
{
        uint16_t rv = CONNACK_RC_REQ_ACCEPT; /* Accept everything from MQTT network */

        *app_usr = NULL;
        if(acl_pg)
                rv = acl_pg->app_cbs.connect(clientId, username,
                                             password, app_usr);

        return rv;
}

int32_t plugin_publish(uint8_t pg_map, const struct utf8_string *topic,
                   const uint8_t *payload, uint32_t pay_len,
                   bool dup, uint8_t qos, bool retain)
{
        int32_t i = 0;
        for(i = 0; i < MAX_PLUGINS; i++) {
                if(PG_MAP_HAS_VALUE(pg_map, i)) {
                        struct plugin_desc *plugin = plugin_find(i);

                        DBG_INFO("Publishing to Plugin ID: %d (%s)\n\r",
                                 plugin->index, plugin->name);
                        
                        if(false == is_inuse(plugin)) 
                                continue; /* Must not happen */
                        
                        plugin->app_cbs.publish(topic, payload, pay_len,
                                                dup, qos, retain);
                }
        }

        /* TBD for error value return. */

        return pay_len;
}

int32_t plugin_disconn(const void *app_usr, bool due2err)
{
        if(acl_pg)
                acl_pg->app_cbs.disconn(app_usr, due2err);

        /* TBD for error value return. */

        return 0;
}

int32_t mqtt_server_topic_enroll(const void *app_hnd, 
                             const struct utf8_string *topic, enum mqtt_qos qos)
{
        return  app_hnd? 
                msg_cbs->topic_enroll(PLUGIN(app_hnd)->index, topic, qos) : -1;
}

int32_t mqtt_server_topic_disenroll(const void *app_hnd, 
                                const struct utf8_string *topic)
{
        return  app_hnd?
                msg_cbs->topic_cancel(PLUGIN(app_hnd)->index, topic) : -1;
}

int32_t mqtt_server_app_pub_send(const  struct utf8_string *topic, 
                             const uint8_t *data_buf, uint32_t data_len,
                             enum mqtt_qos qos, bool retain)
{
        return msg_cbs->publish(topic, data_buf, data_len, qos, retain);
}

static void *server_app_register(const struct mqtt_server_app_cbs *cbs,
                                 const char *name)
{
        struct plugin_desc *plugin = plugin_alloc();
        if(NULL != plugin) {
                strncpy(plugin->name, name, PG_NAME_LEN - 1);
                memcpy(&plugin->app_cbs, cbs,
                       sizeof(struct mqtt_server_app_cbs));

                if((NULL == acl_pg) && cbs->connect)
                        acl_pg = plugin;

        }
        return plugin;
}

void *mqtt_server_app_register(const struct mqtt_server_app_cbs *cbs,
                               const char *name)
{
        if((NULL == cbs)                         || 
           ((!!cbs->connect) ^ (!!cbs->disconn)) ||
           (acl_pg && cbs->connect))
                return NULL;

        return server_app_register(cbs, name);
}

static bool inited = false;

int32_t plugin_init(const struct plugin_core_msg_cbs *cbs)
{
        int32_t idx = 0;

        if(inited)
                return -1;

        if(NULL == cbs)
                return -2;

        if(!(cbs->topic_enroll && cbs->topic_cancel && cbs->publish))
                return -3;

        for(idx = 0; idx < MAX_PLUGINS; idx++) {
                struct plugin_desc *plugin = plugins + idx;
                plugin->index = idx;

                plugin_reset(plugin);
        }

        msg_cbs = &msg_cbacks;
        memcpy(msg_cbs, cbs, sizeof(struct plugin_core_msg_cbs));

        inited = true;

        USR_INFO("Plugin module has been initialized.\n\r");
        return 0;
}

}//namespace mbed_mqtt