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