TI's MQTT Demo with freertos CM4F

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers server_plug.cpp Source File

server_plug.cpp

00001 /******************************************************************************
00002 *
00003 *   Copyright (C) 2014 Texas Instruments Incorporated
00004 *
00005 *   All rights reserved. Property of Texas Instruments Incorporated.
00006 *   Restricted rights to use, duplicate or disclose this code are
00007 *   granted through contract.
00008 *
00009 *   The program may not be used without the written permission of
00010 *   Texas Instruments Incorporated or against the terms and conditions
00011 *   stipulated in the agreement under which this program has been supplied,
00012 *   and under no circumstances can it be used with non-TI connectivity device.
00013 *
00014 ******************************************************************************/
00015 
00016 #include "server_plug.h"
00017 #include "server_core.h"
00018 #include "server_util.h"
00019 
00020 namespace mbed_mqtt {
00021 
00022 #define MAX_PLUGINS            PG_MAP_MAX_ELEMS
00023 #define PG_NAME_LEN            32
00024 
00025 static struct plugin_desc {
00026 
00027         char                          *name;
00028         uint8_t                          index;
00029         uint8_t                          inuse;
00030 
00031         struct mqtt_server_app_cbs  app_cbs;
00032 
00033 } plugins[MAX_PLUGINS];
00034 
00035 #define PLUGIN(app_hnd) ((struct plugin_desc*) app_hnd)
00036 
00037 static inline bool is_inuse(struct plugin_desc *plugin)
00038 {
00039         return plugin->inuse? true : false;
00040 }
00041 
00042 static inline void inuse_set(struct plugin_desc *plugin, bool inuse)
00043 {
00044         plugin->inuse = inuse? 0x01 : 0x00;
00045 }
00046 
00047 static struct plugin_desc *acl_pg = NULL;
00048 
00049 static struct plugin_core_msg_cbs *msg_cbs, msg_cbacks = {NULL, NULL, NULL};
00050 
00051 static inline struct plugin_desc *plugin_find(int32_t idx)
00052 {
00053         return plugins + idx;
00054 }
00055 
00056 static void plugin_reset(struct plugin_desc *plugin)
00057 {
00058         //plugin->app_cbs = NULL; ==> TBD
00059         inuse_set(plugin, false);
00060 
00061         return;
00062 }
00063 
00064 static struct plugin_desc *plugin_alloc(void)
00065 {
00066         struct plugin_desc *plugin = NULL;;
00067         int32_t idx = 0;
00068 
00069         for(idx = 0; idx < MAX_PLUGINS; idx++) {
00070                 plugin = plugins + idx;
00071                 if(false == is_inuse(plugin)) {
00072                         inuse_set(plugin, true);
00073                         break;
00074                 }
00075         }
00076 
00077         DBG_INFO("Plugin alloc %s\n\r",
00078                  (MAX_PLUGINS == idx)? "Failed" : "Success");
00079 
00080         return (MAX_PLUGINS != idx)? plugin : NULL;
00081 }
00082 
00083 #if  0
00084 static void plugin_free(struct plugin_desc *plugin)
00085 {
00086         plugin_reset(plugin);
00087 }
00088 #endif
00089 
00090 uint16_t plugin_connect(const struct utf8_string *clientId,
00091                    const struct utf8_string *username,
00092                    const struct utf8_string *password,
00093                    void **app_usr)
00094 {
00095         uint16_t rv = CONNACK_RC_REQ_ACCEPT; /* Accept everything from MQTT network */
00096 
00097         *app_usr = NULL;
00098         if(acl_pg)
00099                 rv = acl_pg->app_cbs.connect(clientId, username,
00100                                              password, app_usr);
00101 
00102         return rv;
00103 }
00104 
00105 int32_t plugin_publish(uint8_t pg_map, const struct utf8_string *topic,
00106                    const uint8_t *payload, uint32_t pay_len,
00107                    bool dup, uint8_t qos, bool retain)
00108 {
00109         int32_t i = 0;
00110         for(i = 0; i < MAX_PLUGINS; i++) {
00111                 if(PG_MAP_HAS_VALUE(pg_map, i)) {
00112                         struct plugin_desc *plugin = plugin_find(i);
00113 
00114                         DBG_INFO("Publishing to Plugin ID: %d (%s)\n\r",
00115                                  plugin->index, plugin->name);
00116                         
00117                         if(false == is_inuse(plugin)) 
00118                                 continue; /* Must not happen */
00119                         
00120                         plugin->app_cbs.publish(topic, payload, pay_len,
00121                                                 dup, qos, retain);
00122                 }
00123         }
00124 
00125         /* TBD for error value return. */
00126 
00127         return pay_len;
00128 }
00129 
00130 int32_t plugin_disconn(const void *app_usr, bool due2err)
00131 {
00132         if(acl_pg)
00133                 acl_pg->app_cbs.disconn(app_usr, due2err);
00134 
00135         /* TBD for error value return. */
00136 
00137         return 0;
00138 }
00139 
00140 int32_t mqtt_server_topic_enroll(const void *app_hnd, 
00141                              const struct utf8_string *topic, enum mqtt_qos qos)
00142 {
00143         return  app_hnd? 
00144                 msg_cbs->topic_enroll(PLUGIN(app_hnd)->index, topic, qos) : -1;
00145 }
00146 
00147 int32_t mqtt_server_topic_disenroll(const void *app_hnd, 
00148                                 const struct utf8_string *topic)
00149 {
00150         return  app_hnd?
00151                 msg_cbs->topic_cancel(PLUGIN(app_hnd)->index, topic) : -1;
00152 }
00153 
00154 int32_t mqtt_server_app_pub_send(const  struct utf8_string *topic, 
00155                              const uint8_t *data_buf, uint32_t data_len,
00156                              enum mqtt_qos qos, bool retain)
00157 {
00158         return msg_cbs->publish(topic, data_buf, data_len, qos, retain);
00159 }
00160 
00161 static void *server_app_register(const struct mqtt_server_app_cbs *cbs,
00162                                  const char *name)
00163 {
00164         struct plugin_desc *plugin = plugin_alloc();
00165         if(NULL != plugin) {
00166                 strncpy(plugin->name, name, PG_NAME_LEN - 1);
00167                 memcpy(&plugin->app_cbs, cbs,
00168                        sizeof(struct mqtt_server_app_cbs));
00169 
00170                 if((NULL == acl_pg) && cbs->connect)
00171                         acl_pg = plugin;
00172 
00173         }
00174         return plugin;
00175 }
00176 
00177 void *mqtt_server_app_register(const struct mqtt_server_app_cbs *cbs,
00178                                const char *name)
00179 {
00180         if((NULL == cbs)                         || 
00181            ((!!cbs->connect) ^ (!!cbs->disconn)) ||
00182            (acl_pg && cbs->connect))
00183                 return NULL;
00184 
00185         return server_app_register(cbs, name);
00186 }
00187 
00188 static bool inited = false;
00189 
00190 int32_t plugin_init(const struct plugin_core_msg_cbs *cbs)
00191 {
00192         int32_t idx = 0;
00193 
00194         if(inited)
00195                 return -1;
00196 
00197         if(NULL == cbs)
00198                 return -2;
00199 
00200         if(!(cbs->topic_enroll && cbs->topic_cancel && cbs->publish))
00201                 return -3;
00202 
00203         for(idx = 0; idx < MAX_PLUGINS; idx++) {
00204                 struct plugin_desc *plugin = plugins + idx;
00205                 plugin->index = idx;
00206 
00207                 plugin_reset(plugin);
00208         }
00209 
00210         msg_cbs = &msg_cbacks;
00211         memcpy(msg_cbs, cbs, sizeof(struct plugin_core_msg_cbs));
00212 
00213         inited = true;
00214 
00215         USR_INFO("Plugin module has been initialized.\n\r");
00216         return 0;
00217 }
00218 
00219 }//namespace mbed_mqtt