[
  {
    "path": "Client/Makefile",
    "content": "PROGNAME := TomyClient\nSRCDIR := src\nSUBDIR := src/lib\n\nSRCS := $(SRCDIR)/LinuxClientSample.cpp \\\n$(SUBDIR)/mqttsnClientAppFw4Linux.cpp \\\n$(SUBDIR)/mqttsn.cpp \\\n$(SUBDIR)/mqttsnClient.cpp \\\n$(SUBDIR)/zbeeStack.cpp \\\n$(SUBDIR)/udpStack.cpp \\\n$(SUBDIR)/mqUtil.cpp \n\nCXX := g++\nCPPFLAGS += \nDEFS :=\nLDFLAGS += \nLIBS +=\n\nCXXFLAGS := -Wall -O3\n\nOUTDIR := Build\n\nPROG := $(OUTDIR)/$(PROGNAME)\nOBJS := $(SRCS:%.cpp=$(OUTDIR)/%.o)\nDEPS := $(SRCS:%.cpp=$(OUTDIR)/%.d)\n\n.PHONY: install clean distclean\n\nall: $(PROG)\n\n-include $(DEPS)\n\n$(PROG): $(OBJS)\n\t$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS)\n\n$(OUTDIR)/%.o:%.cpp\n\t@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<\n\nclean:\n\trm -rf $(OUTDIR)\n\ndistclean:\n\trm -rf Build\n\t\ninstall:\n\tcp -p $(PROG) ../../\n\t\n"
  },
  {
    "path": "Client/README.md",
    "content": "MQTT-SN Client\n======\n  MQTT-SN Client over XBee (running on linux, Arduino and mbed)    \n  MQTT-SN Client over UDP  (running on linux and Arduino)  \n  \n  \nSupported functions\n-------------------\n\n   QOS Level 0 and 1\n*  SEARCHGW, GWINFO\n*  CONNECT, WILLTOPICREQ, WILLTOPIC, WILLMSGREQ, WILLMSG\n*  PINGREQ, PINGRESP\n*  CONNACK, REGISTER, REGACK, SUBACK, PUBACK, UNSUBACK \n*  SUBSCRIBE, PUBLISH, UNSUBSCRIBE, DISCONNECT\n\nImplemented control flows:  \n   Application program executes publish() function,   \n   Message flow as berrow is conducted automaticaly.  \n\n\n                 Client              Gateway               Broker\n                    |                   |                    |      \n       PUBLISH() -->| --- SERCHGW ----> |                    |  \n                    | <-- GWINFO  ----- |                    |  \n                    | --- CONNECT ----> |                    |  \n                    | <--WILLTOPICREQ-- |                    |  \n                    | --- WILLTOPIC --> |                    |  \n                    | <-- WILLMSGREQ -- |                    |  \n                    | --- WILLMSG ----> | ---- CONNECT ----> |(accepted)     \n                    | <-- CONNACK ----- | <--- CONNACK ----- |   \n                    | --- PUBLISH ----> |                    |  \n                    | <-- PUBACK  ----- | (invalid TopicId)  |  \n                    | --- REGISTER ---> |                    |  \n                    | <-- REGACK  ----- |                    |  \n                    | --- PUBLISH ----> | ---- PUBLISH ----> |(accepted)  \n                    | <-- PUBACK  ----- | <---- PUBACK ----- |    \n                    |                   |                    |    \n                    //                  //                   //      \n                    |                   |                    |          \n     SUBSCRIBE() -->| --- SUBSCRIBE --> | ---- SUBSCRIBE --> |     \n     [set Callback] | <-- SUBACK ------ | <--- SUBACK ------ |    \n                    |                   |                    |    \n                    //                  //                   //    \n                    |                   |                    |    \n                    | <-- REGISTER ---- | <--- PUBLISH ----- |<-- PUBLISH  \n    [exec Callback] | <-- PUBLISH  ---- |                    |  \n                    | --- PUBACK   ---> | ---- PUBACK  ----> |--> PUBACK  \n                    |                   |                    |  \n                \n\nUsage\n------\n####Minimum requirements\n  Over XBee    \n  Three XBee S2 devices,  a coordinator, a gateway and a client.    \n  or two XBee S1 with digimesh firmware, gateway and client.    \n  \n  Over UDP    \n  Arduino with Ethernet shield or Arduino Ether.\n  or linux client.\n\n  MQTT Broker\n  TomyGateway   \n\n####1) Start Gateway  \n\n  see MQTT-SN/Gateway    \n    \n    \n  \n####2) Start Client   (-d parameter is a device which XBee dongle connected.)  \n    \n  1. XBee client    \n\n    $ TomyClient  -i ClientID  -d /dev/ttyUSB0  -b 9600    \n\n  2. UDP Client (Linux only, Arduino is embeded parameters defined by UDP_APP_CONFIG)    \n\n    $ TomyClient  -i ClientID  -g  225.1.1.1  -p 1883   -c  -t WillTopic  -m WillMessage -k 300 \n\n     \t-g : Multicast address    \n        -p : Multicast port        \n        -c : Clean session        \n        -k : Keep alive    \n  \n    \n####3) XBee configurations \n    \n  Serial interfacing  of Clients and gateway.    \n  Coordinator is default setting.  \n  XBee Firmware version is 2xA7.  \n  \n    [BD] 0-7   Arduino Clients : 3 (9600bps)  Linux Clients : 5 (38400bps)  \n    [D7] 1  \n    [D6] 0 or 1  \n    [AP] 2  \n    [SP]  Coordinator, Router Device : AF0  End device :20  \n\n  Other values are defaults. Baudrate is used by  mqtts.begin(device, _baudrate_) or mqtts.begin(_baudrate_) function.   \n  In case of LINUX, if you set D6 to 1, uncomment a line //#define XBEE_FLOWCTL_CRTSCTS in Mqtts_Defines.h\n  \n\nHow to Build (Requiered source code list)\n-----------\n####1) Linux Client\n_copy src/lib/*  and src/LinuxClientSample.cpp_  \n\n     $ make    \n     $ make install    \n\n####2) Arduino Client\n_Copy src/lib into Aruino Librally directory._\n_Copy SoilMoistureClientSample.ino into Aruino sketch directory._\n\n  \n_in IPAddress.h, change raw_address() tp public from private._  \n_Add beginMulticast() to EthernetUDP.cpp_   \nsee http://forum.arduino.cc/index.php?topic=150006.0    \n\n####3) mbed Client\n_copy src/lib/*  and src/mbedClientSample.cpp_  \n\nModule descriptions\n-------------------  \n####1) MqttsClientApp.cpp  \nClient application sample which is used for debug.\n\n  \n####2) MqttsClientFwApp.ino\n  MqttsClient sample application for Arduino. \n    \n###Modules in mqttslib\n\n####1) MqttsClient.cpp\n  MQTT-S Client Engine class. This Class is used by  a application.  \n  Usages are shown as follows.\n  \n    MqttsClient mqtts = MqttsClient();  // Declare the client object\n    mqtts.begin(argv[1], B9600);        // argv[1] is a serial device for XBee. ex) /dev/ttyUSB0 \n    mqtts.init(\"Node-02\");              // Get XBee's address64, short address and set XBee Node ID, \n    mqtts.setWillTopic(willtopic);      // set WILLTOPIC.   \n    mqtts.setWillMessage(willmsg);      // set WILLMSG  those are sent automatically. \n    mqtts.setKeepAlive(60000);          // PINGREQ interval time\n\n    mqtts.subscribe(topic, callback,qos);   // Execute the callback, when the subscribed topic's data is published. \n    mqtts.publish(topic, payload, payload_length,qos); // publish the data, topic is converted into ID automatically.\n    mqtts.publish(topic, MQString* payload,qos);  \n    mqtts.unsubscribe(topic);  \n    mqtts.disconnect();\n\n    above APIs are primitive one.     \n    In the Application, use PUBLISE(), SUBSCRIBE(), UNSUBSCRIBE(), DISCONNECT().     \n    see Sample.cpp    \n\n    \n####2) MqttsClientAppFw4Arduino.cpp\n  Application framework for Arduino.\n  Interupt and  watch dog timer are supported.\n  set MAC address of your Ethernet sheild to the UDP_APP_CONFIG structure.\n      \n####3) MqttsClientAppFw4Linux.cpp\n  Application framework for Linux.\n  watch dog timer are supported.    \n\n####4) MqttsClientAppFw4mbed.cpp\n  Application framework for mbed.\n  watch dog timer are supported.    \n  UDP is not supported.\n\n####5) MQTTS.cpp \n  MQTT-S messages classes and some classes for client and Gateway.\n    \n####6) ZBeeStack.cpp\n  XBee control classes\n\n####7) udpStack.cpp\n  UDP control classes\n    \n####8) MQTTSN_Application.h\n  Default setting is Linux and UDP.  \n  select the system and uncoment it.\n    \n    //#define LINUX \n    //#define MBED\n    \n  select the NetworkStack and uncomment it.\n   \n   //#define NETWORK_XBEE     \n   //#define NETWORK_UDP     \n  \n  \n\n"
  },
  {
    "path": "Client/src/LinuxClientSample.cpp",
    "content": "/*\n * LinuxClientSample.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#include \"lib/MQTTSN_Application.h\"\n\n#ifdef LINUX\n#include \"lib/mqttsnClientAppFw4Linux.h\"\n#include <stdio.h>\n#include <string.h>\n\nusing namespace std;\nusing namespace tomyClient;\n\n/*============================================\n *\n *   MQTT-SN Client Application for Linux\n *\n *===========================================*/\n\n/*------------------------------------------------------\n *             Create Topic\n *------------------------------------------------------*/\n\nMQString* tp1 = new MQString(\"topic/01\");\nMQString* tp2 = new MQString(\"topic/02\");\nMQString* tp3 = new MQString(\"topic/03\");\nMQString* tp4 = new MQString(\"topic/04\");\nMQString* tp5 = new MQString(\"topic/05\");\n\nMQString* tp_request_01 = new MQString(\"topic/req/01\");\nMQString* tp_response_01 = new MQString(\"topic/rsp/01\");\n\nMQString* tp_request_02 = new MQString(\"topic/req/02\");\nMQString* tp_response_02 = new MQString(\"topic/rsp/02\");\n\n/*------------------------------------------------------\n *             Tasks invoked by Timer\n *------------------------------------------------------*/\n\nint f_publish_all(){\n  PUBLISH(tp1,\"topic/01\", 8,QOS1);\n  PUBLISH(tp2,\"topic/02\", 8,QOS1);\n  PUBLISH(tp3,\"topic/03\", 8,QOS1);\n  PUBLISH(tp4,\"topic/04\", 8,QOS1);\n  PUBLISH(tp5,\"topic/05\", 8,QOS1);\n\n  Payload pl = Payload(40);\n  pl.set_uint32( 200);\n  pl.set_uint32( 10);\n  pl.set_uint32( 50000);\n  pl.set_uint32( 70000);\n  pl.set_int32( -300);\n  pl.set_int32(-70000);\n  pl.set_float((float)1000.01);\n  pl.set_str(\"abcdef\");\n  PUBLISH(tp_request_01,&pl,1);\n\n  return 0;\n}\n\n\n/*---------------  List of task invoked by Timer ------------*/\n\nTASK_LIST = {  //{ MQString* topic, executing duration in second},\n  {f_publish_all, 10},\n  END_OF_TASK_LIST\n};\n\n\n/*------------------------------------------------------\n *       Tasks invoked by PUBLISH command Packet\n *------------------------------------------------------*/\n/*----- Topic list used in callback functions -----*/\nTOPICS_IN_CALLBACK = {\n\ttp_response_01,\n\ttp_response_02,\n\tEND_OF_TOPICS\n};\n\nint f_onRequest_01(MqttsnPublish* msg){\n\tprintf(\"inside f_onRequest_01()\\n\");\n\tPayload pl;\n\tpl.getPayload(msg);\n\tpl.print();\n\tprintf(\"uint8: %d\\n\",pl.get_uint32(0));\n\tprintf(\"uint16: %d\\n\",pl.get_uint32(1));\n\tprintf(\"uint32: %d\\n\",pl.get_uint32(2));\n\tprintf(\"int8: %d\\n\",pl.get_uint32(3));\n\tprintf(\"int16: %d\\n\",pl.get_int32(4));\n\tprintf(\"int32: %d\\n\",pl.get_int32(5));\n\tprintf(\"float: %g \\n\",pl.get_float(6));\n\tuint16_t len;\n\tprintf(\"str: %s  \\n\",pl.get_str(7,&len));\n\n  PUBLISH(tp_response_01,&pl,QOS1);\n  return 0;\n}\n\nint f_onRequest_02(MqttsnPublish* msg){\n\tprintf(\"inside f_onRequest_02()\\n\");\n  PUBLISH(tp_response_02,\"topic/rsp/02\", 12,1);\n  return 0;\n}\n\n/*-------------- List of Task invoked by PUBLISH  -----------*/\n\nSUBSCRIBE_LIST = { //{ MQString* topic, on_publish1, QOS },\n  {tp_request_01, f_onRequest_01, QOS1},\n  {tp_request_02, f_onRequest_02, QOS1},\n  END_OF_SUBSCRIBE_LIST\n};\n\n\n/*==================================================\n *      Application setup\n *=================================================*/\n void setup(){\n    printf(\"Client start\\n\");\n }\n/*==============    End of Program    ==============*/\n\n#endif  // LINUX\n"
  },
  {
    "path": "Client/src/SoilMoistureClientSample.ino",
    "content": "/*\n * SoilMoisture.ino\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#include <MQTTSN_Application.h>\n#include <mqttsnClientAppFw4Arduino.h>\n#include <SPI.h>\n#include <Ethernet.h>\n#include <EthernetUdp.h>\n\n/*============================================\n *\n *   MQTT-SN Client Application for Arduino\n *\n *===========================================*/\n #ifdef NETWORK_XBEE\n XBEE_APP_CONFIG = {\n    {\n        9600,           //Baudrate\n        0,              //Serial PortNo (for Arduino App)\n        0               //Device (for linux App)\n    }, \n    {             \n        \"ARD02\",       //ClientId\n        300,            //KeepAlive\n        true,           //Clean session\n        false,           //EndDevice\n        \"willTopic\",    //WillTopic   or 0   DO NOT USE NULL STRING \"\" !\n        \"willMessage\"   //WillMessage or 0   DO NOT USE NULL STRING \"\" !\n    }\n };\n#endif\n\n#ifdef NETWORK_UDP\nUDP_APP_CONFIG = {\n    { \n        {225,1,1,1},         // Multicast group IP\n        1883,                // Multicast group Port\n        {192,168,11,18},     // Local IP     (for Arduino App)\n        12001,               // Local PortNo\n        {0x90,0xa2,0xda,0x0f,0x53,0xa5}       // MAC address  (for Arduino App)\n    },\n    { \n        \"ARD02\",       //ClientId\n        300,            //KeepAlive\n        true,           //Clean session\n        false,           //EndDevice\n        \"willTopic\",    //WillTopic   or 0   DO NOT USE NULL STRING \"\" !\n        \"willMessage\"   //WillMessage or 0   DO NOT USE NULL STRING \"\" !\n    } \n};\n#endif\n\n/*------------------------------------------------------\n *             Create Topic\n *------------------------------------------------------*/\nMQString* topic1 = new MQString(\"ty4tw/tp1\");\nMQString* topic2 = new MQString(\"ty4tw/tp2\");\nMQString* tpMeasure = new MQString(\"ty4tw/soilReg\");\n/*------------------------------------------------------\n *             Tasks invoked by Timer\n *------------------------------------------------------*/\n#define PIN5  5    // 3.3V supply port \n#define MCOUNT 10  // measurement count\n#define PIN0  0    // measurement port\n#define RP   20    // resistance [K ohom] \n\nint measure(){\n  int val = 0;\n  pinMode(PIN5,OUTPUT);\n  digitalWrite(PIN5,1);\n  \n  for(uint8_t cnt = 0; cnt < MCOUNT; cnt++){\n    delay(50);\n    val += analogRead(PIN0);\n  }\n  digitalWrite(PIN5,0);\n  int soilR = 1023 * RP / (val /MCOUNT) - RP;\n  if(soilR < 0){\n    soilR = 9999;\n  }\n  Payload pl(30);\n  pl.set_array(3);\n  pl.set_uint32(GETUTC());\n  pl.set_int32(soilR);\n  pl.set_str(\"Kohom\");\n  return PUBLISH(tpMeasure,&pl,QOS1);\n}\n\n\nint task1(){\n  Payload pl = Payload(36);\n  pl.set_array(9);\n  pl.set_int32(30);\n  pl.set_int32(255);\n  pl.set_int32(70000);\n  pl.set_str(\"abcdef\");\n  pl.set_int32(-16);\n  pl.set_int32(-60);\n  pl.set_int32(-300);\n  pl.set_int32(-70000);\n  pl.set_float(1000.01);\n  return PUBLISH(topic1,&pl,QOS1);\n}\n\n/*---------------  List of task invoked by Timer ------------*/\n\nTASK_LIST = {  //{ MQString* topic, executing duration in second},\n           {measure, 40},\n           {task1,6},\n           //{task2,6},\nEND_OF_TASK_LIST};\n\n\n/*------------------------------------------------------\n *       Tasks invoked by PUBLISH command Packet\n *------------------------------------------------------*/\n TOPICS_IN_CALLBACK = {\n\n   END_OF_TOPICS\n };\n \n\nint on_publish2(MqttsnPublish* msg){\n    theApplication->indicatorOff();\n    return 0;\n}\n\n/*------------ Link Callback to Topic -------------*/\n\nSUBSCRIBE_LIST = {\n                    //{topic1, on_publish1, QOS1},\n                    //{topic2, on_publish2, QOS1},\n\nEND_OF_SUBSCRIBE_LIST};\n\n/*------------------------------------------------------\n *            Tasks invoked by INT0 interuption \n *------------------------------------------------------*/\nvoid interruptCallback(){\n  //NOP\n}\n\n/*------------------------------------------------------\n *            Arduino setup() function \n *------------------------------------------------------*/\n void setup(){\n\n }\n\n\n"
  },
  {
    "path": "Client/src/lib/MQTTSN_Application.h",
    "content": "/*\n * MQTTSN_Application.h\n *\n *                    The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                   All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef MATTSNAPPLICATION_H_\n#define MATTSNAPPLICATION_H_\n\n/****************************************\n      Select Platform and Network\n*****************************************/\n\n/*----------- Select Platform  ---------*/\n#ifndef ARDUINO\n\t#define LINUX\n\t//#define MBED\n#endif\n\n/*--------- Select byte order ----------*/\n#define CPU_LITTLEENDIANN\n//#define CPU_BIGENDIANN\n\n\n/*-------- Select Network  -------------*/\n#define NETWORK_XBEE\n//#define NETWORK_UDP\n\n\n/*--- XBee Buffer Flow Control --*/\n#ifdef NETWORK_XBEE\n\t//#define XBEE_FLOWCTL_CRTSCTS\n#endif\n\n/*======================================\n *         Debug Flag\n ======================================*/\n//#define NW_DEBUG\n//#define MQTTSN_DEBUG\n#define DEBUG\n\n\n/****************************************\n      MQTT-SN Packet length\n*****************************************/\n#ifdef ARDUINO\n\t#define MQTTSN_MAX_FRAME_SIZE               70\n#else\n\t#ifdef NETWORK_XBEE\n\t\t#define MQTTSN_MAX_FRAME_SIZE           70\n\t#else\n\t\t#ifdef NETWORK_UDP\n\t\t\t#define MQTTSN_MAX_FRAME_SIZE     1024\n\t\t#endif\n\t#endif\n#endif\n/****************************************\n      Application config structures\n*****************************************/\n#ifdef LINUX\ntypedef unsigned char  uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int   uint32_t;\ntypedef signed char    int8_t;\ntypedef signed short   int16_t;\ntypedef signed int     int32_t;\n#endif\n\n#ifdef MBED\n\t#include \"mbed.h\"\n#endif\n\n#ifdef ARDUINO\n\t#include <Arduino.h>\n#endif\n\ntypedef struct {\n\tconst char* nodeId;\n\tuint16_t keepAlive;\n\tbool     cleanSession;\n\tbool     endDevice;\n\tconst char* willTopic;\n\tconst char* willMsg;\n}MqttsnConfig;\n\ntypedef struct {\n\tlong baudrate;\n\tuint8_t  portNo;\n\tchar* device;\n}XBeeConfig;\n\ntypedef struct {\n\tXBeeConfig netCfg;\n\tMqttsnConfig mqttsnCfg;\n}XBeeAppConfig;\n\ntypedef struct {\n\tuint8_t  ipAddress[4];\n\tuint16_t gPortNo;\n\tuint8_t  ipLocal[4];\n\tuint16_t uPortNo;\n\tuint8_t  macAddr[6];\n}UdpConfig;\n\ntypedef struct {\n\tUdpConfig netCfg;\n\tMqttsnConfig mqttsnCfg;\n}UdpAppConfig;\n\n/*======================================\n      MACROs for Application\n=======================================*/\n#ifdef NETWORK_XBEE\n    #define XBEE_APP_CONFIG       XBeeAppConfig  theAppConfig\n\t#define APP_CONFIG            XBeeAppConfig\n\t#define NETWORK_CONFIG        XBeeConfig\n#endif\n\n#ifdef NETWORK_UDP\n    #define UDP_APP_CONFIG        UdpAppConfig   theAppConfig\n\t#define APP_CONFIG            UdpAppConfig\n\t#define NETWORK_CONFIG        UdpConfig\n#endif\n\n#define TASK_LIST         TaskList theTaskList[]\n#define END_OF_TASK_LIST  {0,0}\n#define SUBSCRIBE_LIST   OnPublishList theOnPublishList[]\n#define END_OF_SUBSCRIBE_LIST {0,0,0}\n#define TOPICS_IN_CALLBACK MQString* theTopics[]\n#define END_OF_TOPICS    0\n\n#define PUBLISH(...)     theApplication->publish(__VA_ARGS__)\n#define SUBSCRIBE(...)   theApplication->subscribe(__VA_ARGS__)\n#define UNSUBSCRIBE(...) theApplication->unsubscribe(__VA_ARGS__)\n#define DISCONNECT()     theApplication->disconnect()\n#define SETRETAIN(...)   theApplication->setRetain(__VA_ARGS__)\n\n/*======================================\n      MACROs for debugging\n========================================*/\n#ifdef ARDUINO\n\t#ifdef NW_DEBUG\n\t\t#define D_NWSTACK(...)    debug.print(__VA_ARGS__)\n\t\t#define D_NWSTACKLN(... ) debug.println(__VA_ARGS__)\n\t\t#define D_NWSTACKW(...)   debug.print(__VA_ARGS__)\n\t\t#define D_NWSTACKF(...)\n\t#else\n\t\t#define D_NWSTACK(...)\n\t\t#define D_NWSTACKLN(...)\n\t\t#define D_NWSTACKW(...)\n\t\t#define D_NWSTACKF(...)\n\t#endif\n\n\t#ifdef MQTTSN_DEBUG\n\t\t#define D_MQTT(...)    debug.print(__VA_ARGS__)\n\t\t#define D_MQTTW(...)   debug.print(__VA_ARGS__)\n\t\t#define D_MQTTLN(...)  debug.println(__VA_ARGS__)\n\t\t#define D_MQTTF(...)\n\t#else\n\t\t#define D_MQTT(...)\n\t\t#define D_MQTTLN(...)\n\t\t#define D_MQTTW(...)\n\t\t#define D_MQTTF(...)\n\t#endif\n#else\n\t#ifdef NW_DEBUG\n\t\t#define D_NWSTACKF(...)    printf(__VA_ARGS__)\n\t\t#define D_NWSTACKW(...)   printf(__VA_ARGS__)\n\t\t#define D_NWSTACKLN(...)\n\t\t#define D_NWSTACK(...)\n\t#else\n\t\t#define D_NWSTACK(...)\n\t\t#define D_NWSTACKLN(...)\n\t\t#define D_NWSTACKW(...)\n\t\t#define D_NWSTACKF(...)\n\t#endif\n\t#ifdef MQTTSN_DEBUG\n\t\t#define D_MQTTF(...)    printf(__VA_ARGS__)\n\t\t#define D_MQTTW(...)   printf(\"%s\",__VA_ARGS__)\n\t\t#define D_MQTTLN(...)\n\t\t#define D_MQTT(...)\n\t#else\n\t\t#define D_MQTT(...)\n\t\t#define D_MQTTLN(...)\n\t\t#define D_MQTTW(...)\n\t\t#define D_MQTTF(...)\n\t\t#endif\n#endif\n\n#endif /* MATTSNAPPLICATION_H_ */\n\n"
  },
  {
    "path": "Client/src/lib/Network.h",
    "content": "/*\n * Network.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef  NEWORK_H_\n#define  NEWORK_H_\n\n#ifndef ARDUINO\n    #include \"MQTTSN_Application.h\"\n#else\n\t#include <MQTTSN_Application.h>\n#endif\n\n/***********************************\n *     Send Request Type\n ***********************************/\nenum SendReqType{\n    NoReq = 0,\n    UcastReq,\n    BcastReq\n};\n\n/*=================================\n *    Network stacks\n ==================================*/\n#ifdef NETWORK_XBEE\n\t#ifdef ARDUINO\n\t\t#include <zbeeStack.h>\n\t#else\n\t\t#include \"zbeeStack.h\"\n\t#endif\n#endif\n\n#ifdef NETWORK_UDP\n\t#ifdef ARDUINO\n\t\t#include <udpStack.h>\n\t#else\n\t\t#include \"udpStack.h\"\n\t#endif\n#endif\n\n\nnamespace tomyClient {\n/***********************************\n *     MQTT-SN  Client's state\n ***********************************/\nenum NodeStatus {\n    NdDisconnected = 0,\n    NdActive,\n    NdAsleep,\n    NdAwaik,\n    NdLost\n};\n\n#define PACKET_SENDED           0\n#define PACKET_ERROR_RESPONSE  -1\n#define PACKET_ERROR_UNKOWN    -2\n#define PACKET_ERROR_NODATA    -3\n#define PACKET_MODEM_STATUS    -4\n\n}   /* end of namespace */\n\n#endif  /* NEWORK_H_ */\n"
  },
  {
    "path": "Client/src/lib/mqUtil.cpp",
    "content": "/*\n * mqUtil.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef ARDUINO\n        #include \"MQTTSN_Application.h\"\n        #include \"mqUtil.h\"\n\t\t#include \"stdio.h\"\n\t\t#include \"string.h\"\n#else\n        #include <MQTTSN_Application.h>\n        #include <mqUtil.h>\n\t\t#include <stdio.h>\n\t\t#include <string.h>\n#endif  /* ARDUINO */\n\n#ifdef MBED\n        #include \"mbed.h\"\n#endif /* MBED */\n\n\nusing namespace std;\nusing namespace tomyClient;\n\n/*=====================================\n        Global functions\n ======================================*/\n\n#ifdef CPU_LITTLEENDIANN\n\n/*--- For Little endianness ---*/\n\nuint16_t getUint16(uint8_t* pos){\n\tuint16_t val = ((uint16_t)*pos++ << 8);\n\treturn val += *pos;\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n    *pos++ = (val >> 8) & 0xff;\n\t*pos   = val & 0xff;\n}\n\nuint32_t getUint32(uint8_t* pos){\n    uint32_t val = uint32_t(*pos++) <<  24;\n\tval += uint32_t(*pos++) << 16;\n\tval += uint32_t(*pos++) <<  8;\n\treturn val += *pos++;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n\t*pos++ = (val >> 24) & 0xff;\n\t*pos++ = (val >> 16) & 0xff;\n\t*pos++ = (val >>  8) & 0xff;\n\t*pos   =  val & 0xff;\n}\n\nfloat getFloat32(uint8_t* pos){\n\tunion{\n\t\tfloat flt;\n\t\tuint8_t d[4];\n\t}val;\n    val.d[3] = *pos++;\n\tval.d[2] = *pos++;\n\tval.d[1] = *pos++;\n\tval.d[0] = *pos;\n\treturn val.flt;\n}\n\nvoid setFloat32(uint8_t* pos, float flt){\n\tunion{\n\t\tfloat flt;\n\t\tuint8_t d[4];\n\t}val;\n\tval.flt = flt;\n    *pos++ = val.d[3];\n    *pos++ = val.d[2];\n    *pos++ = val.d[1];\n    *pos   = val.d[0];\n}\n\n#endif  // CPU_LITTLEENDIANN\n\n/*--- For Big endianness ---*/\n#ifdef CPU_BIGENDIANN\n\nuint16_t getUint16(uint8_t* pos){\n  uint16_t val = *pos++;\n  return val += ((uint16_t)*pos++ << 8);\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n\t*pos++ =  val & 0xff;\n\t*pos   = (val >>  8) & 0xff;\n}\n\nuint32_t getUint32(uint8_t* pos){\n    long val = uint32_t(*(pos + 3)) << 24;\n    val += uint32_t(*(pos + 2)) << 16;\n\tval += uint32_t(*(pos + 1)) <<  8;\n\treturn val += *pos;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n    *pos++ =  val & 0xff;\n    *pos++ = (val >>  8) & 0xff;\n    *pos++ = (val >> 16) & 0xff;\n    *pos   = (val >> 24) & 0xff;\n}\n\nfloat getFloat32(uint8_t* pos){\n\tunion{\n\t\tfloat flt;\n\t\tuint8_t d[4];\n\t}val;\n\n    val.d[0] = *pos++;\n\tval.d[1] = *pos++;\n\tval.d[2] = *pos++;\n\tval.d[3] = *pos;\n\treturn val.flt;\n}\n\nvoid setFloat32(uint8_t* pos, float flt){\n\tunion{\n\t\tfloat flt;\n\t\tuint8_t d[4];\n\t}val;\n\tval.flt = flt;\n    *pos++ = val.d[0];\n    *pos++ = val.d[1];\n    *pos++ = val.d[2];\n    *pos   = val.d[3];\n}\n\n#endif  // CPU_BIGENDIANN\n\n/*=========================================\n             Class XBeeTimer\n =========================================*/\n\n#ifdef ARDUINO\n/**\n *   for Arduino\n */\nuint32_t XTimer::_unixTime;\nuint32_t XTimer::_epochTime;\nuint32_t XTimer::_timerStopTimeAccum;\nbool    XTimer::_utcFlag;\n\n\nXTimer::XTimer(){\n    stop();\n}\n\nvoid XTimer::initialize(){\n\t_unixTime = 0;\n\t_epochTime = 0;\n\t_timerStopTimeAccum = 0;\n\t_utcFlag = false;\n}\n\nvoid XTimer::start(uint32_t msec){\n    _startTime = millis();\n    _millis = msec;\n    _currentTime = 0;\n\t_timeupUnixTime =  getUnixTime() + msec / 1000;\n}\n\nbool XTimer::isTimeUp(){\n    return isTimeUp(_millis);\n}\n\nbool XTimer::isTimeUp(uint32_t msec){\n\tif(_utcFlag){\n\t\t_utcFlag = false;\n\t\tif(_timeupUnixTime > 1000000000 && _unixTime){\n\t\t\treturn (getUnixTime() >= _timeupUnixTime);\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}else{\n\t\tif ( _startTime){\n\t\t\t_currentTime = millis();\n\t\t\tif ( _currentTime < _startTime){\n\t\t\t\treturn (0xffffffff - _startTime + _currentTime > msec);\n\t\t\t}else{\n\t\t\t\treturn (_currentTime - _startTime > msec);\n\t\t\t}\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nvoid XTimer::stop(){\n    _startTime = 0;\n    _millis = 0;\n    _currentTime = 0;\n    _timeupUnixTime = 0;\n}\n\nvoid XTimer::setUnixTime(uint32_t utc){\n    _epochTime = millis();\n    _timerStopTimeAccum = 0;\n    _unixTime = utc;\n}\n\nuint32_t XTimer::getUnixTime(){\n    uint32_t tm = _timerStopTimeAccum + millis();\n    if (_epochTime > tm ){\n        return _unixTime + (uint32_t)((0xffffffff - tm - _epochTime) / 1000);\n    }else{\n        return _unixTime + (uint32_t)((tm - _epochTime) / 1000);\n    }\n}\n\nvoid XTimer::setStopTimeDuration(uint32_t msec){\n\t_timerStopTimeAccum += msec;\n}\n\nvoid XTimer::changeUTC(){\n\t_utcFlag = true;\n}\n\n#endif\n\n\n#ifdef MBED\n/**\n *   for MBED\n */\nXTimer::XTimer(){\n    stop();\n}\n\nvoid XTimer::start(uint32_t msec){\n    _timer.start();\n    _millis = msec;\n    _timeupTime = time(0) + (uint32_t)(msec/1000UL);\n}\n\nbool XTimer::isTimeUp(){\n    return isTimeUp(_millis);\n}\n\nbool XTimer::isTimeUp(uint32_t msec){\n\tif(_utcFlg){\n\t\tif(_timeupTime > 100000000){\n\t\t\treturn( time(0) > _timeupTime);\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}else{\n\t\treturn _timer.read_ms() > msec;\n\t}\n}\n\nvoid XTimer::stop(){\n    _timer.stop();\n    _millis = 0;\n    _timeupTime = 0;\n}\n\nvoid XTimer::changeUTC(){\n\t_utcFlg = true;\n}\n\n#endif\n\n#ifdef LINUX\n/**\n *   for LINUX\n */\nXTimer::XTimer(){\n\t_startTime.tv_sec = 0;\n\t_millis = 0;\n}\n\nXTimer::~XTimer(){\n\n}\n\nvoid XTimer::start(uint32_t msec){\n  gettimeofday(&_startTime, 0);\n  _millis = msec;\n}\n\nbool XTimer::isTimeUp(void){\n  return isTimeUp(_millis);\n}\n\nbool XTimer::isTimeUp(uint32_t msec){\n    struct timeval curTime;\n    uint32_t secs, usecs;\n    if (_startTime.tv_sec == 0){\n        return false;\n    }else{\n        gettimeofday(&curTime, 0);\n        secs  = (curTime.tv_sec  - _startTime.tv_sec) * 1000;\n        usecs = (curTime.tv_usec - _startTime.tv_usec) / 1000.0;\n        return ((secs + usecs) > (uint32_t)msec);\n    }\n}\n\nvoid XTimer::stop(){\n  _startTime.tv_sec = 0;\n  _millis = 0;\n}\n\n#endif\n"
  },
  {
    "path": "Client/src/lib/mqUtil.h",
    "content": "/*\r\n * mqUtil.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified: 2014/09/05\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 1.0.0\r\n */\r\n\r\n#ifndef XTIMER_H_\r\n#define XTIMER_H_\r\n\r\n\r\n#if defined(ARDUINO)\r\n\t#include <MQTTSN_Application.h>\r\n    #if ARDUINO >= 100\r\n        #include \"Arduino.h\"\r\n        #include <inttypes.h>\r\n    #else\r\n        #if ARDUINO < 100\r\n            #include \"WProgram.h\"\r\n            #include <inttypes.h>\r\n        #endif\r\n    #endif\r\n\r\n\t#define XB_CTS_PIN   3   // XBee CTS\r\n\t#define XB_SLEEP_PIN 4   // XBee Pinhybernate\r\n#else\r\n\t#include \"MQTTSN_Application.h\"\r\n#endif /* ARDUINO */\r\n\r\n\r\n#ifdef LINUX\r\n    #include <sys/time.h>\r\n#endif\r\n\r\n#ifdef MBED\r\n    #include \"mbed.h\"\r\n#endif\r\n\r\nnamespace tomyClient {\r\n\r\n\r\n#ifdef ARDUINO\r\n/*============================================\r\n       XBeeTimer for Arduino\r\n ============================================*/\r\nclass XTimer{\r\npublic:\r\n    XTimer();\r\n    ~XTimer(){};\r\n    void start(uint32_t msec = 0);\r\n    bool isTimeUp(uint32_t msec);\r\n    bool isTimeUp(void);\r\n    void stop();\r\n    static uint32_t getUnixTime();\r\n    static void setUnixTime(uint32_t utc);\r\n\tstatic void setStopTimeDuration(uint32_t msec);\r\n    static void initialize();\r\n    static void changeUTC();\r\n\r\nprivate:\r\n    uint32_t _startTime;\r\n    uint32_t _currentTime;\r\n    uint32_t _millis;\r\n\tuint32_t _timeupUnixTime;\r\n\tstatic uint32_t _unixTime;\r\n\tstatic uint32_t _epochTime;\r\n\tstatic uint32_t _timerStopTimeAccum;\r\n\tstatic bool _utcFlag;\r\n\r\n};\r\n\r\n\r\n#endif\r\n\r\n#ifdef MBED\r\n/*============================================\r\n    XBeeTimer  for MBED\r\n ============================================*/\r\nclass XTimer{\r\npublic:\r\n    XTimer();\r\n    ~XTimer(){};\r\n    void start(uint32_t msec = 0);\r\n    bool isTimeUp(uint32_t msec);\r\n    bool isTimeUp(void);\r\n    void stop(void);\r\n    void changeUTC(void);\r\n\r\nprivate:\r\n    Timer _timer;\r\n    time_t _startTime;\r\n    uint32_t _millis;\r\n    time_t _timeupTime;\r\n    bool _utcFlg;\r\n};\r\n\r\n#endif\r\n\r\n\r\n#ifdef LINUX\r\n/*============================================\r\n                XBeeTimer\r\n ============================================*/\r\nclass XTimer{\r\npublic:\r\n    XTimer();\r\n    ~XTimer();\r\n    void start(uint32_t msec = 0);\r\n    bool isTimeUp(uint32_t msec);\r\n    bool isTimeUp(void);\r\n    void stop(void);\r\n    void changeUTC(void){};\r\nprivate:\r\n    struct timeval _startTime;\r\n    uint32_t _millis;\r\n};\r\n\r\n#endif\r\n}\r\n\r\n#endif  /* XTIMER_H_ */\r\n"
  },
  {
    "path": "Client/src/lib/mqttsn.cpp",
    "content": "/*\n * mqttsn.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n\n#ifndef ARDUINO\n  \t  #include \"MQTTSN_Application.h\"\n#else\n  \t  #include <MQTTSN_Application.h>\n#endif\n\n\n#ifdef ARDUINO\n  #include <mqttsn.h>\n  #include <Network.h>\n\n  #if defined(MQTTSN_DEBUG) || defined(ZBEE_DEBUG)\n    #include <SoftwareSerial.h>\n    extern SoftwareSerial debug;\n  #endif\n\n#endif  /* ARDUINO */\n\n#ifdef MBED\n  #include \"mbed.h\"\n  #include \"Network.h\"\n  #include \"mqttsn.h\"\n#endif  /* MBED */\n\n#ifdef LINUX\n  #include \"Network.h\"\n  #include \"mqttsn.h\"\n  #include <stdio.h>\n  #include <sys/time.h>\n  #include <sys/types.h>\n  #include <sys/stat.h>\n  #include <unistd.h>\n  #include <stdlib.h>\n  #include <string.h>\n  #include <fcntl.h>\n  #include <errno.h>\n  #include <termios.h>\n#endif /* LINUX */\n\n\nusing namespace std;\nusing namespace tomyClient;\n\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern float    getFloat32(uint8_t* pos);\n\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\nextern void setFloat32(uint8_t* pos, float val);\n\n\n/*=====================================\n        Class MQString\n  =====================================*/\nMQString::MQString(){\n    //_length = 0;\n    _constStr = 0;\n    _str = 0;\n}\n\nMQString::MQString(const char* str){\n    if (strlen(str)){\n        _constStr = str;\n    }else{\n        _constStr = 0;\n    }\n    _str = 0;\n}\n\nMQString::MQString(char* str){\n    if (strlen(str)){\n        _str = str;\n    }else{\n        _str = 0;\n    }\n    _constStr = 0;\n}\n\nMQString::~MQString(){\n    if (_str){\n        free(_str);\n    }\n}\n\nuint16_t MQString::getCharLength(){\n    if(_str){\n    \treturn strlen(_str);\n    }\n    return strlen(_constStr);\n}\n\nint MQString::comp(MQString* str){\n    if (_str){\n    \tif(str->getStr()){\n    \t\treturn (strcmp(_str, str->getStr()));\n    \t}else if(str->getConstStr()){\n    \t\treturn (strcmp(_str, str->getConstStr()));\n    \t}\n    }else if(_constStr){\n    \tif(str->getStr()){\n    \t\treturn (strcmp(_constStr, str->getStr()));\n    \t}else if(str->getConstStr()){\n    \t\treturn (strcmp(_constStr, str->getConstStr()));\n    \t}\n    }\n    return 1;\n}\n\n\nint MQString::comp(const char* str){\n    if(_str){\n        return (strcmp(_str, str));\n    }else if (_constStr){\n        return (strcmp(_constStr, str));\n    }\n    return 1;\n}\n\n\nint MQString::ncomp(MQString* str, uint16_t len){\n    if (_str){\n        return strncmp(_str, str->getStr(), (long)len);\n    }else if (_constStr){\n        return strncmp(_constStr, str->getConstStr(), (long)len);\n    }\n    return 1;\n}\n\n\nbool MQString::operator==(MQString &str){\n\treturn (comp(&str) == 0);\n}\n\nbool MQString::operator!=(MQString &str){\n\treturn (comp(&str) != 0);\n}\n\n\nvoid MQString::copy(MQString* str){\n    if (str->isConst()){\n        _constStr = getConstStr();\n    }else{\n        _str = str->getStr();\n    }\n}\n\nMQString* MQString::create(){\n    char* newStr = (char*)calloc(getCharLength()+ 1, sizeof(char));\n    memcpy(newStr, getConstStr(), getCharLength());\n    MQString* newPtr = new MQString((const char*)newStr);\n    return newPtr;\n}\n\nvoid MQString::copy(const char* str){\n    _constStr = str;\n    _str = 0;\n    freeStr();\n}\n\nvoid MQString::copy(char* str){\n    freeStr();\n    _str = (char*)calloc(strlen(str) + 1, sizeof(char));\n    _constStr = 0;\n    strcpy(_str, str);\n}\n\nvoid MQString::copy(uint8_t* str, uint8_t len){\n    freeStr();\n    _str = (char*)calloc(len + 1, sizeof(char));\n    _constStr = 0;\n    memcpy(_str, str, len);\n}\n\nvoid MQString::writeBuf(uint8_t* buf){\n    if (_str){\n        memcpy(buf, _str, strlen(_str));\n    }else if (_constStr){\n        memcpy(buf, _constStr, strlen(_constStr));\n    }\n}\n\nvoid MQString::readBuf(uint8_t* buf){\n    _str = 0;\n    _constStr = (const char*)buf;\n}\n\nuint8_t MQString::getChar(uint8_t index){\n    if (_str){\n        return (index < strlen(_str) ? _str[index]: 0);\n    }else if (_constStr){\n        return (index < strlen(_constStr) ? _constStr[index]: 0);\n    }\n    return 0;\n}\n\nchar* MQString::getStr(){\n    return (_str ? _str : 0);\n}\n\nconst char* MQString::getConstStr(){\n    return (_constStr ? _constStr : 0);\n}\n\n\nbool MQString::isConst(){\n  return (_constStr ? true : false);\n}\n\nvoid MQString::freeStr(){\n    if (_str){\n        free(_str);\n        _str = 0;\n    }\n}\n\n\n/*=====================================\n        Class MqttsnMessage\n ======================================*/\nMqttsnMessage::MqttsnMessage(){\n    _msgBuff = 0;    _flags = 0;\n    _flags = 0;\n    _length = 0;\n    _status = 0;\n    _type = 0;\n}\nMqttsnMessage::~MqttsnMessage(){\n    if (_msgBuff != 0){\n        delete(_msgBuff);\n    }\n}\n\nvoid MqttsnMessage::reset(){\n    _msgBuff = 0;\n    _length = 0;\n    _status = 0;\n    _type = 0;\n}\n\nvoid MqttsnMessage::setType(uint8_t type){\n    _type = type;\n    if ( _msgBuff != 0){\n    \tif(_length > 255){\n    \t\t_msgBuff[3] = type;\n    \t}else{\n    \t\t_msgBuff[1] = type;\n    \t}\n    }\n}\n\nvoid MqttsnMessage::setFlags(uint8_t flg){\n    _flags = flg;\n    if ( _msgBuff != 0){\n    \tif(_length > 255){\n    \t\t_msgBuff[4] = flg;\n    \t}else{\n    \t\t_msgBuff[2] = flg;\n    \t}\n    }\n}\n\nvoid MqttsnMessage::setLength(uint16_t length){\n    _length = length;\n    if ( _msgBuff != 0){\n    \tif(_length > 255){\n    \t\t_msgBuff[0] = 0x01;\n\t\t\tsetUint16(_msgBuff + 1, _length);\n\t\t}else{\n\t\t\t _msgBuff[0] = length;\n\t\t}\n    }\n}\n\nvoid MqttsnMessage::setQos(uint8_t qos){\n\t_flags &= 0x9f;\n\tif(qos == QOS1){\n\t\t_flags |= 0x20;\n\t}else if(qos == QOS2){\n\t\t_flags |= 0x40;\n\t}\n\tsetFlags(_flags);\n}\n\nbool MqttsnMessage::setBody(uint8_t* body){\n    if (allocateBody()) {\n    \tif(_length > 255){\n    \t\t_msgBuff[0] = 0x01;\n\t\t\tsetUint16(_msgBuff + 1, _length);\n\t\t\t_msgBuff[3] = _type;\n\t\t\tmemcpy(_msgBuff + 4, body, _length - 4);\n    \t}else{\n\t\t\t_msgBuff[0] = _length;\n\t\t\t_msgBuff[1] = _type;\n\t\t\tmemcpy(_msgBuff + 2, body, _length - MQTTSN_HEADER_SIZE);\n    \t}\n        return true;\n    }else{\n        return false;\n    }\n}\n\nbool MqttsnMessage::allocateBody(){\n    if ( _length > 0 ) {\n        if (_msgBuff){\n              free(_msgBuff);\n        }\n\n        _msgBuff = (uint8_t*)calloc(_length + 1, sizeof(uint8_t));\n        if ( _msgBuff){\n        \tif(_length > 255){\n        \t\t_msgBuff[0] = 0x01;\n        \t\tsetUint16(_msgBuff + 1, _length);\n        \t\t_msgBuff[3] = _type;\n                _msgBuff[4] = _flags;\n        \t}else{\n\t\t\t\t_msgBuff[0] = _length;\n\t\t\t\t_msgBuff[1] = _type;\n\t\t        _msgBuff[2] = _flags;\n        \t}\n            return true;\n        }else{\n            return false;\n        }\n    }else{\n        return false;\n    }\n}\n\nvoid MqttsnMessage::setDup(){\n\tif(_msgBuff && (_type == MQTTSN_TYPE_PUBLISH || _type == MQTTSN_TYPE_SUBSCRIBE)){\n\t\t_flags |= 0x80;\n\t\tgetBody()[0] = _flags ;\n\t}\n}\n\nvoid MqttsnMessage::setStatus(uint8_t stat){\n    _status = stat;\n}\n\nuint8_t MqttsnMessage::getQos(){\n    return (_flags & (MQTTSN_FLAG_QOS_1 | MQTTSN_FLAG_QOS_2)) >> 5;\n}\n\nuint8_t MqttsnMessage::getLength(){\n    return _length;\n}\n\nuint8_t MqttsnMessage::getType(){\n    return _type;\n}\n\nuint8_t MqttsnMessage::getFlags(){\n    return _flags;\n}\n\nuint8_t MqttsnMessage::getStatus(){\n    return _status;\n}\n\nuint8_t* MqttsnMessage::getBody(){\n\tif(_length > 255){\n\t\treturn _msgBuff + 4;\n\t}else{\n\t\treturn _msgBuff + MQTTSN_HEADER_SIZE;\n\t}\n}\n\nuint16_t MqttsnMessage::getBodyLength(){\n    if(_length > 255){\n    \treturn _length - 4;\n    }else{\n    \treturn _length - MQTTSN_HEADER_SIZE;\n    }\n}\n\nuint16_t MqttsnMessage::getFrameLength(){\n    return _length;\n}\n\nuint8_t* MqttsnMessage::getMsgBuff(){\n    return _msgBuff;\n}\n\nvoid MqttsnMessage::setMsgBuff(uint8_t* msgBuff){\n    _msgBuff = msgBuff;\n}\n\nbool MqttsnMessage::copy(MqttsnMessage* src){\n    setLength(src->getLength());\n    setType(src->getType());\n    setFlags(src->getFlags());\n    setStatus(src->getStatus());\n    _msgBuff = src->_msgBuff;\n    src->setMsgBuff(0);\n    if (_msgBuff == 0){\n        return false;\n    }\n    return true;\n}\n\nconst char* MqttsnMessage::getMsgTypeName(){\n\tswitch(_type){\n\tcase 0x00:\n\t\treturn \"ADVERTIZE\";\n\tcase 0x01:\n\t\treturn \"SEARCGW\";\n\tcase 0x02:\n\t\treturn \"GWINFO\";\n\tcase 0x04:\n\t\treturn \"CONNECT\";\n\tcase 0x05:\n\t\treturn \"CONNACK\";\n\tcase 0x06:\n\t\treturn \"WILLTOPICREQ\";\n\tcase 0x07:\n\t\treturn \"WILLTOPIC\";\n\tcase 0x08:\n\t\treturn \"WILLMSGREQ\";\n\tcase 0x09:\n\t\treturn \"WILLMSG\";\n\tcase 0x0a:\n\t\treturn \"REGISTER\";\n\tcase 0x0b:\n\t\treturn \"REGACK\";\n\tcase 0x0c:\n\t\treturn \"PUBLISH\";\n\tcase 0x0d:\n\t\treturn \"PUBACK\";\n\tcase 0x0e:\n\t\treturn \"PUBCOMP\";\n\tcase 0x0f:\n\t\treturn \"PUBREC\";\n\tcase 0x10:\n\t\treturn \"PUBREL\";\n\tcase 0x12:\n\t\treturn \"SUBSCRIBE\";\n\tcase 0x13:\n\t\treturn \"SUBACK\";\n\tcase 0x14:\n\t\treturn \"UNSUBSCRIBE\";\n\tcase 0x15:\n\t\treturn \"UNSUBACK\";\n\tcase 0x16:\n\t\treturn \"PINGREQ\";\n\tcase 0x17:\n\t\treturn \"PINGRESP\";\n\tcase 0x18:\n\t\treturn \"DISCONNECT\";\n\tdefault:\n\t\treturn \"\";\n\t}\n}\n\n\n/*=====================================\n        Class MqttsnAdvrtise\n ======================================*/\nMqttsnAdvertise::MqttsnAdvertise():MqttsnMessage(){\n    setLength(5);\n    setType(MQTTSN_TYPE_ADVERTISE);\n    allocateBody();\n}\n\nMqttsnAdvertise::~MqttsnAdvertise(){\n\n}\n\nvoid MqttsnAdvertise::setGwId(uint8_t id){\n    getBody()[0] = id;\n}\n\nvoid MqttsnAdvertise::MqttsnAdvertise::setDuration(uint16_t duration){\n    uint8_t* pos = getBody() + 1;\n    setUint16(pos, duration);\n}\n\nuint8_t MqttsnAdvertise::getGwId(){\n    return getBody()[0];\n}\n\nuint16_t MqttsnAdvertise::getDuration(){\n  uint8_t* pos = getBody() + 1;\n    return getUint16(pos);\n}\n\n/*=====================================\n        Class MqttsnSearchgw\n ======================================*/\nMqttsnSearchGw::MqttsnSearchGw():MqttsnMessage(){\n    setLength(3);\n    setType(MQTTSN_TYPE_SEARCHGW);\n    allocateBody();\n}\n\nMqttsnSearchGw::~MqttsnSearchGw(){\n\n}\n\nvoid MqttsnSearchGw::setRadius(uint8_t radius){\n  getBody()[0] = radius;\n}\n\nuint8_t MqttsnSearchGw::getRadius(){\n  return getBody()[0];\n}\n\n/*=====================================\n        Class MqttsnGwinfo\n ======================================*/\nMqttsnGwInfo::MqttsnGwInfo():MqttsnMessage(){\n  setLength(3);\n  setType(MQTTSN_TYPE_GWINFO);\n  allocateBody();\n}\n\nMqttsnGwInfo::~MqttsnGwInfo(){\n\n}\n\nuint8_t MqttsnGwInfo::getGwId(){\n    return getBody()[0];\n}\n\nvoid MqttsnGwInfo::setGwId(uint8_t id){\n    getBody()[0] = id;\n}\n\n/*=====================================\n         Class MqttsnConnect\n  ======================================*/\nMqttsnConnect::MqttsnConnect(MQString* id):MqttsnMessage(){\n    setLength(id->getCharLength() + 6);\n    allocateBody();\n    setType(MQTTSN_TYPE_CONNECT);\n    getBody()[1] = MQTTSN_PROTOCOL_ID;\n    id->writeBuf(getBody() + 4);\n}\n\nMqttsnConnect::~MqttsnConnect(){\n\n}\n\nvoid MqttsnConnect::setDuration(uint16_t msec){\n    setUint16((uint8_t*)getBody() + 2, msec);\n}\n\nuint16_t MqttsnConnect::getDuration(){\n    return getUint16((uint8_t*)getBody() + 2);\n}\n\nvoid MqttsnConnect::setClientId(MQString* id){\n    id->writeBuf(getBody() + 4);\n    setLength(id->getCharLength() + 6);\n}\n\nuint8_t* MqttsnConnect::getClientId(){\n    return getBody() + 6;\n}\n\nvoid MqttsnConnect::setFrame(uint8_t* data, uint8_t len){\n    setLength(len + MQTTSN_HEADER_SIZE);\n    allocateBody();\n    memcpy(getBody(), data, len);\n    getBody()[2] = getUint16(data + 4);\n    getBody()[0] = *(data + 2);\n}\n\n/*=====================================\n        Class MqttsnConnack\n ======================================*/\nMqttsnConnack::MqttsnConnack():MqttsnMessage(){\n    setLength(3);\n    setType(MQTTSN_TYPE_CONNACK);\n    allocateBody();\n}\n\nMqttsnConnack::~MqttsnConnack(){\n\n}\n\nvoid MqttsnConnack::setReturnCode(uint8_t rc){\n    getBody()[0] = rc;\n}\n\nuint8_t MqttsnConnack::getReturnCode(){\n    return getBody()[0];\n}\n\n/*=====================================\n       Class MqttsnWillTopicReq\n======================================*/\nMqttsnWillTopicReq::MqttsnWillTopicReq():MqttsnMessage(){\n    setLength(2);\n    setType(MQTTSN_TYPE_WILLTOPICREQ);\n    allocateBody();\n}\n\nMqttsnWillTopicReq::~MqttsnWillTopicReq(){\n\n}\n\n/*=====================================\n         Class MqttsnWillTopic\n  ======================================*/\nMqttsnWillTopic::MqttsnWillTopic():MqttsnMessage(){\n    setLength(3);\n    setType(MQTTSN_TYPE_WILLTOPIC);\n    allocateBody();\n    _flags = 0;\n}\n\nMqttsnWillTopic::~MqttsnWillTopic(){\n\n}\n\n\nvoid MqttsnWillTopic::setWillTopic(MQString* topic){\n    setLength(topic->getCharLength() + 3);\n    allocateBody();\n    topic->writeBuf(getBody() + 1);\n    _msgBuff[2] = _flags;\n    _ustring.copy(topic);\n}\n\nMQString* MqttsnWillTopic::getWillTopic(){\n  if (_msgBuff){\n        return &_ustring;\n    }else{\n        return 0;\n    }\n}\n\nbool MqttsnWillTopic::isWillRequired(){\n    return getBody()[0] && MQTTSN_FLAG_WILL;\n}\n\n/*=====================================\n         Class MqttsnWillMsgReq\n  ======================================*/\nMqttsnWillMsgReq::MqttsnWillMsgReq():MqttsnMessage(){\n    setLength(2);\n    setType(MQTTSN_TYPE_WILLMSGREQ);\n    allocateBody();\n\n}\n\nMqttsnWillMsgReq::~MqttsnWillMsgReq(){\n\n}\n\n/*=====================================\n         Class MqttsnWillMsg\n  ======================================*/\nMqttsnWillMsg::MqttsnWillMsg():MqttsnMessage(){\n    setLength(2);\n    setType(MQTTSN_TYPE_WILLMSG);\n    allocateBody();\n}\n\nMqttsnWillMsg::~MqttsnWillMsg(){\n\n}\n\nvoid MqttsnWillMsg::setWillMsg(MQString* msg){\n    setLength(2 + msg->getCharLength());\n    allocateBody();\n    msg->writeBuf(getBody());\n}\n\nchar* MqttsnWillMsg::getWillMsg(){\n    if (_msgBuff){\n            return (char*)getBody();\n    }else{\n            return 0;\n    }\n}\n\n/*=====================================\n         Class MqttsnRegister\n  ======================================*/\nMqttsnRegister::MqttsnRegister():MqttsnMessage(){\n    setLength(6);\n    setType(MQTTSN_TYPE_REGISTER);\n    allocateBody();\n    _topicId = 0;\n    _msgId = 0;\n}\n\nMqttsnRegister::~MqttsnRegister(){\n\n}\n\nvoid MqttsnRegister::setTopicId(uint16_t topicId){\n  if (_msgBuff){\n            setUint16(getBody(), topicId);\n    }\n    _topicId = topicId;\n}\nuint16_t MqttsnRegister::getTopicId(){\n    return _topicId;\n}\nvoid MqttsnRegister::setMsgId(uint16_t msgId){\n    if (_msgBuff){\n            setUint16(getBody() + 2, msgId);\n    }\n    _msgId = msgId;\n}\nuint16_t MqttsnRegister::getMsgId(){\n    return _msgId;\n\n}\nvoid MqttsnRegister::setTopicName(MQString* topicName){\n    setLength(6 + topicName->getCharLength());\n    allocateBody();\n    topicName->writeBuf(getBody() + 4);\n    setTopicId(_topicId);\n    setMsgId(_msgId);\n}\n\nvoid MqttsnRegister::setFrame(uint8_t* data, uint8_t len){\n    setLength(len + MQTTSN_HEADER_SIZE);\n    allocateBody();\n    memcpy(getBody(), data, len);\n    _topicId = getUint16(data);\n    _msgId = getUint16(data + 2);\n    _ustring.readBuf(getBody() + 4);\n}\n\nvoid MqttsnRegister::setFrame(NWResponse* resp){\n    setFrame(resp->getPayload() + MQTTSN_HEADER_SIZE, resp->getPayload(0) - MQTTSN_HEADER_SIZE);\n}\n\nMQString* MqttsnRegister::getTopicName(){\n    return &_ustring;\n}\n\n/*=====================================\n         Class MqttsnRegAck\n  ======================================*/\nMqttsnRegAck::MqttsnRegAck():MqttsnMessage(){\n    setLength(7);\n    setType(MQTTSN_TYPE_REGACK);\n    allocateBody();\n}\nMqttsnRegAck::~MqttsnRegAck(){\n\n}\nvoid MqttsnRegAck::setTopicId(uint16_t topicId){\n    setUint16((uint8_t*)getBody(), topicId);\n}\nuint16_t MqttsnRegAck::getTopicId(){\n    return getUint16((unsigned char*)getBody());\n}\nvoid MqttsnRegAck::setMsgId(uint16_t msgId){\n    setUint16(getBody()+ 2,msgId);\n}\nuint16_t MqttsnRegAck::getMsgId(){\n    return getUint16((unsigned char*)getBody()+ 2);\n}\nvoid MqttsnRegAck::setReturnCode(uint8_t rc){\n    getBody()[4] = rc;\n}\nuint8_t MqttsnRegAck::getReturnCode(){\n    return (uint8_t)getBody()[4];\n}\n\n/*=====================================\n         Class MqttsnPublish\n  ======================================*/\nMqttsnPublish::MqttsnPublish():MqttsnMessage(){\n    setLength(7);\n    setType(MQTTSN_TYPE_PUBLISH);\n    allocateBody();\n    _topicId = 0;\n    _topic = 0;\n    _msgId = 0;\n}\n\nMqttsnPublish::~MqttsnPublish(){\n\n}\n\nvoid MqttsnPublish::setTopicId(uint16_t id){\n    setUint16((uint8_t*)(getBody() + 1), id);\n    _topicId = id;\n}\n\nuint16_t MqttsnPublish::getTopicId(){\n    return _topicId;\n}\n\nMQString* MqttsnPublish::getTopic(MQString* topic){\n\tchar tp[3];\n\ttp[0] = (char)*(getBody() + 1);\n\ttp[1] = (char)*(getBody() + 2);\n\ttp[2] = 0;\n\ttopic->copy(tp);\n    return topic;\n}\n\nvoid MqttsnPublish::setTopic(MQString* topic){\n\tif(topic->getCharLength() == 2){\n\t\ttopic->writeBuf((uint8_t*)(getBody() + 1));\n\t\tmemcpy((void*)&_topicId,(getBody() + 1), 2);\n\t\t_flags &= 0xfc;\n\t\t_flags |= MQTTSN_TOPIC_TYPE_SHORT;\n\t}\n}\n\nvoid MqttsnPublish::setMsgId(uint16_t msgId){\n    setUint16((uint8_t*)(getBody() + 3), msgId);\n    _msgId = msgId;\n}\n\nuint16_t MqttsnPublish::getMsgId(){\n    return _msgId;\n}\n\n\nvoid MqttsnPublish::setData(uint8_t* data, uint16_t len){\n    setLength(7 + len);\n    allocateBody();\n    memcpy(getBody() + 5, data, len);\n    setTopicId(_topicId);\n    setMsgId(_msgId);\n}\n\nvoid MqttsnPublish::setData(MQString* str){\n\tsetLength(7 + str->getCharLength());\n\tallocateBody();\n\tsetTopicId(_topicId);\n\tsetMsgId(_msgId);\n\tstr->writeBuf(getBody() + 5);\n}\n\nuint8_t*  MqttsnPublish::getData(){\n    return (uint8_t*)(getBody() + 5);\n}\n\nuint16_t  MqttsnPublish::getDataLength(){\n    return  this->getBodyLength() -  5;\n}\n\nvoid MqttsnPublish::setFrame(uint8_t* data, uint16_t len){\n\tif(len > 255){\n\t\tsetLength(len + MQTTSN_HEADER_SIZE + 2);\n\t}else{\n\t\tsetLength(len + MQTTSN_HEADER_SIZE);\n\t}\n    allocateBody();\n    memcpy(getBody(), data, len);\n    _topicId = getUint16(data + 1);\n    _msgId = getUint16(data + 3);\n    _flags = *data;\n}\n\nvoid MqttsnPublish::setFrame(NWResponse* resp){\n\tsetFrame(resp->getBody(), resp->getBodyLength());\n}\n\nvoid MqttsnPublish::setPayload(Payload* payload){\n\n}\n/*=====================================\n         Class MqttsnPubAck\n ======================================*/\nMqttsnPubAck::MqttsnPubAck():MqttsnMessage(){\n    setLength(7);\n    setType(MQTTSN_TYPE_PUBACK);\n    allocateBody();\n}\nMqttsnPubAck::~MqttsnPubAck(){\n\n}\nvoid MqttsnPubAck::setTopicId(uint16_t topicId){\n    setUint16((uint8_t*)getBody(), topicId);\n}\nuint16_t MqttsnPubAck::getTopicId(){\n    return getUint16((unsigned char*)getBody());\n}\nvoid MqttsnPubAck::setMsgId(uint16_t msgId){\n    setUint16(getBody()+ 2,msgId);\n}\nuint16_t MqttsnPubAck::getMsgId(){\n    return getUint16((unsigned char*)getBody()+ 2);\n}\nvoid MqttsnPubAck::setReturnCode(uint8_t rc){\n    getBody()[4] = rc;\n}\nuint8_t MqttsnPubAck::getReturnCode(){\n    return (uint8_t)getBody()[4];\n}\n\n/*=====================================\n         Class MqttsnPubRec\n ======================================*/\nMqttsnPubRec::MqttsnPubRec(){\n    setLength(4);\n    setType(MQTTSN_TYPE_PUBREC);\n    allocateBody();\n}\nMqttsnPubRec::~MqttsnPubRec(){\n\n}\n\nuint16_t MqttsnPubRec::getMsgId(){\n    return getUint16(getBody());\n}\n\nvoid MqttsnPubRec::setMsgId(uint16_t msgId){\n    setUint16(getBody(),msgId);\n}\n\n/*=====================================\n         Class MqttsnPubRel\n ======================================*/\nMqttsnPubRel::MqttsnPubRel(){\n    setLength(4);\n    setType(MQTTSN_TYPE_PUBREL);\n    allocateBody();\n}\n\nMqttsnPubRel::~MqttsnPubRel(){\n\n}\n\n/*=====================================\n         Class MqttsnPubComp\n ======================================*/\nMqttsnPubComp::MqttsnPubComp(){\n    setLength(4);\n    setType(MQTTSN_TYPE_PUBCOMP);\n    allocateBody();\n}\n\nMqttsnPubComp::~MqttsnPubComp(){\n\n}\n\n /*=====================================\n         Class MqttsnSubscribe\n  ======================================*/\nMqttsnSubscribe::MqttsnSubscribe(){\n    setLength(5);\n    setType(MQTTSN_TYPE_SUBSCRIBE);\n    allocateBody();\n    _topicId = 0;\n    _msgId = 0;\n    _flags = 0;\n}\n\nMqttsnSubscribe::~MqttsnSubscribe(){\n\n}\n\nvoid MqttsnSubscribe::setTopicId(uint16_t predefinedId){\n    setLength(7);\n    allocateBody();\n    setMsgId(_msgId);\n    setUint16((uint8_t*)(getBody() + 3), predefinedId);\n    setFlags(_flags | MQTTSN_TOPIC_TYPE_PREDEFINED);\n    _topicId = predefinedId;\n}\n\nuint16_t MqttsnSubscribe::getTopicId(){\n    if (_msgBuff){\n        _topicId = getUint16(getBody() +3);\n    }\n    return _topicId;\n}\nvoid MqttsnSubscribe::setMsgId(uint16_t msgId){\n    _msgId = msgId;\n    if (_msgBuff){\n       setUint16((uint8_t*)(getBody() + 1), msgId);\n    }\n}\n\nuint16_t MqttsnSubscribe::getMsgId(){\n    if (_msgBuff){\n        _msgId = getUint16(getBody() + 1);\n    }\n    return _msgId;\n}\n\nvoid MqttsnSubscribe::setTopicName(MQString* data){\n    setLength(5 + data->getCharLength());\n    allocateBody();\n    data->writeBuf(getBody() + 3);\n    setMsgId(_msgId);\n    setFlags((_flags & 0xe0) | MQTTSN_TOPIC_TYPE_NORMAL);\n    _ustring.copy(data);\n}\n\n\nMQString*  MqttsnSubscribe::getTopicName(){\n    return &_ustring;\n}\n\nvoid MqttsnSubscribe::setFrame(uint8_t* data, uint8_t len){\n    setLength(len + MQTTSN_HEADER_SIZE);\n    allocateBody();\n    memcpy(getBody(), data, len);\n    _msgId = getUint16(data + 1);\n    _flags = *data;\n    if ((_flags & MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_PREDEFINED){\n    \t_topicId = getUint16(data + 3);\n    }else{\n    \t_topicId = 0;\n\t\t_ustring.readBuf(data + 3);\n    }\n}\n\nvoid MqttsnSubscribe::setFrame(NWResponse* resp){\n\tsetFrame(resp->getPayload() + MQTTSN_HEADER_SIZE, resp->getPayload(0) - MQTTSN_HEADER_SIZE);\n}\n\n/*=====================================\n         Class MqttsnSubAck\n  ======================================*/\nMqttsnSubAck::MqttsnSubAck():MqttsnMessage(){\n    setLength(8);\n    setType(MQTTSN_TYPE_SUBACK);\n    allocateBody();\n}\n\nMqttsnSubAck::~MqttsnSubAck(){\n\n}\n\nvoid MqttsnSubAck::setTopicId(uint16_t id){\n    setUint16((uint8_t*)(getBody() + 1), id);\n}\n\nuint16_t MqttsnSubAck::getTopicId(){\n    return getUint16(getBody() + 1);\n}\nvoid MqttsnSubAck::setMsgId(uint16_t msgId){\n   setUint16((uint8_t*)(getBody() + 3), msgId);\n}\n\nuint16_t MqttsnSubAck::getMsgId(){\n    return getUint16(getBody() + 3);\n}\nvoid MqttsnSubAck::setReturnCode(uint8_t rc){\n    getBody()[6] = rc;\n}\nuint8_t  MqttsnSubAck::getReturnCode(){\n    return getBody()[5];\n}\n\n\n /*=====================================\n         Class MqttsnUnsubscribe\n  ======================================*/\nMqttsnUnsubscribe::MqttsnUnsubscribe() : MqttsnSubscribe(){\n    setType(MQTTSN_TYPE_UNSUBSCRIBE);\n}\nMqttsnUnsubscribe::~MqttsnUnsubscribe(){\n\n}\n\n/*=====================================\n         Class MqttsnUnSubAck\n  ======================================*/\nMqttsnUnSubAck::MqttsnUnSubAck():MqttsnMessage(){\n    setLength(4);\n    setType(MQTTSN_TYPE_UNSUBACK);\n    allocateBody();\n}\n\nMqttsnUnSubAck::~MqttsnUnSubAck(){\n\n}\n\nvoid MqttsnUnSubAck::setMsgId(uint16_t msgId){\n    setUint16((uint8_t*)getBody(), msgId);\n}\n\nuint16_t MqttsnUnSubAck::getMsgId(){\n    return getUint16(getBody());\n}\n\n/*=====================================\n        Class MqttsnPingReq\n ======================================*/\nMqttsnPingReq::MqttsnPingReq(MQString* id):MqttsnMessage(){\n  setLength(id->getCharLength() + 2);\n  setType(MQTTSN_TYPE_PINGREQ);\n  allocateBody();\n  id->writeBuf(getBody());\n\n}\nMqttsnPingReq::~MqttsnPingReq(){\n\n}\n\nchar* MqttsnPingReq::getClientId(){\n    return (char*)getBody();\n}\n\n/*=====================================\n        Class MqttsnPingResp\n ======================================*/\nMqttsnPingResp::MqttsnPingResp():MqttsnMessage(){\n    setLength(2);\n    setType(MQTTSN_TYPE_PINGRESP);\n    allocateBody();\n}\nMqttsnPingResp::~MqttsnPingResp(){\n\n}\n\n /*=====================================\n         Class MqttsnDisconnect\n  ======================================*/\nMqttsnDisconnect::MqttsnDisconnect():MqttsnMessage(){\n    setLength(4);\n    setType(MQTTSN_TYPE_DISCONNECT);\n    allocateBody();\n\n}\nMqttsnDisconnect::~MqttsnDisconnect(){\n\n}\nvoid MqttsnDisconnect::setDuration(uint16_t duration){\n    setUint16((uint8_t*)getBody(), duration);\n}\nuint16_t MqttsnDisconnect::getDuration(){\n    return getUint16((uint8_t*)getBody());\n}\n\n\n/*=====================================\n        Class Topic\n ======================================*/\nTopic::Topic(){\n    _topicStr = 0;\n    _callback = 0;\n    _topicId = 0;\n    _status = 0;\n}\n\nTopic::~Topic(){\n    if (_topicStr){\n        delete _topicStr;\n    }\n}\n\nuint8_t Topic::getStatus(){\n    return _status;\n}\n\nuint16_t Topic::getTopicId(){\n    return _topicId;\n}\n\nMQString* Topic::getTopicName(){\n    return _topicStr;\n}\n\nuint8_t Topic::getTopicLength(){\n    return _topicStr->getCharLength();\n}\n\nTopicCallback Topic::getCallback(){\n    return _callback;\n}\n\nvoid Topic::setTopicId(uint16_t id){\n    _topicId = id;\n}\n\nvoid Topic::setStatus(uint8_t stat){\n    _topicId = stat;\n}\n\n\nvoid Topic::setTopicName(MQString* topic){\n    _topicStr = topic;\n}\n\nvoid Topic::setCallback(TopicCallback callback){\n    _callback = callback;\n}\n\nint Topic::execCallback(MqttsnPublish* msg){\n    if(_callback != 0){\n        return _callback(msg);\n    }\n    return 0;\n}\n\nvoid Topic::copy(Topic* src){\n    setTopicId(src->getTopicId());\n    setStatus(src->getStatus());\n    setCallback(src->getCallback());\n    setCallback(_callback);\n    _topicStr = src->getTopicName();\n}\n\nuint8_t Topic::isWildCard(){\n    if (getTopicName()->getChar(getTopicName()->getCharLength() - 1) == MQTTSN_TOPIC_SINGLE_WILDCARD){\n        return MQTTSN_TOPIC_SINGLE_WILDCARD;\n    }else if (getTopicName()->getChar(getTopicName()->getCharLength() - 1) == MQTTSN_TOPIC_MULTI_WILDCARD){\n        return MQTTSN_TOPIC_MULTI_WILDCARD;\n    }\n    return 0;\n}\n\nbool Topic::isMatch(Topic* wildCard){\n    uint8_t pos = wildCard->getTopicName()->getCharLength() - 1;\n    if (wildCard->isWildCard() == MQTTSN_TOPIC_SINGLE_WILDCARD &&\n        getTopicName()->ncomp(wildCard->getTopicName(), (long)pos) == 0 ){\n        for(; pos < getTopicName()->getCharLength(); pos++){\n            if (getTopicName()->getChar(pos) == '/'){\n                return false;\n            }\n        }\n        return true;\n    }else if(wildCard->isWildCard() == MQTTSN_TOPIC_MULTI_WILDCARD &&\n        getTopicName()->ncomp(wildCard->getTopicName(), (long)pos) == 0 ){\n        return true;\n    }\n    return false;\n}\n\n/*=====================================\n        Class Topics\n ======================================*/\nTopics::Topics(){\n    _sizeMax = 0;\n    _elmCnt = 0;\n    _topics = 0;\n}\n\nTopics::~Topics() {\n\n}\n\nbool Topics::allocate(uint8_t size){\n    _elmCnt = 0;\n      _topics = (Topic*)calloc(size, sizeof(Topic));\n    if (_topics == 0){\n        _sizeMax = 0;\n        return false;\n    }else{\n        _sizeMax = size;\n        return true;\n    }\n}\n\n\nuint16_t Topics::getTopicId(MQString* topic){\n    Topic *p = getTopic(topic);\n    if ( p != 0) {\n        return p->getTopicId();\n    }\n    return 0;\n}\n\n\nTopic* Topics::getTopic(MQString* topic) {\n    for (int i = 0; i < _elmCnt; i++) {\n\t\tif ( topic->comp(_topics[i].getTopicName()) == 0) {\n            return &_topics[i];\n        }\n    }\n    return 0;\n}\n\nTopic* Topics::getTopic(uint16_t id) {\n    for (int i = 0; i < _elmCnt; i++) {\n        if ( _topics[i].getTopicId() == id) {\n            return &_topics[i];\n        }\n    }\n      return 0;\n}\n\nbool Topics::setTopicId(MQString* topic, uint16_t id){\n    Topic* p = getTopic(topic);\n    if ( p != 0) {\n        p->setTopicId(id);\n        return true;\n    }else{\n        return false;\n    }\n}\n\nbool Topics::setCallback(MQString* topic, TopicCallback callback){\n    Topic* p = getTopic(topic);\n    if ( p != 0) {\n        p->setCallback(callback);\n        return true;\n    }else{\n        return false;\n    }\n}\nbool Topics::setCallback(uint16_t topicId, TopicCallback callback){\n    Topic* p = getTopic(topicId);\n    if ( p != 0) {\n        p->setCallback(callback);\n        return true;\n    }else{\n        return false;\n    }\n}\nint Topics::execCallback(uint16_t topicId, MqttsnPublish* msg){\n    Topic* p = getTopic(topicId);\n    if ( p != 0) {\n        return p->execCallback(msg);\n    }\n    return 0;\n}\n\nint Topics::execCallback(MQString* topic, MqttsnPublish* msg){\n    Topic* p = getTopic(topic);\n    if ( p != 0) {\n        return p->execCallback(msg);\n    }\n    return 0;\n}\n\nvoid Topics::addTopic(MQString* topic){\n    if (getTopic(topic) == 0){\n        if ( _elmCnt < _sizeMax){\n            _topics[_elmCnt].setTopicName(topic);\n            _elmCnt++;\n        }else{\n            Topic* saveTopics = _topics;\n            Topic* newTopics = (Topic*)calloc(_sizeMax += MQTTSN_MAX_TOPICS + 1, sizeof(Topic));\n            if (newTopics != 0){\n                _topics = newTopics;\n                for(int i = 0; i < _elmCnt; i++){\n                    _topics[i].copy(&saveTopics[i]);\n                    saveTopics[i].setTopicName((MQString*)0);\n                }\n\n                _topics[_elmCnt].setTopicName(topic);\n                _elmCnt++;\n                if (saveTopics){\n                    delete saveTopics;\n                }\n            }\n        }\n    }\n}\n\nTopic* Topics::match(MQString* topic){\n    for ( int i = 0; i< _elmCnt; i++){\n        if (_topics[i].isWildCard()){\n            if (getTopic(topic)->isMatch(&_topics[i])){\n               return &_topics[i];\n            }\n        }\n    }\n    return 0;\n}\n\nvoid Topics::setSize(uint8_t size){\n    _sizeMax = size;\n}\n\nvoid Topics::clearTopic(void){\n\tfor( int i = 0; i < _elmCnt; i++){\n\t\tif ( _topics[i].getTopicId() >= MQTTSN_TOPICID_NORMAL) {\n\t\t\t_elmCnt = i + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n\n/*=====================================\n        Class Payload\n  =====================================*/\nPayload::Payload(){\n\t_buff = _pos = 0;\n\t_len = 0;\n\t_elmCnt = 0;\n\t_memDlt = 0;\n}\n\nPayload::Payload(uint16_t len){\n\t_buff = (uint8_t*)calloc(len, sizeof(uint8_t));\n\tif(_buff == 0){\n\t\texit(-1);\n\t}\n\t_pos = _buff;\n\t_elmCnt = 0;\n\t_len = len;\n\t_memDlt = 1;\n}\n\nPayload::~Payload(){\n\tif(_memDlt){\n\t\tfree(_buff);\n\t}\n}\n\nvoid Payload::init(){\n\t_pos = _buff;\n\t_elmCnt = 0;\n}\n\n\nvoid Payload::getPayload(MqttsnPublish* msg){\n\tif(_memDlt){\n\t\t\tfree(_buff);\n\t\t\t_memDlt = 0;\n\t}\n\t_buff = msg->getData();\n\t_len = msg->getDataLength();\n\t_pos = _buff + _len;\n\t/*\n\tfor(uint8_t i; i < MSGPACK_MAX_ELEMENTS; i++){\n\t\tif(getBufferPos(i) != 0){\n\t\t\t_elmCnt++;\n\t\t}else{\n\t\t\tbreak;\n\t\t}\n\t}\n\t*/\n\t_elmCnt = 6;\n}\n\nuint16_t Payload::getAvailableLength(){\n\treturn _len - (_pos - _buff);\n}\n\nuint16_t Payload::getLen(){\n\treturn _pos - _buff;\n}\n\nuint8_t* Payload::getBuf(){\n\treturn _buff;\n}\n\n/*======================\n *     setter\n ======================*/\nint8_t Payload::set_uint32(uint32_t val){\n\tif(getAvailableLength() < 6){\n\t\treturn -1;\n\t}\n\tif(val < 128){\n\t\t*_pos++ = (uint8_t)val;\n\t}else if(val < 256){\n\t\t*_pos++ = MSGPACK_UINT8;\n\t\t*_pos++ = (uint8_t)val;\n\t}else if(val < 65536){\n\t\t*_pos++ = MSGPACK_UINT16;\n\t\tsetUint16(_pos,(uint16_t) val);\n\t\t_pos += 2;\n\t}else{\n\t\t*_pos++ = MSGPACK_UINT32;\n\t\tsetUint32(_pos, val);\n\t\t_pos += 4;\n\t}\n\t_elmCnt++;\n\treturn 0;\n}\n\nint8_t Payload::set_int32(int32_t val){\n\tif(getAvailableLength() < 6){\n\t\t\treturn -1;\n\t}\n\tif((val > -32) && (val < 0)){\n\t\t*_pos++ = val | MSGPACK_NEGINT;\n\t}else if((val >= 0) && (val < 128)){\n\t\t*_pos++ = val;\n\t}else if(val > -128 && val < 128){\n\t\t*_pos++ = MSGPACK_INT8;\n\t\t*_pos++ = (uint8_t)val;\n\t}else if(val > -32768 && val < 32768){\n\t\t*_pos++ = MSGPACK_INT16;\n\t\tsetUint16(_pos, (uint16_t)val);\n\t\t_pos += 2;\n\t}else{\n\t\t*_pos++ = MSGPACK_INT32;\n\t\tsetUint32(_pos, (uint32_t)val);\n\t\t_pos += 4;\n\t}\n\t_elmCnt++;\n\treturn 0;\n}\n\nint8_t Payload::set_float(float val){\n\tif(getAvailableLength() < 6){\n\t\t\treturn -1;\n\t}\n\t*_pos++ = MSGPACK_FLOAT32;\n\tsetFloat32(_pos, val);\n\t_pos += 4;\n\t_elmCnt++;\n\treturn 0;\n}\n\nint8_t Payload::set_str(char* val){\n\treturn set_str((const char*) val);\n}\n\nint8_t Payload::set_str(const char* val){\n\tif(getAvailableLength() < strlen(val) + 3){\n\t\treturn -1;\n\t}else if(strlen(val) < 32){\n\t\t*_pos++ = (uint8_t)strlen(val) | MSGPACK_FIXSTR;\n\t}else if(strlen(val) < 256){\n\t\t*_pos++ = MSGPACK_STR8;\n\t\t*_pos++ = (uint8_t)strlen(val);\n\t}else if(strlen(val) < 65536){\n\t\t*_pos++ = MSGPACK_STR16;\n\t\tsetUint16(_pos, (uint16_t)strlen(val));\n\t\t_pos += 2;\n\t}\n\tmemcpy(_pos, val, strlen(val));\n\t_pos += strlen(val);\n\treturn 0;\n}\n\nint8_t Payload::set_array(uint8_t val){\n\tif(getAvailableLength() < (uint16_t)val+ 1){\n\t\treturn -1;\n\t}\n\tif(val < 16){\n\t\t*_pos++ = MSGPACK_ARRAY15 | val;\n\t}else{\n\t\t*_pos++ = MSGPACK_ARRAY16;\n\t\tsetUint16(_pos,(uint16_t)val);\n\t\t_pos += 2;\n\t}\n\t_elmCnt++;\n\treturn 0;\n}\n\n/*======================\n *     getter\n ======================*/\nuint8_t Payload::getArray(uint8_t index){\n\tuint8_t rc = 0;\n\tuint8_t* val = getBufferPos(index);\n\tif(val != 0){\n\t\tif(*val == MSGPACK_ARRAY15){\n\t\t\trc = *val & 0x0F;\n\t\t}else if(*val == MSGPACK_ARRAY16){\n\t\t\trc = (uint8_t)getUint16(val + 1);\n\t\t}\n\t}\n\treturn rc;\n}\n\nuint32_t Payload::get_uint32(uint8_t index){\n\tuint32_t rc = 0;\n\tuint8_t* val = getBufferPos(index);\n\tif(val != 0){\n\t\tif(*val == MSGPACK_UINT32){\n\t\t\trc = getUint32(val + 1);\n\t\t}else if(*val == MSGPACK_UINT16){\n\t\t\trc = (uint32_t)getUint16(val + 1);\n\t\t}else if(*val == MSGPACK_UINT8){\n\t\t\trc = (uint32_t)*(val + 1);\n\t\t}else if(*val < 128){\n\t\t\trc = (uint32_t)*val;\n\t\t}\n\t}\n\treturn rc;\n}\n\nint32_t Payload::get_int32(uint8_t index){\n\tint32_t rc = 0;\n\tuint8_t* val = getBufferPos(index);\n\tif(val != 0){\n\t\tif(*val == MSGPACK_INT32){\n\t\t\trc = (int32_t) getUint32(val + 1);\n\t\t}else if(*val == MSGPACK_INT16){\n\t\t\tuint16_t d16 = getUint16(val + 1);\n\t\t\tif(d16 >= 32768){\n\t\t\t\trc = d16 - 65536;\n\t\t\t}else{\n\t\t\t\trc = (int32_t)d16;\n\t\t\t}\n\t\t}else if(*val == MSGPACK_INT8){\n\t\t\trc = (int32_t)*(val + 1);\n\t\t}else if((*val & MSGPACK_NEGINT) == MSGPACK_NEGINT){\n\t\t\t*val &= ~MSGPACK_NEGINT;\n\t\t\trc = ((int32_t)*val) * -1;\n\t\t}else{\n\t\t\trc = (int32_t) *val;\n\t\t}\n\t}\n\treturn rc;\n}\n\nfloat Payload::get_float(uint8_t index){\n\tuint8_t* val = getBufferPos(index);\n\tif(val != 0){\n\t\tif(*val == MSGPACK_FLOAT32){\n\t\t\treturn getFloat32(val + 1);\n\t\t}\n\t}\n\treturn 0;\n}\n\nconst char* Payload::get_str(uint8_t index, uint16_t* len){\n\tuint8_t* val = getBufferPos(index);\n\tif(val != 0){\n\t\tif(*val == MSGPACK_STR16){\n\t\t\t*len = getUint16(val + 1);\n\t\t\treturn (const char*)(val + 3);\n\t\t}else if(*val == MSGPACK_STR8){\n\t\t\t*len = *(val + 1);\n\t\t\treturn (const char*)(val + 2);\n\t\t}else if(*val & MSGPACK_FIXSTR){\n\t\t\t*len = *val & (~MSGPACK_FIXSTR);\n\t\t\treturn (const char*)(val + 1);\n\t\t}\n\t}\n\t*len = 0;\n\treturn (const char*) 0;\n\n}\n\n\nuint8_t* Payload::getBufferPos(uint8_t index){\n\tuint8_t* bpos = 0;\n\tuint8_t* pos = _buff;\n\n\tfor(uint8_t i = 0; i <= index; i++){\n\t\tbpos = pos;\n\t\tswitch(*pos){\n\t\tcase MSGPACK_FALSE:\n\t\tcase MSGPACK_TRUE:\n\t\t\tpos++;\n\t\t\tbreak;\n\t\tcase MSGPACK_UINT8:\n\t\tcase MSGPACK_INT8:\n\t\t\tpos += 2;\n\t\t\tbreak;\n\t\tcase MSGPACK_UINT16:\n\t\tcase MSGPACK_INT16:\n\t\tcase MSGPACK_ARRAY16:\n\t\t\tpos += 3;\n\t\t\tbreak;\n\t\tcase MSGPACK_UINT32:\n\t\tcase MSGPACK_INT32:\n\t\tcase MSGPACK_FLOAT32:\n\t\t\tpos += 5;\n\t\t\tbreak;\n\t\tcase MSGPACK_STR8:\n\t\t\tpos += *(pos + 1) + 2;\n\t\t\tbreak;\n\t\tcase MSGPACK_STR16:\n\t\t\tpos += getUint16(pos + 1) + 3;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif((*pos < MSGPACK_POSINT) ||\n\t\t\t\t((*pos & MSGPACK_NEGINT) == MSGPACK_NEGINT) ||\n\t\t\t\t((*pos & MSGPACK_ARRAY15) == MSGPACK_ARRAY15)) {\n\t\t\t\tpos++;\n\t\t\t}else if((*pos & MSGPACK_FIXSTR) == MSGPACK_FIXSTR){\n\t\t\t\tpos += *pos & (~MSGPACK_FIXSTR);\n\t\t\t}\n\t\t}\n\t\t/*\n\t\tif((pos - _buff) >= _len){\n\t\t\treturn 0;\n\t\t}\n\t\t*/\n\t}\n\treturn bpos;\n}\n\nvoid Payload::print(){\n\tfor(uint8_t* pos = _buff; pos < _pos; pos++){\n\t\tprintf(\" 0x%x\", *pos);\n\t}\n\tprintf(\"\\n\");\n}\n\n/*=====================================\n        Class PublishHandller\n ======================================*/\nPublishHandller::PublishHandller(){\n\n}\nPublishHandller::~PublishHandller(){\n\n}\nint PublishHandller::exec(MqttsnPublish* msg, Topics* topics){\n\tMQString tp = MQString();\n\tif((msg->getFlags() && MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_SHORT){\n\t\tif (topics->getTopic(msg->getTopic(&tp))){\n\t\t\treturn topics->getTopic(msg->getTopic(&tp))->execCallback(msg);\n\t\t}\n\t}else{\n\t\tif (topics->getTopic(msg->getTopicId())){\n\t\t\treturn topics->getTopic(msg->getTopicId())->execCallback(msg);\n\t\t}\n\t}\n    return 0;\n}\n\n\n\n/////////////////// End of File ///////////////\n"
  },
  {
    "path": "Client/src/lib/mqttsn.h",
    "content": "/*\n * mqttsn.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef MQTTS_H_\n#define MQTTS_H_\n\n#ifdef ARDUINO\n        #include <MQTTSN_Application.h>\n#else\n        #include \"MQTTSN_Application.h\"\n#endif\n\n#if defined(ARDUINO) && ARDUINO >= 100\n        #include \"Arduino.h\"\n        #include <inttypes.h>\n        #include <Network.h>\n#endif\n\n#if defined(ARDUINO) && ARDUINO < 100\n        #include \"WProgram.h\"\n        #include <inttypes.h>\n        #include <Network.h>\n#endif\n\n#ifdef LINUX\n        #include <sys/time.h>\n        #include <iostream>\n        #include \"Network.h\"\n#endif\n\n#ifdef MBED\n        #include \"mbed.h\"\n        #include \"Network.h\"\n#endif\n\n\n                              /* [sec] */\n#define MQTTSN_DEFAULT_KEEPALIVE 3600     // 1H\n#define MQTTSN_DEFAULT_DURATION   900     // 15min\n#define MQTTSN_TIME_SEARCHGW        3\n#define MQTTSN_TIME_RETRY          10\n#define MQTTSN_TIME_WAIT          300     //  5min\n#define MQTTSN_RETRY_COUNT          5\n\n#define MQTTSN_MAX_TOPICS         15\n#define MQTTSN_MAX_PACKET_LENGTH  60\n\n#define MQTTSN_TYPE_ADVERTISE     0x00\n#define MQTTSN_TYPE_SEARCHGW      0x01\n#define MQTTSN_TYPE_GWINFO        0x02\n#define MQTTSN_TYPE_CONNECT       0x04\n#define MQTTSN_TYPE_CONNACK       0x05\n#define MQTTSN_TYPE_WILLTOPICREQ  0x06\n#define MQTTSN_TYPE_WILLTOPIC     0x07\n#define MQTTSN_TYPE_WILLMSGREQ    0x08\n#define MQTTSN_TYPE_WILLMSG       0x09\n#define MQTTSN_TYPE_REGISTER      0x0A\n#define MQTTSN_TYPE_REGACK        0x0B\n#define MQTTSN_TYPE_PUBLISH       0x0C\n#define MQTTSN_TYPE_PUBACK        0x0D\n#define MQTTSN_TYPE_PUBCOMP       0x0E\n#define MQTTSN_TYPE_PUBREC        0x0F\n#define MQTTSN_TYPE_PUBREL        0x10\n#define MQTTSN_TYPE_SUBSCRIBE     0x12\n#define MQTTSN_TYPE_SUBACK        0x13\n#define MQTTSN_TYPE_UNSUBSCRIBE   0x14\n#define MQTTSN_TYPE_UNSUBACK      0x15\n#define MQTTSN_TYPE_PINGREQ       0x16\n#define MQTTSN_TYPE_PINGRESP      0x17\n#define MQTTSN_TYPE_DISCONNECT    0x18\n#define MQTTSN_TYPE_WILLTOPICUPD  0x1A\n#define MQTTSN_TYPE_WILLTOPICRESP 0x1B\n#define MQTTSN_TYPE_WILLMSGUPD    0x1C\n#define MQTTSN_TYPE_WILLMSGRESP   0x1D\n\n#define MQTTSN_TOPIC_TYPE_NORMAL     0x00\n#define MQTTSN_TOPIC_TYPE_PREDEFINED 0x01\n#define MQTTSN_TOPIC_TYPE_SHORT      0x02\n#define MQTTSN_TOPIC_TYPE            0x03\n\n#define MQTTSN_FLAG_DUP     0x80\n#define MQTTSN_FLAG_QOS_0   0x0\n#define MQTTSN_FLAG_QOS_1   0x20\n#define MQTTSN_FLAG_QOS_2   0x40\n#define MQTTSN_FLAG_QOS_N1  0xc0\n#define MQTTSN_FLAG_RETAIN  0x10\n#define MQTTSN_FLAG_WILL    0x08\n#define MQTTSN_FLAG_CLEAN   0x04\n\n#define MQTTSN_PROTOCOL_ID  0x01\n#define MQTTSN_HEADER_SIZE  2\n\n#define MQTTSN_RC_ACCEPTED                  0x00\n#define MQTTSN_RC_REJECTED_CONGESTION       0x01\n#define MQTTSN_RC_REJECTED_INVALID_TOPIC_ID 0x02\n#define MQTTSN_RC_REJECTED_NOT_SUPPORTED    0x03\n\n#define MQTTSN_MSG_REQUEST     1\n#define MQTTSN_MSG_RESEND_REQ  2\n#define MQTTSN_MSG_WAIT_ACK    3\n#define MQTTSN_MSG_COMPLETE    4\n#define MQTTSN_MSG_REJECTED    5\n\n\n#define MQTTSN_GW_INIT         0\n#define MQTTSN_GW_SEARCHING    1\n#define MQTTSN_GW_FOUND        2\n#define MQTTSN_GW_CONNECTED    3\n#define MQTTSN_GW_DISCONNECTED 4\n#define MQTTSN_GW_LOST         5\n\n#define MQTTSN_ERR_NO_ERROR            0\n#define MQTTSN_ERR_NOT_CONNECTED      -11\n#define MQTTSN_ERR_RETRY_OVER         -12\n#define MQTTSN_ERR_GATEWAY_LOST       -13\n#define MQTTSN_ERR_CANNOT_ADD_REQUEST -14\n#define MQTTSN_ERR_NO_TOPICID         -15\n#define MQTTSN_ERR_REJECTED           -16\n#define MQTTSN_ERR_WAIT_GWINFO        -17\n#define MQTTSN_ERR_OUT_OF_MEMORY      -18\n#define MQTTSN_ERR_PING_REQUIRED      -19\n#define MQTTSN_ERR_ACK_TIMEOUT        -20\n#define MQTTSN_ERR_PINGRESP_TIMEOUT   -21\n#define MQTTSN_ERR_INVALID_TOPICID    -22\n#define MQTTSN_ERR_NO_DATA            -23\n#define MQTTSN_ERR_REBOOT_REQUIRED    -24\n#define MQTTSN_READ_RESP_ONCE_MORE    -25\n\n#define MQTTSN_TOPIC_MULTI_WILDCARD   '#'\n#define MQTTSN_TOPIC_SINGLE_WILDCARD  '+'\n\n#define MQTTSN_TOPICID_NORMAL 256\n#define MQTTSN_TOPICID_PREDEFINED_TIME   0x0001\n#define MQTTSN_TOPIC_PREDEFINED_TIME     (\"$GW/01\")\n\n#define QOS0  0\n#define QOS1  1\n#define QOS2  2\n\n#define MSGPACK_FALSE    0xc2\n#define MSGPACK_TRUE     0xc3\n#define MSGPACK_POSINT   0x80\n#define MSGPACK_NEGINT   0xe0\n#define MSGPACK_UINT8    0xcc\n#define MSGPACK_UINT16   0xcd\n#define MSGPACK_UINT32   0xce\n#define MSGPACK_INT8     0xd0\n#define MSGPACK_INT16    0xd1\n#define MSGPACK_INT32    0xd2\n#define MSGPACK_FLOAT32  0xca\n#define MSGPACK_FIXSTR   0xa0\n#define MSGPACK_STR8     0xd9\n#define MSGPACK_STR16    0xda\n#define MSGPACK_ARRAY15  0x90\n#define MSGPACK_ARRAY16  0xdc\n#define MSGPACK_MAX_ELEMENTS   50   // Less than 256\n\nusing namespace tomyClient;\n\n/*=====================================\n        Class MQString\n =====================================*/\nclass MQString{\npublic:\n    MQString();\n    MQString(const char*);\n    MQString(char*);\n    ~MQString();\n    uint16_t getCharLength();\n    int     comp(MQString* str);\n    int     comp(const char* str);\n    int     ncomp(MQString* str, uint16_t n);\n    void    copy(MQString* str);\n    void    copy(const char* str);\n    void    copy(char* str);\n    void    copy(uint8_t* str, uint8_t len);\n    MQString* create();\n    void    writeBuf(uint8_t* buf);\n    void    readBuf(uint8_t* buf);\n    uint8_t getChar(uint8_t index);\n    char*  getStr();\n    const char* getConstStr();\n    bool    isConst();\n    bool operator==(MQString&);\n    bool operator!=(MQString&);\nprivate:\n    void    freeStr();\n    char*    _str;\n    const char* _constStr;\n};\n\n/*=====================================\n        Class MqttsnMessage\n  =====================================*/\nclass MqttsnMessage {\npublic:\n    MqttsnMessage();\n    ~MqttsnMessage();\n    void   setLength(uint16_t length);\n    void   setType(uint8_t type);\n    bool   setBody(uint8_t* body);\n    bool   allocateBody();\n    void   setStatus(uint8_t stat);\n    void   setDup();\n    void   setQos(uint8_t qos);\n    void   setRetain(bool flg);\n    void   setFlags(uint8_t flag);\n    uint8_t getLength();\n    uint8_t getType();\n    uint8_t getFlags();\n    uint8_t getStatus();\n    uint8_t getQos();\n    uint8_t* getBody();\n    uint8_t* getMsgBuff();\n    uint16_t getFrameLength();\n    uint16_t getBodyLength();\n    bool    isDup();\n    bool    copy(MqttsnMessage* src);\n    void    reset();\n    void    setMsgBuff(uint8_t* buff);\n    const char* getMsgTypeName();\nprotected:\n    uint8_t* _msgBuff;\n    uint8_t  _flags;\nprivate:\n    uint8_t  _status; // 1:request 2:sending 3:resending 4:waitingAck  5:complite\n    uint8_t  _type;\n    uint16_t  _length;\n};\n\n/*=====================================\n        Class MqttsnAdvertize\n ======================================*/\nclass MqttsnAdvertise : public MqttsnMessage {\npublic:\n  MqttsnAdvertise();\n  ~MqttsnAdvertise();\n  void setGwId(uint8_t id);\n  void setDuration(uint16_t duration);\n  uint8_t getGwId();\n  uint16_t getDuration();\n\nprivate:\n};\n\n/*=====================================\n        Class MqttsnSearchGw\n ======================================*/\nclass MqttsnSearchGw : public MqttsnMessage {\npublic:\n    MqttsnSearchGw();\n  ~MqttsnSearchGw();\n  void setRadius(uint8_t radius);\n  uint8_t getRadius();\n\nprivate:\n};\n\n/*=====================================\n        Class MqttsnGwinfo\n ======================================*/\nclass MqttsnGwInfo : public MqttsnMessage {\npublic:\n  MqttsnGwInfo();\n  ~MqttsnGwInfo();\n  void setGwId(uint8_t id);\n  uint8_t getGwId();\n\nprivate:\n};\n\n/*=====================================\n         Class MqttsnConnect\n  ======================================*/\nclass MqttsnConnect : public MqttsnMessage {\npublic:\n    MqttsnConnect(MQString* id);\n    ~MqttsnConnect();\n    void setDuration(uint16_t msec);\n    void setClientId(MQString* id);\n    uint8_t* getClientId();\n    uint16_t getDuration();\n    void setFrame(uint8_t* data, uint8_t len);\nprivate:\n };\n\n/*=====================================\n        Class MqttsnConnack\n ======================================*/\nclass MqttsnConnack : public MqttsnMessage  {\npublic:\n    MqttsnConnack();\n    ~MqttsnConnack();\n    void setReturnCode(uint8_t rc);\n    uint8_t getReturnCode();\n\nprivate:\n\n};\n\n/*=====================================\n         Class MqttsnWillTopicReq\n  ======================================*/\nclass MqttsnWillTopicReq : public MqttsnMessage  {\npublic:\n    MqttsnWillTopicReq();\n    ~MqttsnWillTopicReq();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnWillTopic\n  ======================================*/\nclass MqttsnWillTopic : public MqttsnMessage  {\npublic:\n    MqttsnWillTopic();\n    ~MqttsnWillTopic();\n    void setWillTopic(MQString* topic);\n    MQString* getWillTopic();\n    bool isWillRequired();\n\nprivate:\n    MQString _ustring;\n };\n\n/*=====================================\n         Class MqttsnWillMsgReq\n  ======================================*/\nclass MqttsnWillMsgReq : public MqttsnMessage  {\npublic:\n    MqttsnWillMsgReq();\n    ~MqttsnWillMsgReq();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnWillMsg\n  ======================================*/\nclass MqttsnWillMsg : public MqttsnMessage  {\npublic:\n    MqttsnWillMsg();\n    ~MqttsnWillMsg();\n    void setWillMsg(MQString* msg);\n    char* getWillMsg();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnRegister\n  ======================================*/\nclass MqttsnRegister : public MqttsnMessage  {\npublic:\n    MqttsnRegister();\n    ~MqttsnRegister();\n    void setTopicId(uint16_t topicId);\n    uint16_t getTopicId();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n    void setTopicName(MQString* topicName);\n    void setFrame(uint8_t* data, uint8_t len);\n    void setFrame(NWResponse* resp);\n    MQString* getTopicName();\n\nprivate:\n    uint16_t _topicId;\n    uint16_t _msgId;\n    MQString _ustring;\n\n };\n\n/*=====================================\n         Class MqttsnRegAck\n  ======================================*/\nclass MqttsnRegAck : public MqttsnMessage  {\npublic:\n    MqttsnRegAck();\n    ~MqttsnRegAck();\n    void setTopicId(uint16_t topicId);\n    uint16_t getTopicId();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n    void setReturnCode(uint8_t rc);\n    uint8_t getReturnCode();\n\nprivate:\n\n };\n\n /*=====================================\n         Class MqttsnPublish\n  ======================================*/\nclass Payload;\n\nclass MqttsnPublish : public MqttsnMessage  {\npublic:\n    MqttsnPublish();\n    ~MqttsnPublish();\n    void setTopicId(uint16_t id);\n    void setTopic(MQString* topic);\n    void setMsgId(uint16_t msgId);\n    void setData(uint8_t* data, uint16_t len);\n    void setData(MQString* str);\n    void setFrame(uint8_t* data, uint16_t len);\n    void setFrame(NWResponse* resp);\n    void setPayload(Payload* payload);\n    MQString* getTopic(MQString* topic);\n    uint16_t getMsgId();\n    uint16_t getTopicId();\n\n    uint8_t* getData();\n    uint16_t getDataLength();\n\nprivate:\n    uint16_t _topicId;\n    uint16_t _msgId;\n    MQString* _topic;\n };\n\n/*=====================================\n         Class MqttsnPubAck\n  ======================================*/\nclass MqttsnPubAck : public MqttsnMessage  {\npublic:\n    MqttsnPubAck();\n    ~MqttsnPubAck();\n    void setTopicId(uint16_t id);\n    uint16_t getTopicId();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n    void setReturnCode(uint8_t rc);\n    uint8_t getReturnCode();\n\n\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnPubRec\n  ======================================*/\nclass MqttsnPubRec : public MqttsnMessage  {\npublic:\n\tMqttsnPubRec();\n    ~MqttsnPubRec();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnPubRel\n  ======================================*/\nclass MqttsnPubRel : public MqttsnPubRec  {\npublic:\n\tMqttsnPubRel();\n    ~MqttsnPubRel();\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnPubComp\n  ======================================*/\nclass MqttsnPubComp : public MqttsnPubRec  {\npublic:\n\tMqttsnPubComp();\n    ~MqttsnPubComp();\nprivate:\n\n };\n\n /*=====================================\n         Class MqttsnSubscribe\n  ======================================*/\nclass MqttsnSubscribe : public MqttsnMessage  {\npublic:\n    MqttsnSubscribe();\n    ~MqttsnSubscribe();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n    uint16_t getTopicId();\n    MQString* getTopicName();\n    void setTopicId(uint16_t predefinedId);\n\tvoid setFrame(uint8_t* data, uint8_t len);\n\tvoid setFrame(NWResponse* resp);\n    void setTopicName(MQString* topicName);\nprotected:\n    uint16_t _topicId;\n    uint16_t _msgId;\n    MQString _ustring;\n };\n\n/*=====================================\n         Class MqttsnSubAck\n  ======================================*/\nclass MqttsnSubAck : public MqttsnMessage  {\npublic:\n    MqttsnSubAck();\n    ~MqttsnSubAck();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n    void setTopicId(uint16_t topicId);\n    uint16_t getTopicId();\n    void setReturnCode(uint8_t rc);\n    uint8_t getReturnCode();\n\nprivate:\n\n };\n\n /*=====================================\n         Class MqttsnUnsubscribe\n  ======================================*/\nclass MqttsnUnsubscribe : public MqttsnSubscribe  {\npublic:\n    MqttsnUnsubscribe();\n    ~MqttsnUnsubscribe();\nprivate:\n\n };\n\n/*=====================================\n         Class MqttsnUnSubAck\n  ======================================*/\nclass MqttsnUnSubAck : public MqttsnMessage  {\npublic:\n    MqttsnUnSubAck();\n    ~MqttsnUnSubAck();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n\nprivate:\n\n };\n\n/*=====================================\n        Class MqttsnPingReq\n ======================================*/\nclass MqttsnPingReq : public MqttsnMessage  {\npublic:\n    MqttsnPingReq(MQString* id);\n    ~MqttsnPingReq();\n    char* getClientId();\nprivate:\n\n};\n\n/*=====================================\n        Class MqttsnPingResp\n ======================================*/\nclass MqttsnPingResp : public MqttsnMessage  {\npublic:\n    MqttsnPingResp();\n    ~MqttsnPingResp();\nprivate:\n\n};\n\n /*=====================================\n         Class MqttsnDisconnect\n  ======================================*/\nclass MqttsnDisconnect : public MqttsnMessage  {\npublic:\n    MqttsnDisconnect();\n    ~MqttsnDisconnect();\n    void setDuration(uint16_t duration);\n    uint16_t getDuration();\nprivate:\n\n };\n\n/*=====================================\n        Class Topic\n ======================================*/\ntypedef int (*TopicCallback)(MqttsnPublish*);\n\nclass Topic {\npublic:\n    Topic();\n    ~Topic();\n    uint8_t   getStatus();\n    uint16_t  getTopicId();\n    MQString*  getTopicName();\n    uint8_t   getTopicLength();\n    uint8_t   getTopicType();\n    TopicCallback getCallback();\n    void     setTopicId(uint16_t id);\n    void     setTopicName(MQString* topic);\n    void     setStatus(uint8_t stat);\n    int      execCallback(MqttsnPublish* msg);\n    void     copy(Topic* src);\n    void     setCallback(TopicCallback callback);\n    uint8_t   isWildCard();\n    bool     isMatch(Topic* wildCard);\nprivate:\n    uint16_t  _topicId;\n    uint8_t   _status;\n    MQString*  _topicStr;\n    TopicCallback  _callback;\n};\n\n/*=====================================\n        Class Topics\n ======================================*/\nclass Topics {\npublic:\n      Topics();\n      ~Topics();\n      bool     allocate(uint8_t topicsSize);\n      uint16_t  getTopicId(MQString* topic);\n      Topic*    getTopic(MQString* topic);\n      Topic*    getTopic(uint16_t topicId);\n      bool     setTopicId(MQString* topic, uint16_t id);\n      bool     setCallback(MQString* topic, TopicCallback callback);\n      bool     setCallback(uint16_t topicId, TopicCallback callback);\n      int      execCallback(uint16_t  topicId, MqttsnPublish* msg);\n      int      execCallback(MQString* topic, MqttsnPublish* msg);\n      void     addTopic(MQString* topic);\n      Topic*    match(MQString* topic);\n      void     setSize(uint8_t size);\n      void     clearTopic(void);\n\nprivate:\n\n    uint8_t   _sizeMax;\n    uint8_t   _elmCnt;\n    Topic*  _topics;\n\n};\n\n/*=====================================\n        Class Payload\n  =====================================*/\nclass Payload{\npublic:\n\tPayload();\n\tPayload(uint16_t len);\n\t~Payload();\n\tvoid init(void);\n\tint8_t set_uint32(uint32_t val);\n\tint8_t set_int32(int32_t val);\n\tint8_t set_float(float val);\n\tint8_t set_str(char* val);\n\tint8_t set_str(const char* val);\n\tint8_t set_array(uint8_t val);\n\n\tuint8_t getArray(uint8_t index);\n\tuint32_t get_uint32(uint8_t index);\n\tint32_t  get_int32(uint8_t index);\n    float    get_float(uint8_t index);\n    const char* get_str(uint8_t index, uint16_t* len);\n\n\tvoid \t getPayload(MqttsnPublish* msg);\n\tuint16_t getAvailableLength();\n\tuint16_t getLen();\n\tuint8_t* getBuf();\n\n\tvoid print();\nprivate:\n\tuint8_t* getBufferPos(uint8_t index);\n\tuint8_t* _buff;\n\tuint16_t _len;\n\tuint8_t  _elmCnt;\n\tuint8_t* _pos;\n\tuint8_t  _memDlt;\n};\n\n/*=====================================\n        Class Publish Handler\n ======================================*/\nclass PublishHandller {\npublic:\n    PublishHandller();\n    ~PublishHandller();\n    int exec(MqttsnPublish* msg, Topics* topics);\n\n};\n\n\n#endif  /* MQTTS_H_ */\n"
  },
  {
    "path": "Client/src/lib/mqttsnClient.cpp",
    "content": "/*\n * mqttsnClient.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/11/25\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.1.1\n */\n\n#ifdef ARDUINO\n\n#endif  /* ARDUINO */\n\n#ifdef ARDUINO\n\t#include <MQTTSN_Application.h>\n\t#include <mqUtil.h>\n\t#include <mqttsnClient.h>\n\t#if defined(MQTTSN_DEBUG) || defined(NW_DEBUG) || defined(DEBUG)\n\t\t#include <SoftwareSerial.h>\n\t\textern SoftwareSerial debug;\n\t#endif\n#else\n\t#include \"MQTTSN_Application.h\"\n\t#include \"mqUtil.h\"\n\t#include \"mqttsnClient.h\"\n#endif\n\n#ifdef MBED\n  #include \"mbed.h\"\n#endif  /* MBED */\n\n#ifdef LINUX\n  #include <stdio.h>\n  #include <sys/time.h>\n  #include <sys/types.h>\n  #include <sys/stat.h>\n  #include <unistd.h>\n  #include <stdlib.h>\n  #include <string.h>\n  #include <fcntl.h>\n  #include <errno.h>\n  #include <termios.h>\n#endif /* LINUX */\n\n\nusing namespace std;\nusing namespace tomyClient;\n\nextern OnPublishList theOnPublishList[];\nextern APP_CONFIG theAppConfig;\nextern MQString* theTopics[];\n\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern float    getFloat32(uint8_t* pos);\n\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\nextern void setFloat32(uint8_t* pos, float val);\n\nstatic MqttsnClient*  theMqttsn;\n\n/*=================================================================\n\n        Class MqttsnnClient\n\n ================================================================*/\nvoid ResponseHandler(NWResponse* resp, int* returnCode){\n        theMqttsn->recieveMessageHandler(resp, returnCode);\n}\n\nMqttsnClient::MqttsnClient(){\n    _network = new Network();\n    _network->setRxHandler(ResponseHandler);\n    _sendQ = new SendQue();\n    _duration = 0;\n    _clientId = new MQString();\n    _clientFlg = 0;\n    _nRetry = MQTTSN_RETRY_COUNT;\n    _nRetryCnt = 0;\n    _tRetry = 0;\n    _willTopic = _willMessage = 0;\n    _clientStatus.setKeepAlive(MQTTSN_DEFAULT_KEEPALIVE);\n    _msgId = 0;\n    _topics.allocate(MQTTSN_MAX_TOPICS + 1);\n    _sendFlg = false;\n    _subscribingFlg = false;\n    theMqttsn = this;\n}\n\nMqttsnClient::~MqttsnClient(){\n  _sendQ->deleteAllRequest();\n  delete _network;\n}\n\n\nint MqttsnClient::initialize(APP_CONFIG config){\n    _clientId->copy(config.mqttsnCfg.nodeId);\n    MQString* pre1 = new MQString(MQTTSN_TOPIC_PREDEFINED_TIME);\n    _topics.addTopic(pre1);\n    _topics.setTopicId(pre1,MQTTSN_TOPICID_PREDEFINED_TIME);\n    return _network->initialize(config.netCfg);\n}\n\nvoid MqttsnClient::subscribe(){\n\tfor(int i = 0; theOnPublishList[i].pubCallback; i++){\n\t\tsubscribe(theOnPublishList[i].topic, theOnPublishList[i].pubCallback, theOnPublishList[i].qos);\n\t}\n}\n\nvoid MqttsnClient::createTopics(){\n\tfor(int i = 0; theTopics[i]; i++){\n\t\tregisterTopic(theTopics[i]);\n\t}\n}\n\nvoid MqttsnClient::setSubscribing(bool flg){\n\t_clientStatus.setSubscribing(flg);\n}\n\nint MqttsnClient::readPacket(){\n\treturn _network->readPacket(1); // XBee: Modem Staus, UDP: neglect\n}\n\nTopics* MqttsnClient::getTopics(){\n    return &_topics;\n}\n\nvoid MqttsnClient::setKeepAlive(uint16_t sec){\n\t_clientStatus.setKeepAlive(sec);\n}\n\nvoid MqttsnClient::setWillTopic(MQString* topic){\n    _willTopic = topic;\n    _clientFlg |= MQTTSN_FLAG_WILL;\n}\n\nvoid MqttsnClient::setWillMessage(MQString* msg){\n    _willMessage = msg;\n    _clientFlg |= MQTTSN_FLAG_WILL;\n}\n\n\nvoid MqttsnClient::setRetain(bool retain){\n\tif(retain){\n\t\t_clientFlg |= MQTTSN_FLAG_RETAIN;\n\t}else{\n\t\t_clientFlg &= (~MQTTSN_FLAG_RETAIN);\n\t}\n}\n\nvoid MqttsnClient::setSleepMode(){\n\t_clientStatus.setModeSleep();\n}\n\nvoid MqttsnClient::setClean(bool clean){\n\tif(clean){\n\t\t_clientFlg |= MQTTSN_FLAG_CLEAN;\n\t}else{\n\t\t_clientFlg ^= MQTTSN_FLAG_CLEAN;\n\t}\n}\n\nbool MqttsnClient::isCleanSession(){\n\treturn _clientFlg && MQTTSN_FLAG_CLEAN;\n}\n\nvoid MqttsnClient::setRetryMax(uint8_t cnt){\n    _nRetry = cnt;\n}\n\n\nvoid MqttsnClient::setGwAddress(){\n\t_network->setGwAddress();\n}\n\nMQString* MqttsnClient::getClientId(){\n    return _clientId;\n}\n\nClientStatus* MqttsnClient::getClientStatus(){\n\treturn &_clientStatus;\n}\n\n\nuint16_t MqttsnClient::getNextMsgId(){\n    _msgId++;\n    if (_msgId == 0){\n        _msgId = 1;\n    }\n    return _msgId;\n}\n\nuint8_t MqttsnClient::getMsgRequestType(){\n    if (_sendQ->getMessage(0)){\n        return _sendQ->getMessage(0)->getType();\n    }else{\n        return 0;\n    }\n}\nuint8_t MqttsnClient::getMsgRequestStatus(){\n    return _sendQ->getStatus(0);\n}\n\nuint8_t MqttsnClient::getMsgRequestCount(){\n  return _sendQ->getCount();\n}\n\nvoid MqttsnClient::setMsgRequestStatus(uint8_t stat){\n    _sendQ->setStatus(0,stat);\n}\n\nvoid MqttsnClient::clearMsgRequest(){\n    _sendQ->deleteRequest(0);\n}\n\nvoid MqttsnClient::createTopic(MQString* topic, TopicCallback callback){\n    _topics.addTopic(topic);\n    _topics.setCallback(topic, callback);\n}\n\nvoid MqttsnClient::delayTime(uint16_t maxTime){\n#ifdef ARDUINO\n    srand((uint32_t)millis( ));\n    uint32_t tm = rand() % (maxTime * 1000);\n#else\n    srand((uint32_t)time( 0 ));\n    uint32_t tm = (rand() % (maxTime * 1000));\n#endif\n    XTimer delayTimer;\n    delayTimer.start(tm);\n    while(!delayTimer.isTimeUp()){\n       _network->readPacket();\n    }\n}\n\nvoid MqttsnClient::copyMsg(MqttsnMessage* msg, NWResponse* recvMsg){\n    memcpy(msg->getMsgBuff(), recvMsg->getPayload(), recvMsg->getPayload(0));\n}\n\n\n\n/*========================================================\n    Send a MQTT-S Message (add the send request)\n==========================================================*/\nint MqttsnClient::requestSendMsg(MqttsnMessage* mqttsMsgPtr){\n    int index = _sendQ->addRequest((MqttsnMessage*)mqttsMsgPtr);\n\t_sendQ->setStatus(index, MQTTSN_MSG_REQUEST);\n    return MQTTSN_ERR_NO_ERROR;\n}\n\n/*========================================================\n  Send a MQTT-S Message (add to the top of the send request)\n==========================================================*/\nint MqttsnClient::requestPrioritySendMsg(MqttsnMessage* mqttsMsgPtr){\n    _sendQ->addPriorityRequest((MqttsnMessage*)mqttsMsgPtr);\n    _sendQ->setStatus(0, MQTTSN_MSG_REQUEST);\n    return MQTTSN_ERR_NO_ERROR;\n}\n\n/*========================================================\n  Execute sending a MQTT-S Message\n==========================================================*/\n\n/*-------------  send Message once -----------------*/\nint MqttsnClient::exec(){\n    int rc;\n\n    if (!_clientStatus.isGatewayAlive()){\n\t\tD_MQTTW(\"Gateway is Dead.\\r\\n\");\n\t\t_clientStatus.init();\n\t}\n/*\n    if(_sendFlg){\n    \treturn MQTTSN_ERR_NO_ERROR;\n    }else{\n    \t//_sendFlg = true;\n    }\n*/\n    while(true){\n        rc = sendRecvMsg();\n\n        if (rc == MQTTSN_ERR_RETRY_OVER){\n\t\t\tif (getMsgRequestType() == MQTTSN_TYPE_WILLTOPIC    ||\n\t\t\t    getMsgRequestType() == MQTTSN_TYPE_WILLMSG      ||\n\t\t\t  \tgetMsgRequestType() == MQTTSN_TYPE_PINGREQ      ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_PUBLISH      ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_REGISTER     ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_SUBSCRIBE    ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_CONNECT      ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_UNSUBSCRIBE  ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_PUBREC       ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_SEARCHGW     ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_PUBREL) {\n\t\t\t\t_clientStatus.init();\n\t\t\t}\n        }else if(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\t\t_clientStatus.init();\n\t\t}else if(rc != MQTTSN_ERR_NO_ERROR && rc != MQTTSN_ERR_INVALID_TOPICID){\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n    clearMsgRequest();\n//    _sendFlg = false;\n    return rc;\n}\n\n/*=============================\n *   Send or Receive Message\n ==============================*/\nint MqttsnClient::sendRecvMsg(){\n    int rc = MQTTSN_ERR_NO_ERROR;\n\n    if (!_clientStatus.isGatewayAlive()){\n\t\tD_MQTTW(\"Gateway is Dead.\\r\\n\");\n\t\t_clientStatus.init();\n\t}\n\n\t/*======= Establish Connection ===========*/\n\tif (_clientStatus.isLost() ||_clientStatus.isSearching() ){\n\t\t/*------------ Send SEARCHGW --------------*/\n\t\tif (getMsgRequestType() != MQTTSN_TYPE_SEARCHGW){\n\t\t\tsearchGw(0);   //ZB_BROADCAST_RADIUS_MAX_HOPS\n\t\t}\n\t\t_clientStatus.sendSEARCHGW();\n\t\t_network->resetGwAddress();\n\t\trc = broadcast(MQTTSN_TIME_RETRY);\n\t\tif ( rc != MQTTSN_ERR_NO_ERROR){\n\t\t\treturn rc;\n\t\t}\n\t}\n\n\tif (!_clientStatus.isConnected() && !_clientStatus.isSearching()){\n\t\t/*-----------  Send CONNECT ----------*/\n\t\tif (getMsgRequestType() != MQTTSN_TYPE_CONNECT){\n\t\t\tconnect();\n\t\t}\n\t\trc = unicast(MQTTSN_TIME_RETRY);\n\t\tif ( rc != MQTTSN_ERR_NO_ERROR){\n\t\t\treturn rc;\n\t\t}\n\t}\n\n\tif(_clientStatus.isOnConnected()){\n\t\t/*----------- ready to send  ----------*/\n\t\t_clientStatus.setAvailableToSend();\n\t\t/*----------- in case of clean session ----------*/\n\t\tif(isCleanSession() && !_clientStatus.isSubscribing()){\n\t\t\t_clientStatus.setSubscribing(true);  // re-entrant control\n\t\t\tsubscribe();\n\t\t\t_clientStatus.setSubscribing(false); // re-entrant control\n\t\t}\n\t}\n\n\tif (getMsgRequestStatus() == MQTTSN_MSG_REQUEST || getMsgRequestStatus() == MQTTSN_MSG_RESEND_REQ){\n        /*======  Send Message =======*/\n        if (_clientStatus.isAvailableToSend()){\n\t\t\trc = unicast(MQTTSN_TIME_RETRY);\n\t\t}else{\n\t\t\trc = MQTTSN_ERR_NOT_CONNECTED;\n\t\t}\n    }\n\n\t/*======= Receive Message ===========*/\n\t_network->readPacket();  //  Receive MQTT-S Message\n\n\tif (_clientStatus.isPINGREQRequired()){\n\t\t/*-------- Send PINGREQ -----------*/\n\t\tif(getMsgRequestType() != MQTTSN_TYPE_PINGREQ){\n\t\t\tpingReq(_clientId);\n\t\t}\n\t\trc = unicast(MQTTSN_TIME_RETRY);\n\t}\n\treturn rc;\n}\n\n/*------------------------------------\n *   Broad cast the MQTT-S Message\n -------------------------------------*/\nint MqttsnClient::broadcast(uint16_t packetReadTimeout){\n    int retry = 0;\n    while(retry < _nRetry){\n        D_MQTTW(\"Bcast \");\n\t\tD_MQTTLN(_sendQ->getMessage(0)->getMsgTypeName());\n\t\tD_MQTTF(\"%s\\r\\n\", _sendQ->getMessage(0)->getMsgTypeName());\n\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"Bcast \");\n\t\tdebug.println(_sendQ->getMessage(0)->getMsgTypeName());\n#endif\n        _network->send(_sendQ->getMessage(0)->getMsgBuff(), _sendQ->getMessage(0)->getLength(),BcastReq);\n\n        _respTimer.start(packetReadTimeout * 1000);\n        setMsgRequestStatus(MQTTSN_MSG_WAIT_ACK);\n\n        while(!_respTimer.isTimeUp()){\n        \tif(_network->readPacket() != PACKET_ERROR_NODATA){\n\t\t\t\tif (getMsgRequestStatus() == MQTTSN_MSG_COMPLETE){\n\t\t\t\t\tclearMsgRequest();\n\t\t\t\t\treturn MQTTSN_ERR_NO_ERROR;\n\t\t\t\t}else if(getMsgRequestStatus() == MQTTSN_MSG_REJECTED){\n\t\t\t\t\t//clearMsgRequest();\n\t\t\t\t\treturn MQTTSN_ERR_REBOOT_REQUIRED;\n\t\t\t\t}\n        \t}\n        }\n        setMsgRequestStatus(MQTTSN_MSG_REQUEST);\n        retry++;\n    }\n    //clearMsgRequest();\n    return MQTTSN_ERR_RETRY_OVER;\n}\n\n/*------------------------------------\n *   Unicast the MQTT-S Message\n -------------------------------------*/\nint MqttsnClient::unicast(uint16_t packetReadTimeout){\n    int retry = 0;\n\n    while(retry < _nRetry){\n    \tif (getMsgRequestStatus() == MQTTSN_MSG_RESEND_REQ){\n\t\t\t/* ------  Re send Time delay -------*/\n\t\t\t#ifdef ARDUINO\n\t\t\t  delay(MQTTSN_TIME_WAIT * 1000UL);\n\t\t\t#else\n\t\t\t\t#ifdef MBED\n\t\t\t\t\twait_ms(MQTTSN_TIME_WAIT * 1000);\n\t\t\t\t#else\n\t\t\t\t\tusleep(MQTTSN_TIME_WAIT * 1000000);\n\t\t\t\t#endif\n\t\t\t#endif\n\t\t\tsetMsgRequestStatus(MQTTSN_MSG_REQUEST);\n\t\t}\n\n    \t/*------ Send Top message in SendQue -----*/\n    \tif (getMsgRequestStatus() != MQTTSN_MSG_REQUEST){\n    \t\treturn MQTTSN_ERR_NO_ERROR;\n    \t}\n\n        D_MQTTW(\"Ucast \");\n        D_MQTTLN(_sendQ->getMessage(0)->getMsgTypeName());\n        D_MQTTF(\"%s\\r\\n\", _sendQ->getMessage(0)->getMsgTypeName());\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"Ucast \");\n\t\tdebug.println(_sendQ->getMessage(0)->getMsgTypeName());\n#endif\n\n        _network->send(_sendQ->getMessage(0)->getMsgBuff(), _sendQ->getMessage(0)->getLength(), UcastReq);\n        _clientStatus.setLastSendTime();\n\n        _sendQ->getMessage(0)->setDup();\n        _respTimer.start(packetReadTimeout * 1000UL);\n        setMsgRequestStatus(MQTTSN_MSG_WAIT_ACK);\n\n        while(!_respTimer.isTimeUp()){\n            if ((getMsgRequestType() == MQTTSN_TYPE_PUBLISH &&\n            \t\t  _sendQ->getMessage(0)->getQos() == 0 )  ||\n            \tgetMsgRequestType() == MQTTSN_TYPE_PUBACK     ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_REGACK     ||\n\t\t\t\tgetMsgRequestType() == MQTTSN_TYPE_PUBCOMP    ||\n\t\t\t\tgetMsgRequestStatus() == MQTTSN_MSG_COMPLETE ){\n            \t//clearMsgRequest();\n                return MQTTSN_ERR_NO_ERROR;\n            }else if(getMsgRequestType() == MQTTSN_TYPE_DISCONNECT ){\n            \t_clientStatus.recvDISCONNECT();\n            \t//clearMsgRequest();\n\t\t\t\treturn MQTTSN_ERR_NO_ERROR;\n        \t}else if (getMsgRequestStatus() == MQTTSN_MSG_REJECTED){\n        \t\t//clearMsgRequest();\n\t\t\t\treturn MQTTSN_ERR_REJECTED;\n            }\n            /*----- Read response  ----*/\n\t\t\tint rc = _network->readPacket();\n\t\t\tif(rc == MQTTSN_READ_RESP_ONCE_MORE){\n\t\t\t\trc = _network->readPacket();\n\t\t\t}\n            if(rc == MQTTSN_ERR_INVALID_TOPICID){\n            \t//clearMsgRequest();\n            \treturn rc;\n            }else if(rc == PACKET_MODEM_STATUS ){\n\t\t\t\tbreak;\n\t\t\t}\n\n            /*---- WILLTOPICREQ ,WILLMESSAGEREQ PUBREC are received ---*/\n            if (getMsgRequestStatus() == MQTTSN_MSG_REQUEST &&\n               (getMsgRequestType() == MQTTSN_TYPE_WILLTOPIC ||\n                getMsgRequestType() == MQTTSN_TYPE_WILLMSG  ||\n                getMsgRequestType() == MQTTSN_TYPE_PUBREL)){\n            \tretry = 0;\n                break;\n            }\n\n        }\n\t\tsetMsgRequestStatus(MQTTSN_MSG_REQUEST);\n        retry++;\n    }\n    return MQTTSN_ERR_RETRY_OVER;\n}\n\n/*========================================\n *   Create & send the MQTT-S Messages\n =========================================*/\n#ifdef MQTTSN_DEBUG\nconst char* gateWayLost = \" Gateway lost\\r\\n\";\n#endif\n\n/*--------- REGISTER ------*/\nint MqttsnClient::registerTopic(MQString* topic){\n    MqttsnRegister mqttsMsg = MqttsnRegister();\n    mqttsMsg.setTopicName(topic);\n    mqttsMsg.setMsgId(getNextMsgId());\n    _topics.addTopic(topic);\n\n    D_MQTTW(\"\\nREGISTER SEND Topic = \");\n\tD_MQTTLN(topic->getConstStr());\n\tD_MQTTF(\"%s\\r\\n\", topic->getConstStr());\n\n    requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- PUBLISH ------*/\nint MqttsnClient::publish(MQString* topic, const char* data, int dataLength, uint8_t qos){\n\tif(!_clientStatus.isAvailableToSend()){\n\t\treturn MQTTSN_ERR_NOT_CONNECTED;\n\t}\n\n\tMqttsnPublish mqttsMsg = MqttsnPublish();\n\tuint16_t topicId = _topics.getTopicId(topic);\n\n    if (topic->getCharLength() == 2 && topicId == 0){\n\t\t_topics.addTopic(topic);\n\t\tif(topic->getStr()){\n\t\t\ttopicId = getUint16((uint8_t*)topic->getStr());\n\t\t}else{\n\t\t\ttopicId = getUint16((uint8_t*)topic->getConstStr());\n\t\t}\n\t\t_topics.setTopicId(topic, topicId);\n\t\tmqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_SHORT);\n\t\tmqttsMsg.setTopicId(topicId);\n\t}else{\n\t\tmqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_NORMAL);\n\t\tif(topicId){\n\t\t\tmqttsMsg.setTopicId(topicId);\n\t\t}else{\n\t\t\tregisterTopic(topic);\n\t\t\tmqttsMsg.setTopicId(_topics.getTopicId(topic));\n\t\t}\n\t}\n    mqttsMsg.setQos(qos);\n\tmqttsMsg.setData((uint8_t*)data, (uint8_t)dataLength);\n\tif (qos){\n\t\tmqttsMsg.setMsgId(getNextMsgId());\n\t}\n\trequestSendMsg((MqttsnMessage*)&mqttsMsg);\n\n\tD_MQTTW(\"PUBLISH SEND msgID = \");\n\tD_MQTTLN(mqttsMsg.getMsgId(),DEC);\n\tD_MQTTF(\"%d\\r\\n\", mqttsMsg.getMsgId());\n\n\tint rc = exec();\n\tif (rc == MQTTSN_ERR_INVALID_TOPICID){\n\t\tregisterTopic(topic);\n\t}\n\treturn rc;\n}\n\n/*--------- PUBLISH ------*/\nint MqttsnClient::publish(MQString* topic, MQString* data, uint8_t qos){\n\tif(data->getStr()){\n\t\treturn publish(topic, (const char*)data->getStr(),data->getCharLength(), qos);\n\t}else if(data->getConstStr()){\n\t\treturn publish(topic, data->getConstStr(),data->getCharLength(), qos);\n\t}\n\treturn MQTTSN_ERR_NO_DATA;\n}\n\n/*--------- PUBLISH ------*/\nint MqttsnClient::publish(MQString* topic, Payload* payload, uint8_t qos){\n\treturn publish(topic, (const char*)(payload->getBuf()), payload->getLen(), qos);\n}\n/*--------- PUBLISH ------*/\nint MqttsnClient::publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos){\n\tMqttsnPublish mqttsMsg = MqttsnPublish();\n    mqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_PREDEFINED);\n    mqttsMsg.setTopicId(predefinedId);\n    mqttsMsg.setQos(qos);\n    mqttsMsg.setData((uint8_t*)data, (uint8_t)dataLength);\n    if (qos){\n        mqttsMsg.setMsgId(getNextMsgId());\n    }\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- SUBSCRIBE ------*/\nint MqttsnClient::subscribe(MQString* topic, TopicCallback callback, uint8_t qos){\n\tMqttsnSubscribe mqttsMsg = MqttsnSubscribe();\n    uint16_t topicId = _topics.getTopicId(topic);\n    if (topic->getCharLength() == 2 && topicId == 0){\n    \tif(topic->getStr()){\n    \t\ttopicId = getUint16((uint8_t*)topic->getStr());\n    \t}else{\n    \t\ttopicId = getUint16((uint8_t*)topic->getConstStr());\n    \t}\n\t\t_topics.addTopic(topic);\n\t\t_topics.setTopicId(topic, topicId);\n\t\t_topics.setCallback(topic, callback);\n\t\tmqttsMsg.setTopicName(topic);\n\t\tmqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_SHORT);\n    }else{\n        mqttsMsg.setTopicName(topic);\n        mqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_NORMAL);\n        _topics.addTopic(topic);\n        _topics.setCallback(topic, callback);\n    }\n    mqttsMsg.setMsgId(getNextMsgId());\n    mqttsMsg.setQos(qos);\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- SUBSCRIBE ------*/\nint MqttsnClient::subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos){\n\tMqttsnSubscribe mqttsMsg = MqttsnSubscribe();\n    mqttsMsg.setTopicId(predefinedId);\n    mqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_PREDEFINED);\n    mqttsMsg.setMsgId(getNextMsgId());\n    _topics.setCallback(predefinedId, callback);\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- UNSUBSCRIBE ------*/\nint MqttsnClient::unsubscribe(MQString* topic){\n    MqttsnUnsubscribe mqttsMsg = MqttsnUnsubscribe();\n    uint16_t topicId = _topics.getTopicId(topic);\n    if (topic->getCharLength() == 2 && topicId > 0){\n        mqttsMsg.setTopicName(topic);\n        mqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_SHORT);\n    }else{\n        mqttsMsg.setTopicId(topicId);\n\t\tmqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_NORMAL);\n    }\n    mqttsMsg.setMsgId(getNextMsgId());\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- UNSUBSCRIBE ------*/\nint MqttsnClient::unsubscribe(uint16_t predefinedId){\n    MqttsnUnsubscribe mqttsMsg = MqttsnUnsubscribe();\n    mqttsMsg.setTopicId(predefinedId);\n    mqttsMsg.setMsgId(getNextMsgId());\n    mqttsMsg.setFlags(_clientFlg | MQTTSN_TOPIC_TYPE_PREDEFINED);\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*--------- DISCONNECT ------*/\nint MqttsnClient::disconnect(uint16_t duration){\n    MqttsnDisconnect mqttsMsg = MqttsnDisconnect();\n    if (duration){\n        mqttsMsg.setDuration(duration);\n    }\n    requestSendMsg((MqttsnMessage*)&mqttsMsg);\n    return exec();\n}\n\n/*====  private Messages ====*/\n\n/*--------- SEARCHGW ------*/\nint  MqttsnClient::searchGw(uint8_t radius){\n    MqttsnSearchGw mqttsMsg = MqttsnSearchGw();\n    mqttsMsg.setRadius(radius);\n    delayTime(MQTTSN_TIME_SEARCHGW);\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- CONNECT ------*/\nint MqttsnClient::connect(){\n    MqttsnConnect mqttsMsg = MqttsnConnect(_clientId);\n    mqttsMsg.setDuration(_clientStatus.getKeepAlive());\n    mqttsMsg.setFlags(_clientFlg);\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- WILLTOPIC ------*/\nint MqttsnClient::willTopic(){\n    MqttsnWillTopic mqttsMsg = MqttsnWillTopic();\n    mqttsMsg.setWillTopic(_willTopic);\n    mqttsMsg.setFlags(_clientFlg & 0x70);\n    return requestSendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- WILLMSG ------*/\nint MqttsnClient::willMsg(){\n    MqttsnWillMsg mqttsMsg = MqttsnWillMsg();\n    mqttsMsg.setWillMsg(_willMessage);\n    return requestSendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- PUBACK ------*/\nint MqttsnClient::pubAck(uint16_t topicId, uint16_t msgId, uint8_t rc){\n    MqttsnPubAck mqttsMsg = MqttsnPubAck();\n    mqttsMsg.setTopicId(topicId);\n    mqttsMsg.setMsgId(msgId);\n    mqttsMsg.setReturnCode(rc);\n\n    D_MQTTW(\"\\nPUBACK SEND MsgId = \");\n\tD_MQTTLN(msgId,DEC);\n\tD_MQTTF(\"%d\", msgId);\n\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n    //return requestSendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- PUBREC ------*/\nint MqttsnClient::pubRec(uint16_t msgId){\n\tMqttsnPubRec mqttsMsg = MqttsnPubRec();\n    mqttsMsg.setMsgId(msgId);\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- PUBREL ------*/\nint MqttsnClient::pubRel(uint16_t msgId){\n    MqttsnPubRel mqttsMsg = MqttsnPubRel();\n    mqttsMsg.setMsgId(msgId);\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- PUBCOMP ------*/\nint MqttsnClient::pubComp(uint16_t msgId){\n    MqttsnPubComp mqttsMsg = MqttsnPubComp();\n    mqttsMsg.setMsgId(msgId);\n    return requestPrioritySendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- REGACK ------*/\nint MqttsnClient::regAck(uint16_t topicId, uint16_t msgId, uint8_t rc){\n    MqttsnRegAck mqttsMsg = MqttsnRegAck();\n    mqttsMsg.setTopicId(topicId);\n    mqttsMsg.setMsgId(msgId);\n    mqttsMsg.setReturnCode(rc);\n    return requestSendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/*--------- PINGREQ ------*/\nint  MqttsnClient::pingReq(MQString* clientId){\n    MqttsnPingReq mqttsMsg = MqttsnPingReq(clientId);\n    return requestSendMsg((MqttsnMessage*)&mqttsMsg);\n}\n\n/* ===================================================\n          Procedures for  Received Messages\n =====================================================*/\nvoid MqttsnClient::recieveMessageHandler(NWResponse* recvMsg, int* returnCode){\n\tuint8_t msgType = recvMsg->getType();\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"Receive Msg=0x\");\n\t\tdebug.println(msgType,HEX);\n#endif\n    if ( (_clientStatus.isSearching() && msgType != MQTTSN_TYPE_GWINFO) ||\n    \t (_clientStatus.isSubscribing() && msgType == MQTTSN_TYPE_PUBLISH ) ||\n\t\t (getMsgRequestType() == MQTTSN_TYPE_PUBLISH &&\n\t\t  getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n\t\t  msgType == MQTTSN_TYPE_PUBLISH ) )\n    {\n    \tD_MQTTW(\"Ignore Received Message\\r\\n\");\n\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println(\"Ignore Received Message\");\n#endif\n/*---------  GWINFO  ----------*/\n\t}else if (msgType == MQTTSN_TYPE_GWINFO && recvMsg->getPayloadLength() == 3){\n\t\tD_MQTTW(\"GWINFO recv\\r\\n\");\n\t\tMqttsnGwInfo mqMsg = MqttsnGwInfo();\n\t\tcopyMsg(&mqMsg, recvMsg);\n\t\tif (getMsgRequestType() == MQTTSN_TYPE_SEARCHGW){\n\t\t\tif(_clientStatus.recvGWINFO(&mqMsg)){\n\t\t\t\tsetMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n\t\t\t}else{\n\t\t\t\tsetMsgRequestStatus(MQTTSN_MSG_REJECTED);\n\t\t\t}\n\t\t\tif(isCleanSession()){\n\t\t\t\t_topics.clearTopic();\n\t\t\t}\n\t\t\t_network->setGwAddress();\n\t\t}\n/*---------  REGISTER  ----------*/\n\t}else if (msgType == MQTTSN_TYPE_REGISTER){\n\n\t\tif(_clientStatus.isAvailableToSend()){\n\t\t\tD_MQTTW(\"REGISTER recv\\r\\n\");\n\t\t\tMqttsnRegister mqMsg = MqttsnRegister();\n\n\t\t\tmqMsg.setFrame(recvMsg);\n\t\t\tuint16_t topicId = _topics.getTopicId(mqMsg.getTopicName());\n\t\t\tif (topicId == 0){\n\t\t\t\tif (_topics.match(mqMsg.getTopicName())){\n\t\t\t\t\tMQString* mqStr = mqMsg.getTopicName()->create();\n\t\t\t\t\t_topics.addTopic(mqStr);\n\t\t\t\t\t_topics.setTopicId(mqStr,mqMsg.getTopicId());\n\t\t\t\t\t_topics.setCallback(mqMsg.getTopicId(),_topics.match(mqStr)->getCallback());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mqMsg.getMsgId() != 0){\n\t\t\t\tregAck(mqMsg.getTopicId(), mqMsg.getMsgId(), MQTTSN_RC_ACCEPTED);\n\t\t\t\tif(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK){\n\t\t\t\t\t*returnCode = MQTTSN_READ_RESP_ONCE_MORE;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tD_MQTTW(\"RegAck is not required\\r\\n\");\n\t\t\t}\n\t\t}else{\n\t\t\tD_MQTTW(\"REGISTER recv. Client is not Active\\r\\n\");\n\t\t}\n/*---------  PUBLISH  --------*/\n    }else if (msgType == MQTTSN_TYPE_PUBLISH){\n\n    \tif(_clientStatus.isAvailableToSend()){\n    \t\t_clientStatus.setSubscribing(true);\n\t\t\tMqttsnPublish mqMsg = MqttsnPublish();\n\t\t\tmqMsg.setFrame(recvMsg);\n\n    \t\tD_MQTTW(\"PUBLISH RECV msgID = \");\n    \t\tD_MQTTLN(mqMsg.getMsgId(),DEC);\n    \t\tD_MQTTF(\"%d\\r\\n\", mqMsg.getMsgId());\n\n\t\t\tif (mqMsg.getQos() == QOS1){\n\t\t\t\tpubAck(mqMsg.getTopicId(), mqMsg.getMsgId(), MQTTSN_RC_ACCEPTED);\n\t\t\t\tunicast(MQTTSN_TIME_RETRY);\n\t\t\t}else if(mqMsg.getQos() == QOS2){\n\t\t\t\tpubRec(mqMsg.getMsgId());\n\t\t\t\tunicast(MQTTSN_TIME_RETRY);\n\t\t\t}\n\n\t\t\tif(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK){\n\t\t\t\t*returnCode = MQTTSN_READ_RESP_ONCE_MORE;\n\t\t\t}\n\t\t\t_pubHdl.exec(&mqMsg,&_topics);   //  Execute Callback routine\n    \t\t_clientStatus.setSubscribing(false);\n    \t}else{\n    \t\tD_MQTTW(\"PUBLISH recv Client is not Active\\r\\n\");\n    \t}\n\n/*===========  Response  =========*/\n\n/*---------  PUBACK  ----------*/\n    }else if (msgType == MQTTSN_TYPE_PUBACK &&\n    \t\t(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n    \t\t getMsgRequestType() == MQTTSN_TYPE_PUBLISH)){\n        MqttsnPubAck mqMsg = MqttsnPubAck();\n        copyMsg(&mqMsg, recvMsg);\n\n        D_MQTTW(\"\\nPUBACK RECV MsgId = \");\n\t\tD_MQTTLN(mqMsg.getMsgId(),DEC);\n\t\tD_MQTTF(\"%d\", mqMsg.getMsgId());\n        D_MQTTW(\" RC=\");\n        D_MQTTLN(mqMsg.getReturnCode(),DEC);\n        D_MQTTF(\"%d\\r\\n\", mqMsg.getReturnCode());\n\n        if (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody() + 3)){\n            if (mqMsg.getReturnCode() == MQTTSN_RC_ACCEPTED){\n                setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n\n            }else if (mqMsg.getReturnCode() == MQTTSN_RC_REJECTED_CONGESTION){\n                  setMsgRequestStatus(MQTTSN_MSG_RESEND_REQ);\n\n            }else if (mqMsg.getReturnCode() == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID){\n                *returnCode = MQTTSN_ERR_INVALID_TOPICID;\n                setMsgRequestStatus(MQTTSN_MSG_REJECTED);\n            }\n        }else{\n        \t//D_MQTTW(\"MsgId dosn't match.\\r\\n\");\n        }\n\n/*---------  PINGRESP  ----------*/\n    }else if (msgType == MQTTSN_TYPE_PINGRESP){\n        D_MQTTW(\"PINGRESP recv\\r\\n\");\n\n        if (getMsgRequestType() == MQTTSN_TYPE_PINGREQ){\n        \t_clientStatus.recvPINGRESP();\n            setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n        }\n\n/*---------  ADVERTISE  ----------*/\n    }else if (msgType == MQTTSN_TYPE_ADVERTISE){\n        D_MQTTW(\"ADVERTISE recv\\r\\n\");\n\n        MqttsnAdvertise mqMsg = MqttsnAdvertise();\n        copyMsg(&mqMsg, recvMsg);\n        _clientStatus.recvADVERTISE(&mqMsg);\n        if(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK){\n        \t*returnCode = MQTTSN_READ_RESP_ONCE_MORE;\n        }\n\n/*---------  CONNACK  ----------*/\n    }else if (msgType == MQTTSN_TYPE_CONNACK){\n        if ((getMsgRequestType() == MQTTSN_TYPE_CONNECT || getMsgRequestType() == MQTTSN_TYPE_WILLMSG)){\n            MqttsnConnack mqMsg = MqttsnConnack();\n            copyMsg(&mqMsg, recvMsg);\n\n            D_MQTTW(\"CONNACK recv RC=\");\n\t\t\tD_MQTTLN(mqMsg.getReturnCode(),DEC);\n\t\t\tD_MQTTF(\"%d\\r\\n\", mqMsg.getReturnCode());\n\n            if (mqMsg.getReturnCode() == MQTTSN_RC_ACCEPTED){\n                setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n                _clientStatus.recvCONNACK();\n\n            }else{\n               setMsgRequestStatus(MQTTSN_MSG_REJECTED);\n               *returnCode = MQTTSN_ERR_REJECTED;\n\t\t\t\tclearMsgRequest();\n               _clientStatus.recvDISCONNECT();\n            }\n        }\n        D_MQTTW(\"\\r\\n\");\n\n/*---------  REGACK  ----------*/\n    }else if (msgType == MQTTSN_TYPE_REGACK){\n         D_MQTTW(\"REGACK recv\\r\\n\");\n\n        if (getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n            getMsgRequestType() == MQTTSN_TYPE_REGISTER){\n            MqttsnRegAck mqMsg = MqttsnRegAck();\n            copyMsg(&mqMsg, recvMsg);\n            if (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody() + 2)){\n\t\t\t\tif (getUint16((uint8_t*)_sendQ->getMessage(0)->getBody()+4)){\n\t\t\t\t\tif (mqMsg.getReturnCode() == MQTTSN_RC_ACCEPTED){\n\t\t\t\t\t\tsetMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n\t\t\t\t\t\tMQString topic;\n\t\t\t\t\t\ttopic.readBuf(_sendQ->getMessage(0)->getBody() + 4);\n\t\t\t\t\t\t_topics.setTopicId(&topic, mqMsg.getTopicId());\n\t\t\t\t\t}else if (mqMsg.getReturnCode() == MQTTSN_RC_REJECTED_CONGESTION){\n\t\t\t\t\t  setMsgRequestStatus(MQTTSN_MSG_RESEND_REQ);\n\t\t\t\t\t}else{\n\t\t\t\t\t\t*returnCode = MQTTSN_ERR_REJECTED;\n\t\t\t\t\t}\n\t\t\t\t}\n            }\n        }\n\n/*---------  SUBACK  ----------*/\n    }else if (msgType == MQTTSN_TYPE_SUBACK && getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK){\n        MqttsnSubAck mqMsg = MqttsnSubAck();\n        copyMsg(&mqMsg, recvMsg);\n\n        D_MQTT(\"\\nSUBACK RC=\");\n        D_MQTTLN(mqMsg.getReturnCode(),HEX);\n        D_MQTTF(\"\\nSUBACK RC=%d\\r\\n\", mqMsg.getReturnCode());\n\n        if (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody() + 1)){\n            if (mqMsg.getReturnCode() == MQTTSN_RC_ACCEPTED){\n                setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n                if (_sendQ->getMessage(0)->getBodyLength() > 5){ // TopicName is not Id\n                    MQString topic;\n                    topic.copy(_sendQ->getMessage(0)->getBody() + 3,\n                    \t\t_sendQ->getMessage(0)->getBodyLength() - 3);\n                    _topics.setTopicId(&topic, mqMsg.getTopicId());\n                }\n            }else if (mqMsg.getReturnCode() == MQTTSN_RC_REJECTED_CONGESTION){\n                setMsgRequestStatus(MQTTSN_MSG_RESEND_REQ);\n            }else{\n                *returnCode = MQTTSN_ERR_REJECTED;       // Return Code\n            }\n        }\n\n/*---------  UNSUBACK  ----------*/\n    }else if (msgType == MQTTSN_TYPE_UNSUBACK && getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK){\n        D_MQTTW(\"UNSUBACK recv\\r\\n\");\n        MqttsnUnSubAck mqMsg = MqttsnUnSubAck();\n        copyMsg(&mqMsg, recvMsg);\n        if (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody() + 1)){\n              setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n        }\n\n/*---------  DISCONNECT  ----------*/\n    }else if (msgType == MQTTSN_TYPE_DISCONNECT){\n         D_MQTTW(\"DISCONNECT recv\\r\\n\");\n         setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n         _clientStatus.recvDISCONNECT();\n\n\n/*---------  WILLTOPICREQ  ----------*/\n    }else if (msgType == MQTTSN_TYPE_WILLTOPICREQ){\n        D_MQTTW(\"WILLTOPICREQ recv\\r\\n\");\n        if (getMsgRequestType() == MQTTSN_TYPE_CONNECT){\n            clearMsgRequest();\n        \t//setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n            MqttsnWillTopic mqMsg = MqttsnWillTopic();\n            mqMsg.setFlags(0);                               // ToDo:  add  WillQoS, WillRetain to appConfig\n            mqMsg.setWillTopic(_willTopic);\n            requestPrioritySendMsg((MqttsnMessage*)&mqMsg);\n        }\n\n/*---------  WILLMSGREQ  -----------*/\n    }else if (msgType == MQTTSN_TYPE_WILLMSGREQ){\n        D_MQTTW(\"WILLMSGREQ recv\\r\\n\");\n        if (getMsgRequestType() == MQTTSN_TYPE_WILLTOPIC){\n            clearMsgRequest();\n        \t//setMsgRequestStatus(MQTTSN_MSG_COMPLETE);\n            MqttsnWillMsg mqMsg = MqttsnWillMsg();\n            mqMsg.setWillMsg(_willMessage);\n            requestPrioritySendMsg((MqttsnMessage*)&mqMsg);\n        }\n\n/*---------  PUBREC  ----------*/\n\t}else if (msgType == MQTTSN_TYPE_PUBREC &&\n\t\t\t(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n\t\t\t getMsgRequestType() == MQTTSN_TYPE_PUBLISH)){\n\t\tMqttsnPubRec mqMsg = MqttsnPubRec();\n\t\tcopyMsg(&mqMsg, recvMsg);\n\n\t\tD_MQTTW(\"\\nPUBREC recv\\r\\n\");\n\n\t\tif (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody() + 3)){\n\t\t\tMqttsnPubRel mqrMsg = MqttsnPubRel();\n\t\t\tmqrMsg.setMsgId(mqMsg.getMsgId());\n\t\t\trequestPrioritySendMsg((MqttsnMessage*)&mqrMsg);\n\t\t}\n\n/*---------  PUBREL  ----------*/\n\t}else if (msgType == MQTTSN_TYPE_PUBREL &&\n\t\t\t(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n\t\t\t getMsgRequestType() == MQTTSN_TYPE_PUBREC)){\n\t\tMqttsnPubRel mqMsg = MqttsnPubRel();\n\t\tcopyMsg(&mqMsg, recvMsg);\n\n\t\tD_MQTTW(\"\\nPUBREL recv\\r\\n\");\n\n\t\tif (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody())){\n\t\t\tclearMsgRequest();  // delete PUBREC\n\t\t\tMqttsnPubComp mqrMsg = MqttsnPubComp();\n\t\t\tmqrMsg.setMsgId(mqMsg.getMsgId());\n\t\t\trequestPrioritySendMsg((MqttsnMessage*)&mqMsg);\n\t\t}\n\n/*---------  PUBCOMP  ----------*/\n\t}else if (msgType == MQTTSN_TYPE_PUBCOMP &&\n\t\t\t(getMsgRequestStatus() == MQTTSN_MSG_WAIT_ACK &&\n\t\t\t getMsgRequestType() == MQTTSN_TYPE_PUBREL)){\n\t\tMqttsnPubComp mqMsg = MqttsnPubComp();\n\t\tcopyMsg(&mqMsg, recvMsg);\n\n\t\tD_MQTTW(\"\\nPUBCOMP recv\\r\\n\");\n\n\t\tif (mqMsg.getMsgId() == getUint16(_sendQ->getMessage(0)->getBody())){\n\t\t\tclearMsgRequest();    // delete request of PUBREL\n\t\t\tsetMsgRequestStatus(MQTTSN_MSG_COMPLETE);  // PUBLISH complete\n\t\t}\n    }else{\n\t\t*returnCode = PACKET_ERROR_NODATA;\n\t}\n}\n\n\n/*=====================================\n        Class SendQue\n ======================================*/\nSendQue::SendQue(){\n    _queCnt = 0;\n    _queSize = SENDQ_SIZE;\n}\nSendQue::~SendQue(){\n    for( int i = 0; i < _queCnt; i++){\n        delete _msg[i];\n    }\n}\n\nint SendQue::addRequest(MqttsnMessage* msg){\n    if ( _queCnt < _queSize){\n\n\t\tD_MQTTW(\"\\nAdd SendQue size = \");\n\t\tD_MQTT(_queCnt + 1, DEC);\n\t\tD_MQTT(\" Msg = 0x\");\n\t\tD_MQTTLN(msg->getMsgTypeName());\n\t\tD_MQTTF(\"%d  Msg = 0x%x\\r\\n\", _queCnt + 1, msg->getType());\n\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"\\nAdd SendQue size = \");\n\t\tdebug.print(_queCnt + 1, DEC);\n\t\tdebug.print(\" Msg=\");\n\t\tdebug.println(msg->getMsgTypeName());\n#endif\n        _msg[_queCnt] =new MqttsnMessage();\n        _msg[_queCnt++]->copy(msg);\n        return _queCnt - 1;\n    }\n    return MQTTSN_ERR_CANNOT_ADD_REQUEST; // Over Que size\n}\n\nint SendQue::addPriorityRequest(MqttsnMessage* msg){\n    if ( _queCnt < _queSize){\n\t_queCnt++;\n    }\n\n\tD_MQTTW(\"\\nAdd SendQue Top Size = \");\n\tD_MQTT(_queCnt, DEC);\n\tD_MQTT(\"  Msg = 0x\");\n\tD_MQTTLN(msg->getType(), HEX);\n\tD_MQTTF(\"%d  Msg = 0x%x\", _queCnt, msg->getType());\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"\\nAdd SendQue Top size = \");\n\t\tdebug.print(_queCnt, DEC);\n\t\tdebug.print(\" Msg=\");\n\t\tdebug.print(msg->getMsgTypeName());\n#endif\n\n    for(int i = _queCnt-1; i > 0; i--){\n        _msg[i] = _msg[i - 1];\n    }\n    _msg[0] = new MqttsnMessage();\n    _msg[0]->copy(msg);\n\n\n        for(int i = 1; i < _queCnt; i++){\n     \t    D_MQTT( \"  Msg = 0x\");\n\t\t\tD_MQTT(_msg[i]->getType(), HEX);\n\t\t\tD_MQTTF(\"  Msg = 0x%x \", _msg[i]->getType());\n#if defined(DEBUG) && defined(ARDUINO)\n\t\t\tdebug.print(\"  Msg=\");\n\t\t\tdebug.print(_msg[i]->getMsgTypeName());\n#endif\n        }\n        D_MQTTW(\"\\r\\n\");\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println();\n#endif\n\n    return 0;\n}\n\nint SendQue::deleteRequest(uint8_t index){\n\n\tif ( index < _queCnt){\n\n        delete _msg[index];\n        _queCnt--;\n\n    \tD_MQTTW(\"\\nDelete SendQue  Size = \");\n    \tD_MQTT(_queCnt, DEC);\n    \tD_MQTTF(\"%d\", _queCnt);\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.print(\"\\nDelete SendQue  Size = \");\n\t\tdebug.print(_queCnt, DEC);\n#endif\n\n        for(int i = index; i < _queCnt; i++){\n            _msg[i] = _msg[i + 1];\n\n            D_MQTT( \"  Msg = 0x\");\n\t\t\tD_MQTT(_msg[i]->getType(), HEX);\n\t\t\tD_MQTTF(\"  Msg = 0x%x \", _msg[i]->getType());\n#if defined(DEBUG) && defined(ARDUINO)\n\t\t\tdebug.print(\"  Msg=\");\n\t\t\tdebug.print(_msg[i]->getMsgTypeName());\n#endif\n        }\n\n        D_MQTTW(\"\\r\\n\");\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println();\n#endif\n        for(int i = _queCnt; i < _queSize; i++){\n            _msg[i] = 0;\n        }\n\n        return 0;\n    }\n    return -2;\n}\n\nvoid   SendQue::deleteAllRequest(){\n    while ( _queCnt > 0){\n        deleteRequest(0);\n    }\n}\n\nvoid SendQue::setStatus(uint8_t index, uint8_t status){\n    if ( index < _queCnt){\n        _msg[index]->setStatus(status);\n    }\n}\n\nvoid SendQue::setQueSize(uint8_t sz){\n  _queSize = sz;\n}\n\nMqttsnMessage* SendQue::getMessage(uint8_t index){\n  if ( index < _queCnt){\n      return _msg[index];\n  }\n  return 0;\n}\n\nint SendQue::getStatus(uint8_t index){\n  if ( index < _queCnt){\n      return _msg[index]->getStatus();\n  }\n  return -1;\n}\n\nuint8_t SendQue::getCount(){\n   return _queCnt;\n}\n\n\n/*=====================================\n        Class ClientStatus\n ======================================*/\nClientStatus::ClientStatus(){\n\tinit();\n\t_gwId = 0;\n\t_sleepModeFlg = false;\n\t_onConnectFlg = false;\n\t_subscribingFlg = false;\n}\n\nClientStatus::~ClientStatus(){\n}\n\nvoid ClientStatus::init(){\n\t_gwStat = GW_LOST;\n\t_clStat = CL_DISCONNECTED;\n\n\t_keepAliveDuration = MQTTSN_DEFAULT_DURATION;\n\t_advertiseDuration = MQTTSN_DEFAULT_KEEPALIVE;\n\t_advertiseTimer.stop();\n\t_keepAliveTimer.stop();\n\t_onConnectFlg = false;\n\t_subscribingFlg = false;\n}\n\n\nvoid ClientStatus::changeUTC(){\n\t_keepAliveTimer.changeUTC();   // changeUTC() is static\n}\n\nbool ClientStatus::isLost(){\n\tif(_gwStat == GW_LOST){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\nbool ClientStatus::isSearching(){\n\tif(_gwStat == GW_SEARCHING){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\n\nbool ClientStatus::isConnected(){\n\tif(_gwStat == GW_FIND && _clStat != CL_DISCONNECTED){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\nbool ClientStatus::isOnConnected(){\n\treturn _onConnectFlg;\n}\n\nbool ClientStatus::isSubscribing(){\n\treturn _subscribingFlg;\n}\n\nbool ClientStatus::isAvailableToSend(){\n\tif((_gwStat == GW_FIND) &&\n\t\t((_clStat == CL_ACTIVE) || (_clStat == CL_ASLEEP))){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\nbool ClientStatus::isPINGREQRequired(){\n\tif(_sleepModeFlg){\n\t\t_keepAliveTimer.changeUTC();\n\t}\n\treturn (_keepAliveTimer.isTimeUp() && isConnected());\n}\n\nbool ClientStatus::isGatewayAlive(){\n\tif(_sleepModeFlg){\n\t\t_advertiseTimer.changeUTC();\n\t}\n\treturn (_advertiseTimer.isTimeUp() ? false : true);\n}\n\nuint16_t ClientStatus::getKeepAlive(){\n\treturn _keepAliveDuration;\n}\n\nvoid ClientStatus::setKeepAlive(uint16_t sec){\n\t_keepAliveDuration = sec;\n}\n\nvoid ClientStatus::sendSEARCHGW(){\n\t_gwStat = GW_SEARCHING;\n}\n\nbool ClientStatus::recvGWINFO(MqttsnGwInfo* gwi){\n\tbool rc = true;\n\tif (_gwStat == GW_SEARCHING){\n\t\t_gwStat = GW_FIND;\n\t\tif(_gwId != gwi->getGwId() && _gwId != 0){\n\t\t\trc = false;\n\t\t}\n\t\t_gwId = gwi->getGwId();\n\t}\n\treturn rc;\n}\n\nvoid ClientStatus::recvADVERTISE(MqttsnAdvertise* adv){\n\tif ( adv->getGwId() == _gwId ){\n\t\t_advertiseDuration = (adv->getDuration() > 60 ?\n\t\t\t\tadv->getDuration() + adv->getDuration() / 10 :\n\t\t\t\tadv->getDuration() + adv->getDuration() / 2);\n\t\t_advertiseTimer.start((uint32_t)(_advertiseDuration * 1000UL));\n\t}\n}\n\nvoid ClientStatus::recvCONNACK(){\n\t_onConnectFlg = true;\n}\n\nvoid ClientStatus::recvDISCONNECT(){\n\t_clStat = CL_DISCONNECTED;\n\t_advertiseTimer.stop();\n}\n\nvoid ClientStatus::setLastSendTime(){\n\t_keepAliveTimer.start((uint32_t)(_keepAliveDuration * 1000UL));\n}\n\n\nvoid ClientStatus::recvPINGRESP(){\n\tsetLastSendTime();\n}\n\nvoid ClientStatus::setAvailableToSend(){\n\t_clStat = CL_ACTIVE;\n\t_onConnectFlg = false;\n}\n\nvoid ClientStatus::setSubscribing(bool stat){\n\t_subscribingFlg = stat;\n}\n\nvoid ClientStatus::setModeSleep(){\n\t_sleepModeFlg = true;\n}\n\n\n/*===================  End of file ====================*/\n"
  },
  {
    "path": "Client/src/lib/mqttsnClient.h",
    "content": "/*\n * mqttsnClient.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef MQTTSCLIENT_H_\n#define MQTTSCLIENT_H_\n\n#ifdef LINUX\n\t\t#define SENDQ_SIZE   20\n#else\n\t\t#define SENDQ_SIZE    5\n#endif\n\n#if defined(ARDUINO) && ARDUINO >= 100\n        #include \"Arduino.h\"\n        #include <inttypes.h>\n\t\t#include <MQTTSN_Application.h>\n\t\t#include <Network.h>\n        #include <mqttsn.h>\n\t\t#include <mqUtil.h>\n#else\n        #if defined(ARDUINO) && ARDUINO < 100\n                #include \"WProgram.h\"\n                #include <inttypes.h>\n                #include <mqttsn.h>\n\t\t\t\t#include <Network.h>\n\t\t\t\t#include <mqUtil.h>\n        #else\n                #ifdef LINUX\n                    #include <sys/time.h>\n                #endif\n                #include <iostream>\n\t\t\t\t#include \"MQTTSN_Application.h\"\n\t\t\t\t#include \"Network.h\"\n\t\t\t\t#include \"mqUtil.h\"\n                #include \"mqttsn.h\"\n        #endif\n#endif\n\n\n#define GW_LOST      0\n#define GW_SEARCHING 1\n#define GW_FIND      2\n\n#define CL_DISCONNECTED  0\n#define CL_ACTIVE        1\n#define CL_ASLEEP        2\n#define CL_AWAKE         3\n\n\nusing namespace tomyClient;\n\ntypedef struct {\n\tint (*callback)(void);\n\tuint32_t sec;\n}TaskList;\n\ntypedef struct {\n\tMQString* topic;\n\tint (*pubCallback)(MqttsnPublish*);\n\tuint8_t qos;\n}OnPublishList;\n\ntypedef struct {\n\tuint32_t prevTime;\n\tuint32_t interval;\n\tint (*callback)(void);\n}MQ_TimerTbl;\n\n/*=====================================\n        Class ClientStatus\n ======================================*/\nclass ClientStatus{\npublic:\n\tClientStatus();\n\t~ClientStatus();\n\n\tbool isLost();\n\tbool isSearching();\n\tbool isConnected();\n\tbool isOnConnected();\n\tbool isSubscribing();\n\tbool isAvailableToSend();\n\tbool isPINGREQRequired();\n\tbool isGatewayAlive();\n\n\tuint16_t getKeepAlive();\n\tvoid setKeepAlive(uint16_t sec);\n\tvoid sendSEARCHGW();\n\tbool recvGWINFO(MqttsnGwInfo* gwi);\n\tvoid recvADVERTISE(MqttsnAdvertise* adv);\n\tvoid recvCONNACK();\n\tvoid recvDISCONNECT();\n\tvoid recvPINGRESP();\n\tvoid setAvailableToSend();\n\tvoid setSubscribing(bool);\n\tvoid setLastSendTime();\n\tvoid setModeSleep();\n\tvoid init();\n\n\nprivate:\n\tvoid changeUTC();\n\n\tuint8_t _gwId;\n\tuint8_t _gwStat;\n\tuint8_t _clStat;\n\tbool   _onConnectFlg;\n\tbool   _subscribingFlg;\n\tuint16_t _keepAliveDuration; // PINGREQ interval\n\tuint16_t _advertiseDuration; // Gateway heart beat\n\tXTimer  _keepAliveTimer;\n\tXTimer  _advertiseTimer;\n\tbool _sleepModeFlg;\n};\n\n/*=====================================\n        Class SendQue  (FIFO)\n ======================================*/\nclass SendQue {\npublic:\n    SendQue();\n    ~SendQue();\n    int addRequest(MqttsnMessage* msg);\n    int addPriorityRequest(MqttsnMessage* msg);\n    void setStatus(uint8_t index, uint8_t status);\n    MqttsnMessage* getMessage(uint8_t index);\n    int  getStatus(uint8_t index);\n    uint8_t getCount();\n    int deleteRequest(uint8_t index);\n    void   deleteAllRequest();\n    void setQueSize(uint8_t sz);\nprivate:\n    uint8_t   _queSize;\n    uint8_t   _queCnt;\n    MqttsnMessage*  _msg[SENDQ_SIZE];\n};\n\n\n/*=====================================\n        Class MqttsnClient\n ======================================*/\nclass MqttsnClient {\npublic:\n    MqttsnClient();\n    ~MqttsnClient();\n\n    Topics* getTopics();\n\n    int initialize(APP_CONFIG config);\n    void subscribe();\n    void setSubscribing(bool);\n    void setKeepAlive(uint16_t sec);\n    void setWillTopic(MQString* topic);\n    void setWillMessage(MQString* msg);\n    void setSleepMode(void);\n    void setRetain(bool retain);\n    void setClean(bool clean);\n    void setRetryMax(uint8_t cnt);\n    void setGwAddress();\n    MQString* getClientId();\n    ClientStatus* getClientStatus();\n    bool isCleanSession();\n\n\n    int  publish(MQString* topic, const char* data, int dataLength, uint8_t qos = 1);\n    int  publish(MQString* topic, MQString* data, uint8_t qos = 1);\n    int  publish(uint16_t predifinedId,  const char* data, int dataLength, uint8_t qos = 1);\n    int  publish(MQString* topic, Payload* payload, uint8_t qos = 1);\n    int  registerTopic(MQString* topic);\n    int  subscribe(MQString* topic, TopicCallback callback, uint8_t qos = 1);\n    int  subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos);\n    int  unsubscribe(MQString* topic);\n    int  unsubscribe(uint16_t predefinedId);\n    int  disconnect(uint16_t duration = 0);\n    void createTopics();\n\n    void recieveMessageHandler(NWResponse* msg, int* returnCode);\n    void publishHdl(MqttsnPublish* msg);\n    void recvMsg(uint16_t msec);\n    int  exec();\n    int readPacket();\n    uint8_t getMsgRequestCount();\n\nprivate:\n    int  sendRecvMsg();\n    void clearMsgRequest();\n    int  requestSendMsg(MqttsnMessage* msg);\n    int  requestPrioritySendMsg(MqttsnMessage* mqttsMsgPtr);\n    int  broadcast(uint16_t packetReadTimeout);\n    int  unicast(uint16_t packetReadTimeout);\n\n    int  searchGw(uint8_t radius);\n    int  connect();\n    int  pingReq(MQString* clietnId);\n    int  willTopic();\n    int  willMsg();\n    int  pubAck(uint16_t topicId, uint16_t msgId, uint8_t rc);\n    int  pubRec(uint16_t msgId);\n    int  pubRel(uint16_t msgId);\n    int  regAck(uint16_t topicId, uint16_t msgId, uint8_t rc);\n    int  pubComp(uint16_t msgId);\n\n    uint8_t getMsgRequestType();\n    uint8_t getMsgRequestStatus();\n    void   setMsgRequestStatus(uint8_t stat);\n    void createTopic(MQString* topic, TopicCallback callback);\n\n    void delayTime(uint16_t baseTime);\n    void copyMsg(MqttsnMessage* msg, NWResponse* recvMsg);\n    uint16_t getNextMsgId();\n\n    Network*         _network;\n    Topics           _topics;\n    SendQue*         _sendQ;\n    XTimer           _respTimer;\n    PublishHandller  _pubHdl;\n\n    uint16_t         _duration;\n    MQString*        _clientId;\n    uint8_t          _clientFlg;\n    uint8_t          _nRetry;\n    uint8_t          _nRetryCnt;\n    uint16_t         _tRetry;\n    MQString*         _willTopic;\n    MQString*         _willMessage;\n    uint16_t         _msgId;\n    ClientStatus     _clientStatus;\n    bool             _sendFlg;\n    bool             _subscribingFlg;\n};\n\n\n\n#endif /* MQTTSCLIENT_H_ */\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4Arduino.cpp",
    "content": "/*\n * mqttsnClientAppAppFw4Arduino.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/11/25\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.1.1\n */\n\n#ifdef ARDUINO\n#include <MQTTSN_Application.h>\n#include <mqttsnClientAppFw4Arduino.h>\n#include <avr/power.h>\n#include <avr/sleep.h>\n\n#if defined(MQTTSN_DEBUG) || defined(ZBEE_DEBUG) || defined(DEBUG)\n\t#include <SoftwareSerial.h>\n\textern SoftwareSerial debug;\n#endif\n\nusing namespace std;\nusing namespace tomyClient;\n\nvolatile uint8_t MQ_ErrFlag = MQ_OFF;\nvolatile uint8_t MQ_cnt = 0;\n\nenum MQ_INT_STATUS MQ_intStat;\nenum MQ_INT_STATUS MQ_wdtStat;\n\nextern uint32_t getUint32(uint8_t* pos);\n\nextern APP_CONFIG theAppConfig;\nextern TaskList theTaskList[];\nextern void interruptCallback(void);\n\nMqttsnClientApplication* theApplication = new MqttsnClientApplication();\n\nvoid loop(){\n\ttheApplication->registerInt0Callback(interruptCallback);\n\ttheApplication->addTask();\n\n\ttheApplication->setKeepAlive(theAppConfig.mqttsnCfg.keepAlive);\n\ttheApplication->setClean(theAppConfig.mqttsnCfg.cleanSession);\n\tif(theAppConfig.mqttsnCfg.willTopic){\n\t\tMQString* willTpc = new MQString(theAppConfig.mqttsnCfg.willTopic);\n\t\ttheApplication->setWillTopic(willTpc);\n\t}\n\tif(theAppConfig.mqttsnCfg.willMsg){\n\t\tMQString* willMsg = new MQString(theAppConfig.mqttsnCfg.willMsg);\n\t\ttheApplication->setWillMessage(willMsg);\n\t}\n\tif(theAppConfig.mqttsnCfg.endDevice){\n\t\ttheApplication->setZBPinHibernate();\n\t}\n\n\ttheApplication->initialize(theAppConfig);\n\n\tif(theAppConfig.mqttsnCfg.endDevice){\n\t\ttheApplication->startSleepMode();\n\t}else{\n\t\ttheApplication->startWdt();\n\t}\n\n\twhile(true){\n\t\ttheApplication->run();\n\t}\n}\n\n/*-------------------------------\n * Set WDT Interrupt procedure\n --------------------------------*/\nISR (WDT_vect) {\n\tcli();\n\tMCUSR = 0;\n\twdt_reset();\n\tWDTCSR |= B00011000;   // WDCE:on, WDE:on\n\tWDTCSR = 0x00;\n\tMQ_wdtStat = INT_WDT;\n\tsei();\n}\n\n/*-------------------------------\n * INT0 Interrupt procedure\n --------------------------------*/\nvoid MQInt0(){\n\tdetachInterrupt(0);\n\tMQ_intStat = INT0_LL;\n}\n\n/*-------------------------------\n * Set WDT\n --------------------------------*/\nvoid MQwatchdogEnable(){  // Turn on WDT\n\tcli();\n\tMCUSR = 0;\n\twdt_reset();\n\tWDTCSR |= B00011000;   // WDCE:on, WDE:on\n\tWDTCSR = MQ_WDT_TIME;\n\tMQ_wdtStat = WAIT;\n\tsei();\n}\n\n/*--------------------------------\n   Dummy function\n---------------------------------*/\nvoid IntHandleDummy(){\n}\n\n/*--------------------------------\n        reset Arduino\n---------------------------------*/\n//void (*resetArduino)(void) = 0;\nvoid resetArduino(){\n#ifdef DEBUG\n\t\tdebug.println(\"Reset\");\n#endif\n\tasm volatile(\"jmp 0000\");\n}\n\n/*--------------------------------\n        set UnixTime\n---------------------------------*/\nint setUTC(MqttsnPublish* msg){\n\tXTimer::setUnixTime(getUint32(msg->getData()));\n\treturn 0;\n}\n\n/*========================================\n\t\tClass MqttsnClientApplication\n=========================================*/\nMqttsnClientApplication::MqttsnClientApplication(){\n    _txFlag = false;\n    _intHandler = IntHandleDummy;\n    _sleepFlg = false;\n    _deviceType = ZB_ROUTER_DEVICE;\n\n}\n\nMqttsnClientApplication::~MqttsnClientApplication(){\n\n}\n\nvoid MqttsnClientApplication::addTask(){\n\tfor(int i = 0; theTaskList[i].callback; i++){\n\t\t_wdTimer.registerCallback(theTaskList[i].sec, theTaskList[i].callback);\n\t}\n}\n\nvoid MqttsnClientApplication::setSubscribe(){\n\t_mqttsn.setSubscribing(true);  // re-entrant control\n\t_mqttsn.subscribe();\n    _mqttsn.subscribe(MQTTSN_TOPICID_PREDEFINED_TIME, setUTC,QOS0);\n    _mqttsn.setSubscribing(false);\n}\n\nvoid MqttsnClientApplication::initialize(APP_CONFIG config){\n\t//blinkIndicator(100);\n    _mqttsn.initialize(config);\n    XTimer::initialize();\n    setSubscribe();\n}\n\nint MqttsnClientApplication::run(){\n\twakeupXB();\n\t_mqttsn.readPacket(); //ModemeStatus or Stored packet\n\t_mqttsn.readPacket();\n\tcheckInterupt();   // WDT routines are executed\n\n\tint rc = _mqttsn.exec();\n\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\tresetArduino();\n\t}else if(rc == MQTTSN_ERR_NO_ERROR){\n\t\tsleepXB();\n\t\tsleepApp();   // waiting WDT interruption\n\t}\n\treturn 0;\n}\n\n\nvoid MqttsnClientApplication::setKeepAlive(uint16_t sec){\n    _mqttsn.setKeepAlive(sec);\n}\n\n\nvoid MqttsnClientApplication::setWillTopic(MQString* willTopic){\n    _mqttsn.setWillTopic(willTopic);\n}\n\nvoid MqttsnClientApplication::setWillMessage(MQString* willMsg){\n    _mqttsn.setWillMessage(willMsg);\n}\n\nvoid MqttsnClientApplication::setRetain(bool retain){\n    _mqttsn.setRetain(retain);\n}\n\nvoid MqttsnClientApplication::setClean(bool clean){\n    _mqttsn.setClean(clean);\n}\n\n/*----------- Sleep related functions ------------*/\nvoid MqttsnClientApplication::startWdt(){\n    _wdTimer.start();\n}\n\nvoid MqttsnClientApplication::stopWdt(){\n    _wdTimer.stop();\n}\n\nvoid MqttsnClientApplication::sleepApp(){\n\tif(_deviceType == ZB_PIN_HIBERNATE && _sleepFlg){\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println(\"sleep\");\n#endif\n\t\tset_sleep_mode(SLEEP_MODE_PWR_SAVE);\n\t\tMQwatchdogEnable();\n\t\tsleep_enable();\n\t\tMQ_wdtStat = WAIT;\n\t\tsleep_mode();      // waiting WDT interrupt\n\t\tsleep_disable();\n\t\tXTimer::setStopTimeDuration(MQ_WDT_TIME_MSEC);\n\t}\n}\n\nvoid MqttsnClientApplication::sleepXB(){\n\tif(_deviceType == ZB_PIN_HIBERNATE && _sleepFlg){\n\t\tpinMode(XB_SLEEP_PIN, INPUT);\n\t}\n}\n\nvoid MqttsnClientApplication::wakeupXB(){\n\tif(_deviceType == ZB_PIN_HIBERNATE){\n\t\tpinMode(XB_SLEEP_PIN, OUTPUT);\n\t\tdigitalWrite(XB_SLEEP_PIN, LOW);\n\t\tdelay(20);\n\t}\n}\n\nvoid MqttsnClientApplication::startSleepMode(){\n\tif(_deviceType == ZB_PIN_HIBERNATE){\n\t\t_sleepFlg = true;\n\t\tMQ_intStat = WAIT;\n\t\tMQ_wdtStat = WAIT;\n\t\tsetInterrupt();\n\t}else{\n\t\t_sleepFlg = false;\n\t}\n}\n\nvoid MqttsnClientApplication::setZBPinHibernate(){\n\t_deviceType = ZB_PIN_HIBERNATE;\n\tpinMode(MQ_INT0_PIN,INPUT_PULLUP);\n\twakeupXB();\n\t_mqttsn.getClientStatus()->setModeSleep();\n}\n\n/*-------------- Interrupt related functions ------*/\nvoid MqttsnClientApplication::checkInterupt(){\n\n    // interrupt Event\n    if (MQ_intStat == INT0_LL){\n        MQ_intStat = INT0_WAIT_HL;\n        interruptHandler();\n        setInterrupt();\n    }\n    // WDT event\n    if (MQ_wdtStat == INT_WDT){\n\t\t_wdTimer.wakeUp();    // check interval & execute callback\n        _wdTimer.start();     // WDT restart\n    }\n}\n\nvoid MqttsnClientApplication::interruptHandler(){\n    wakeupXB();\n    _intHandler();\n    sleepXB();\n}\n\nvoid MqttsnClientApplication::setInterrupt(){\n    if (MQ_intStat == INT0_WAIT_HL){\n\t\twhile(digitalRead(MQ_INT0_PIN) == 0){\n\t\t\t\t// wait LL to HL\n\t\t}\n    }\n    MQ_intStat = WAIT;\n    attachInterrupt(0,MQInt0,LOW);\n}\n\n\n/*--------------------  MQTT-SN functions ---------------*/\n\nint MqttsnClientApplication::registerTopic(MQString* topic){\n    return _mqttsn.registerTopic(topic);\n}\n\nint MqttsnClientApplication::publish(MQString* topic, const char* data, int dataLength, uint8_t qos){\n\treturn _mqttsn.publish(topic, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::publish(MQString* topic, Payload* payload, uint8_t qos){\n\treturn _mqttsn.publish(topic, payload, qos);\n}\n\nint MqttsnClientApplication::subscribe(MQString* topic, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(topic, callback,qos);\n}\n\nint MqttsnClientApplication::subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(predefinedId, callback, qos);\n}\n\nint MqttsnClientApplication::publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos){\n    return _mqttsn.publish(predefinedId, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::unsubscribe(MQString* topic){\n    return _mqttsn.unsubscribe(topic);\n}\n\nint MqttsnClientApplication::disconnect(uint16_t duration){\n    return _mqttsn.disconnect(duration);\n}\n\n/*------------- UTC functions -------------*/\nuint32_t MqttsnClientApplication::getUnixTime(){\n\treturn XTimer::getUnixTime();\n}\n/*\n#define LEAP_YEAR(Y)  ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )\nstatic const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};\n\nvoid MqttsnClientApplication::getDateTime(char* buf) {\n\tuint16_t year;\n\tuint8_t month;\n\tuint8_t mLen;\n\tuint8_t day;\n\tuint8_t hour;\n\tuint8_t min;\n\tuint8_t sec;\n\tuint16_t days;\n\tuint32_t utc;\n\n\tutc = getUnixTime();\n\n\tsec = utc % 60;\n\tutc /= 60;\n\tmin = utc % 60;\n\tutc /= 60;\n\thour = utc % 24;\n\tutc /= 24;\n\n\tyear = days = 0;\n\twhile((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= utc) {\n\t    year++;\n\t}\n\tdays -= LEAP_YEAR(year) ? 366 : 365;\n\tyear += 1970;\n\tutc  -= days;\n\n\tdays = 0;\n\tfor (month = 0; month < 12; month++) {\n\t\tif (month == 1) {\n\t\t  if (LEAP_YEAR(year)) {\n\t\t\t  mLen = 29;\n\t\t  } else {\n\t\t\t  mLen = 28;\n\t\t  }\n\t\t} else {\n\t\t\tmLen = monthDays[month];\n\t\t}\n\t\tif (utc >= mLen) {\n\t\t  utc -= mLen;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\tmonth += 1;\n\tday = utc + 1;\n\n\tsprintf(buf,\"GMT%4d%2d%2d%2d%2d%2d\",year,month,day,hour,min,sec);\n\tchar* pos = buf + 7;\n\tfor(int i = 0; i < 10; i++){\n\t\tif(*( pos + i) == 0x20){\n\t\t\t*(pos + i) = 0x30;\n\t\t}\n\t}\n}\n*/\n\n/*-------------- Indicator --------------*/\nvoid MqttsnClientApplication::indicatorOn(){\n    digitalWrite(MQ_LED_PIN,MQ_ON);\n}\n\nvoid MqttsnClientApplication::indicatorOff(){\n    digitalWrite(MQ_LED_PIN,MQ_OFF);\n}\n\nvoid MqttsnClientApplication::blinkIndicator(int msec){\n    digitalWrite(MQ_LED_PIN,MQ_ON);\n    delay(msec);\n    digitalWrite(MQ_LED_PIN,MQ_OFF);\n}\n\n\n/*-------------- Callback related functions ---------------*/\nvoid MqttsnClientApplication::registerInt0Callback(void (*callback)()){\n    _intHandler = callback;\n}\n\nvoid MqttsnClientApplication::refleshWdtCallbackTable(){\n  _wdTimer.refleshRegisterTable();\n}\n\n/*======================================\n               Class WdTimer\n========================================*/\nWdTimer::WdTimer(void) {\n    _timerTbls = 0;\n    _timerCnt = 0;\n    _initFlg = true;\n\n}\n\nvoid WdTimer::start(void) {    \n\tMQwatchdogEnable();\n}\n\n\nvoid WdTimer::stop(void){\n    cli();\n    MCUSR = 0;\n    wdt_reset();\n    WDTCSR |= B00011000;   // WDCE:on, WDE:on\n    WDTCSR = 0x00;\n    MQ_wdtStat = WAIT;\n    sei();\n}\n\n\nbool WdTimer::wakeUp(void){\n    bool rcflg = false;\n    int rc;\n\tfor(uint8_t i = 0; i < _timerCnt; i++) {\n\t\tif ((_timerTbls[i].prevTime + _timerTbls[i].interval < getUnixTime()) || _initFlg){\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println(\"Task start\");\n#endif\n\t\t\trc = (_timerTbls[i].callback)();\n\t\t\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED || rc == MQTTSN_ERR_INVALID_TOPICID){\n\t\t\t\tresetArduino();\n\t\t\t}\n\t\t\t_timerTbls[i].prevTime = getUnixTime();\n\t\t\trcflg = true;\n\n#if defined(DEBUG) && defined(ARDUINO)\n\t\tdebug.println(\"Task end\");\n#endif\n\t\t}\n\t}\n\t_initFlg = false;\n    return rcflg;\n}\n\nint WdTimer::registerCallback(uint32_t sec, int (*callback)(void)){\n    MQ_TimerTbl *savTbl = _timerTbls;\n    MQ_TimerTbl *newTbl = (MQ_TimerTbl*)calloc(_timerCnt + 1,sizeof(MQ_TimerTbl));\n\n    if ( newTbl != 0 ) {\n        _timerTbls = newTbl;\n        for(uint8_t i = 0; i < _timerCnt; i++ ){\n\t\t\t_timerTbls[i].prevTime = savTbl[i].prevTime;\n\t\t\t_timerTbls[i].interval = savTbl[i].interval;\n\t\t\t_timerTbls[i].callback = savTbl[i].callback;\n        }\n        free(savTbl);\n\n        //_timerTbls[_timerCnt].prevTime = getUnixTime();\n        _timerTbls[_timerCnt].prevTime = (uint32_t)0;\n        _timerTbls[_timerCnt].interval = sec;\n        _timerTbls[_timerCnt].callback = callback;\n        _timerCnt++;\n        return MQTTSN_ERR_NO_ERROR;\n    }\n    return MQTTSN_ERR_OUT_OF_MEMORY;\n} \n\nvoid WdTimer::refleshRegisterTable(){\n    for(uint8_t i = 0; i < _timerCnt; i++) {\n        _timerTbls[i].prevTime = getUnixTime();\n    }\n}\n\n\n\n#endif  /* ARDUINO */\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4Arduino.h",
    "content": "/*\r\n * mqttsnClientAppFw4Arduino.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified: 2014/09/05\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 1.0.0\r\n */\r\n\r\n#ifdef ARDUINO\r\n\r\n#ifndef MQTTSNCLIENTAPPLICATION_H_\r\n#define MQTTSNCLIENTAPPLICATION_H_\r\n\r\n#include <MQTTSN_Application.h>\r\n#include <mqttsnClient.h>\r\n#include <mqUtil.h>\r\n#include <avr/wdt.h>\r\n#include <avr/sleep.h>\r\n#include <avr/interrupt.h>\r\n#include <inttypes.h>\r\n#include <Ethernet.h>\r\n#include <EthernetUdp.h>\r\n#include <SPI.h>\r\n\r\n#define MQ_LED_PIN  13\r\n#define MQ_INT0_PIN 2\r\n#define MQ_SLEEP_PIN 4  // Connect to XBee DTR for hibernation mode\r\n#define MQ_ERROR_RECOVERY_DURATION_ON 8\r\n#define MQ_ON      1\r\n#define MQ_OFF     0\r\n\r\n#define ZB_ROUTER_DEVICE  0\r\n#define ZB_PIN_HIBERNATE 1\r\n\r\n\r\n#define MQ_WDT_ERR   (B01100000)  // Error Indication time\r\n\r\n#define MQ_WDT_TIME (B01000110)   // 1 Sec\r\n#define MQ_WDT_TIME_MSEC   1000\r\n\r\n//#define MQ_WDT_TIME (B01000111)   // 2 Secs\r\n//#define MQ_WDT_TIME_MSEC   2000\r\n\r\n//#define MQ_WDT_TIME (B01100000)   // 4 Secs\r\n//#define MQ_WDT_TIME_MSEC   4000\r\n \r\n//#define MQ_WDT_TIME (B01100001)   // 8 Secs\r\n//#define MQ_WDT_TIME_MSEC   8000\r\n\r\n\r\nenum MQ_INT_STATUS{ WAIT, INT0_LL, INT0_WAIT_HL, INT_WDT};\r\n\r\n\r\n#define INDICATOR_ON()   theApplication->indicatorOn()\r\n#define INDICATOR_OFF()  theApplication->indicatorOff()\r\n#define BLINK_INDICATOR(...) theApplication->blinkIndicator(__VA_ARGS__)\r\n#define GETUTC()         theApplication->getUnixTime()\r\n//#define GET_DATETIME(...) theApplication->getDateTime(__VA_ARGS__)\r\n\r\n\r\nextern void setUint32(uint8_t*, uint32_t);\r\nextern uint32_t getUint32(uint8_t*);\r\nextern void setUint16(uint8_t*, uint16_t);\r\nextern uint16_t getUint16(uint8_t*);\r\n\r\n\r\n/*======================================\r\n               Class WdTimer\r\n========================================*/\r\nclass WdTimer:public XTimer {\r\npublic:\r\n\tWdTimer(void);\r\n\tint  registerCallback(uint32_t sec, int (*proc)(void));\r\n\tvoid refleshRegisterTable();\r\n\tvoid start(void);\r\n\tvoid stop(void);\r\n\tbool wakeUp(void);\r\n\r\nprivate:\t\r\n\tMQ_TimerTbl *_timerTbls;\r\n\tuint8_t _timerCnt;\r\n\tbool _initFlg;\r\n};\r\n\r\n\r\n/*======================================\r\n       Class MqttsnClientApplication\r\n========================================*/\r\nclass MqttsnClientApplication{\r\npublic:\r\n\tMqttsnClientApplication();\r\n\t~MqttsnClientApplication();\r\n\tvoid registerInt0Callback(void (*callback)());\r\n\tvoid registerWdtCallback(long sec, int (*callback)(void));\r\n\tvoid refleshWdtCallbackTable();\r\n\tint  initialize(APP_CONFIG config);\r\n\tint  setSubscribe();\r\n\tvoid setKeepAlive(uint16_t msec);\r\n\tvoid setWillTopic(MQString* willTopic);\r\n\tvoid setWillMessage(MQString* willMsg);\r\n\tvoid setRetain(bool retain);\r\n\tvoid setClean(bool clean);\r\n\tvoid setClientId(MQString* id);\r\n\tvoid setZBPinHibernate();\r\n\tvoid blinkIndicator(int msec);\r\n\tvoid startSleepMode();\r\n\tvoid subscribe(void);\r\n\tvoid addTask(void);\r\n\t\r\n\tint registerTopic(MQString* topic);\r\n\tint publish(MQString* topic, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(MQString* topic, Payload* payload, uint8_t qos);\r\n\tint subscribe(MQString* topic, TopicCallback callback, uint8_t qos = 1);\r\n\tint subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos = 1);\r\n\tint unsubscribe(MQString* topic);\r\n\tint disconnect(uint16_t duration);\r\n\r\n\tvoid startWdt();\r\n\tvoid stopWdt();\r\n\tint  run();\r\n\tvoid setUnixTime(MqttsnPublish* msg);\r\n\tuint32_t getUnixTime();\r\n\tvoid getDateTime(char* buf);\r\n\tvoid reboot();\r\n\tvoid indicatorOn();\r\n\tvoid indicatorOff();\r\n\r\nprivate:\r\n\tvoid checkInterupt();\r\n\tvoid interruptHandler();\r\n    void setInterrupt();\r\n\tvoid sleepXB();\r\n\tvoid wakeupXB();\r\n\tvoid sleepApp();\r\n\t\r\n\tMqttsnClient _mqttsn;\r\n\tbool _txFlag;\r\n\tbool  _sleepFlg;\r\n\tuint8_t _deviceType;\r\n\r\n\tWdTimer _wdTimer;\r\n\tXTimer _keepAliveTimer;\r\n\tXTimer _advertiseTimer;\r\n\r\n\tvoid (*_intHandler)(void);\r\n\r\n};\r\n\r\nextern MqttsnClientApplication* theApplication;\r\n\r\n#else\r\n\r\n#endif /*ARDUINO*/\r\n\r\n\r\n\r\n\r\n#endif /* MQTTSNCLIENTAPPLICATION_H_ */\r\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4Linux.cpp",
    "content": "/*\n * mqttsnClientAppAppFwLinux.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef ARDUINO\n \n#include \"MQTTSN_Application.h\"\n\n#ifdef LINUX\n#include \"mqttsnClientAppFw4Linux.h\"\n#include <unistd.h>\n#include <time.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <termios.h>\n\nusing namespace std;\nusing namespace tomyClient;\n\nMqttsnClientApplication* theApplication = new MqttsnClientApplication();\n\nextern TaskList theTaskList[];\nextern void  setup();\nextern MQString theTopics[];\n\n#ifdef NETWORK_XBEE\nXBeeAppConfig  theAppConfig = { { 0, 0, 0 },{ 0, 0, false, false, 0, 0 } };\n#endif\n\n#ifdef NETWORK_UDP\nUdpAppConfig   theAppConfig = {{ {0,0,0,0}, 0, {0,0,0,0}, 0, {0,0,0,0,0,0} },{ 0, 0, false, false, 0, 0 } };\n#endif\n\n\n/*========================================\n\t\tmain function\n=========================================*/\nint main(int argc, char **argv){\n\ttheApplication->addTask();\n\tsetup();\n\ttheApplication->initialize(argc, argv);\n\ttheApplication->run();\n\treturn 0;\n}\n\n/*========================================\n\t\tClass MqttsnClientApplication\n=========================================*/\nMqttsnClientApplication::MqttsnClientApplication(){\n\n}\n\nMqttsnClientApplication::~MqttsnClientApplication(){\n\n}\n\n\nvoid MqttsnClientApplication::startWdt(){\n    _wdTimer.start();\n}\n\nvoid MqttsnClientApplication::stopWdt(){\n    _wdTimer.stop();\n}\n\n/*------------ Client execution  forever --------------*/\nint MqttsnClientApplication::run(){\n\twhile(true){\n\t\t_wdTimer.wakeUp();\n\t\t_mqttsn.readPacket();\n\t\tint rc = _mqttsn.exec();\n\t\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\t\t_mqttsn.subscribe();\n\t\t}\n\t}\n\treturn 0;\n}\n\n\nvoid MqttsnClientApplication::initialize(int argc, char** argv){\n\tint arg;\n\tunsigned int val;\n\tchar* id = 0;\n\tMQString* willTopic;\n\tMQString* willMsg;\n#ifdef NETWORK_XBEE\n\tunsigned int br = B57600;\n\tchar* dev = 0;\n#endif\n#ifdef NETWORK_UDP\n\tchar* ipAddr = 0;\n\tuint16_t gPortNo = 0;\n\tuint16_t uPortNo = 0;\n#endif\n\n\twhile((arg = getopt(argc, argv, \"hcb:d:u:i:k:t:m:g:p:\"))!= -1){\n\t\tswitch(arg){\n\t\tcase 'h':\n\t\t\tprintf(\"Usage:  -b: [baudrate]      (XBee)\\n\");\n\t\t\tprintf(\"        -d: [device]        (XBee)\\n\");\n\t\t\tprintf(\"        -g: [groupIp]       (UDP)\\n\");\n\t\t\tprintf(\"        -p: [group portNo]  (UDP)\\n\");\n\t\t\tprintf(\"        -u: [client portNo] (UDP)\\n\");\n\t\t\tprintf(\"        -c: CleanSession\\n\");\n\t\t\tprintf(\"        -i: [ClientId]\\n\");\n\t\t\tprintf(\"        -k: [keepAliveTime in second]\\n\");\n\t\t\tprintf(\"        -t: [willTopic]\\n\");\n\t\t\tprintf(\"        -m: [willMessage]\\n\");\n\t\t\texit(0);\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\t_mqttsn.setClean(true);\n\t\t\tbreak;\n\n\t\tcase 'i':\n\t\t\tid = strdup(optarg);\n\t\t\tbreak;\n\t\tcase 't':\n\t\t\twillTopic = new MQString((const char*)optarg);\n\t\t\t_mqttsn.setWillTopic(willTopic);\n\t\t\tbreak;\n\t\tcase 'm':\n\t\t\twillMsg = new MQString((const char*)optarg);\n\t\t\t_mqttsn.setWillMessage(willMsg);\n\t\t\tbreak;\n\t\tcase 'k':\n\t\t\tval = atoi(optarg);\n\t\t\t_mqttsn.setKeepAlive(val);\n\t\t\tbreak;\n#ifdef NETWORK_XBEE\n\t\tcase 'd':\n\t\t\tdev = strdup(optarg);\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\tval = atoi(optarg);\n\t\t\tswitch(val){\n\t\t\tcase 9600:\n\t\t\t\tbr = B9600;\n\t\t\t\tbreak;\n\t\t\tcase 19200:\n\t\t\t\tbr =B19200;\n\t\t\t\tbreak;\n\t\t\tcase 38400:\n\t\t\t\tbr =B38400;\n\t\t\t\tbreak;\n\t\t\tcase 57600:\n\t\t\t\tbr =B57600;\n\t\t\t\tbreak;\n\t\t\tcase 115200:\n\t\t\t\tbr = B115200;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tprintf(\"Invalid baudrate!\\n\");\n\t\t\t\texit(-1);\n\t\t\t}\n\t\t\tbreak;\n#endif\n#ifdef NETWORK_UDP\n\t\tcase 'g':\n\t\t\tipAddr = optarg;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tgPortNo = atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'u':\n\t\t\tuPortNo = atoi(optarg);\n\t\t\tbreak;\n#endif\n\t\tcase '?':\n\t\t\tprintf(\"Unrecognized option! %c\\n\", arg);\n\t\t\texit(-1);\n\t\t}\n\t}\n\n#ifdef NETWORK_XBEE\n    if(br && dev){\n        theAppConfig.netCfg.baudrate = br;\n　       theAppConfig.netCfg.device = strdup(dev);\n    }else{\n        printf(\"argument error\\n\");\n        exit(1);\n    }\n#endif\n\n#ifdef NETWORK_UDP\n\tif(gPortNo && ipAddr[0] && uPortNo){\n\t\ttheAppConfig.netCfg.gPortNo = gPortNo;\n\t\ttheAppConfig.netCfg.uPortNo = uPortNo;\n\t\tuint32_t ipaddr = inet_addr(ipAddr);\n\t\ttheAppConfig.netCfg.ipAddress[0] = (ipaddr & 0xff000000) >> 24;\n\t\ttheAppConfig.netCfg.ipAddress[1] = (ipaddr & 0x00ff0000) >> 16;\n\t\ttheAppConfig.netCfg.ipAddress[2] = (ipaddr & 0x0000ff00) >> 8;\n\t\ttheAppConfig.netCfg.ipAddress[3] = (ipaddr & 0x000000ff);\n\t}else{\n\t\tprintf(\"argument error\\n\");\n\t\texit(1);\n\t}\n#endif\n\n\tif(id){\n\t\ttheAppConfig.mqttsnCfg.nodeId = strdup(id);\n\t}else{\n\t\ttheAppConfig.mqttsnCfg.nodeId =\"node\";\n\t}\n\n\t_mqttsn.initialize(theAppConfig);\n\n\tsetSubscribe();\n}\n\nvoid MqttsnClientApplication::setSubscribe(){\n\t_mqttsn.setSubscribing(true);\n    _mqttsn.createTopics();\n\t_mqttsn.subscribe();\n\t_mqttsn.setSubscribing(false);\n}\n\nvoid MqttsnClientApplication::addTask(){\n\tfor(int i = 0; theTaskList[i].sec; i++){\n\t\t_wdTimer.registerCallback(theTaskList[i].sec, theTaskList[i].callback);\n\t}\n}\n\nint MqttsnClientApplication::publish(MQString* topic, const char* data, int dataLength, uint8_t qos){\n\treturn _mqttsn.publish(topic, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos){\n    return _mqttsn.publish(predefinedId, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::publish(MQString* topic, Payload* payload, uint8_t qos){\n\treturn _mqttsn.publish(topic, payload, qos);\n}\n\nint MqttsnClientApplication::subscribe(MQString* topic, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(topic, callback,qos);\n}\n\nint MqttsnClientApplication::subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(predefinedId, callback, qos);\n}\n\n\nint MqttsnClientApplication::unsubscribe(MQString* topic){\n    return _mqttsn.unsubscribe(topic);\n}\n\nint MqttsnClientApplication::disconnect(uint16_t duration){\n    return _mqttsn.disconnect(duration);\n}\n\nvoid MqttsnClientApplication::setRetain(bool flag){\n    _mqttsn.setRetain(flag);\n}\n\n\n\n/*-------------- Callback related functions ---------------*/\n\n\nvoid MqttsnClientApplication::refleshWdtCallbackTable(){\n  _wdTimer.refleshRegisterTable();\n}\n\n/*======================================\n               Class WdTimer\n========================================*/\nWdTimer::WdTimer(void) {\n    _timerTbls = 0;\n    _timerCnt = 0;\n    _initFlg = true;\n\n}\n\nvoid WdTimer::start(void) {    \n\t//MQwatchdogEnable();\n}\n\n\nvoid WdTimer::stop(void){\n    //\n}\n\n\nbool WdTimer::wakeUp(void){\n    bool rcflg = false;\n    int rc;\n\tfor(uint8_t i = 0; i < _timerCnt; i++) {\n\t\tif ((_timerTbls[i].prevTime + _timerTbls[i].interval < (uint32_t)time(0)) || _initFlg){\n\t\t\trc = (_timerTbls[i].callback)();\n\t\t\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\t\t\ttheApplication->setSubscribe();\n\t\t\t}\n\t\t\t_timerTbls[i].prevTime = time(0);\n\t\t\trcflg = true;\n\t\t}\n\t}\n\t_initFlg = false;\n    return rcflg;\n}\n\nint WdTimer::registerCallback(uint32_t sec, int (*callback)(void)){\n    MQ_TimerTbl *savTbl = _timerTbls;\n    MQ_TimerTbl *newTbl = (MQ_TimerTbl*)calloc((unsigned int)_timerCnt + 1,sizeof(MQ_TimerTbl));\n\n    if ( newTbl != 0 ) {\n        _timerTbls = newTbl;\n        for(uint8_t i = 0; i < _timerCnt; i++ ){\n\t\t\t_timerTbls[i].prevTime = savTbl[i].prevTime;\n\t\t\t_timerTbls[i].interval = savTbl[i].interval;\n\t\t\t_timerTbls[i].callback = savTbl[i].callback;\n        }\n        free(savTbl);\n\n        _timerTbls[_timerCnt].prevTime = time(0);\n        _timerTbls[_timerCnt].interval = sec;\n        _timerTbls[_timerCnt].callback = callback;\n        _timerCnt++;\n        return MQTTSN_ERR_NO_ERROR;\n    }\n    return MQTTSN_ERR_OUT_OF_MEMORY;\n} \n\nvoid WdTimer::refleshRegisterTable(){\n    for(uint8_t i = 0; i < _timerCnt; i++) {\n        _timerTbls[i].prevTime = time(0);\n    }\n}\n\n\n#endif\n#endif\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4Linux.h",
    "content": "/*\r\n * mqttsnClientAppFw4Linux.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified: 2014/09/05\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 1.0.0\r\n */\r\n\r\n#ifdef LINUX\r\n\r\n#ifndef MQTTSNCLIENTAPPLICATION_H_\r\n#define MQTTSNCLIENTAPPLICATION_H_\r\n\r\n#include \"MQTTSN_Application.h\"\r\n#include \"mqttsnClient.h\"\r\n#include \"mqUtil.h\"\r\n\r\n\r\n/*======================================\r\n               Class WdTimer\r\n========================================*/\r\nclass WdTimer:public XTimer {\r\npublic:\r\n\tWdTimer(void);\r\n\tint  registerCallback(uint32_t sec, int (*proc)(void));\r\n\tvoid refleshRegisterTable();\r\n\tvoid start(void);\r\n\tvoid stop(void);\r\n\tbool wakeUp(void);\r\n\r\nprivate:\t\r\n\tMQ_TimerTbl *_timerTbls;\r\n\tuint8_t _timerCnt;\r\n\tbool _initFlg;\r\n};\r\n\r\n\r\n/*======================================\r\n       Class MqttsnClientApplication\r\n========================================*/\r\nclass MqttsnClientApplication{\r\npublic:\r\n\tMqttsnClientApplication();\r\n\t~MqttsnClientApplication();\r\n\tvoid refleshWdtCallbackTable();\r\n\tvoid initialize(int argc, char** argv);\r\n\tvoid setSubscribe();\r\n\r\n\tint publish(MQString* topic, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(MQString* topic, Payload* payload, uint8_t qos);\r\n\tint subscribe(MQString* topic, TopicCallback callback, uint8_t qos = 1);\r\n\tint subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos = 1);\r\n\tint unsubscribe(MQString* topic);\r\n\tint disconnect(uint16_t duration);\r\n\tvoid setRetain(bool flag);\r\n\r\n\tvoid addTask();\r\n\tvoid startWdt();\r\n\tvoid stopWdt();\r\n\tint  run();\r\n\r\n\r\nprivate:\r\n\tMqttsnClient _mqttsn;\r\n\tWdTimer _wdTimer;\r\n\tXTimer _keepAliveTimer;\r\n\tXTimer _advertiseTimer;\r\n\r\n};\r\n\r\nextern MqttsnClientApplication* theApplication;\r\n\r\n\r\n\r\n#else\r\n\r\n#endif /*LINUX*/\r\n\r\n\r\n\r\n\r\n#endif /* MQTTSCLIENTAPPLICATION_H_ */\r\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4mbed.cpp",
    "content": "/*\n * mqttsnClientAppAppFwmbed.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef ARDUINO\n\n#include \"MQTTSN_Application.h\"\n#ifdef MBED\n#include \"mqttsnClientAppFw4mbed.h\"\n#include <time.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\nusing namespace std;\nusing namespace tomyClient;\n\nMqttsnClientApplication* theApplication = new MqttsnClientApplication();\n\nextern TaskList theTaskList[];\nextern OnPublishList theOnPublishList[];\nextern APP_CONFIG    theAppConfig;\nextern void  setup();\n\n/*========================================\n\t\tmain function\n=========================================*/\nint main(){\n\ttheApplication->setKeepAlive(theAppConfig.mqttsnCfg.keepAlive);\n\ttheApplication->setClean(theAppConfig.mqttsnCfg.cleanSession);\n\tif(theAppConfig.mqttsnCfg.willTopic){\n\t\tMQString* willTpc = new MQString(theAppConfig.mqttsnCfg.willTopic);\n\t\ttheApplication->setWillTopic(willTpc);\n\t}\n\tif(theAppConfig.mqttsnCfg.willMsg){\n\t\tMQString* willMsg = new MQString(theAppConfig.mqttsnCfg.willMsg);\n\t\ttheApplication->setWillMessage(willMsg);\n\t}\n\n\ttheApplication->addTask();\n\tsetup();\n\ttheApplication->initialize(theAppConfig);\n\ttheApplication->run();\n\treturn 0;\n}\n\n/*========================================\n\t\tClass MqttsnClientApplication\n=========================================*/\n/*--------------------------------\n        set UnixTime\n---------------------------------*/\nint setUTC(MqttsnPublish* msg){\n\tset_time(getUint32(msg->getData()));\n\treturn 0;\n}\n\nMqttsnClientApplication::MqttsnClientApplication(){\n\n}\n\nMqttsnClientApplication::~MqttsnClientApplication(){\n\n}\n\n\nvoid MqttsnClientApplication::startWdt(){\n    _wdTimer.start();\n}\n\nvoid MqttsnClientApplication::stopWdt(){\n    _wdTimer.stop();\n}\n\n/*------------ Client execution  forever --------------*/\nint MqttsnClientApplication::run(){\n\twhile(true){\n\t\t_wdTimer.wakeUp();\n\t\t_mqttsn.readPacket();\n\t\tint rc = _mqttsn.exec();\n\t\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\t\t_mqttsn.subscribe();\n\t\t}\n\t}\n}\n\n\nvoid MqttsnClientApplication::initialize(APP_CONFIG config){\n\t_mqttsn.initialize(config);\n\tsetSubscribe();\n}\n\nvoid MqttsnClientApplication::setSubscribe(){\n\t_mqttsn.setSubscribing(true);  // re-entrant control\n\t_mqttsn.subscribe();\n\t_mqttsn.subscribe(MQTTSN_TOPICID_PREDEFINED_TIME, setUTC,1);\n\t_mqttsn.setSubscribing(false);\n}\n\t\nvoid MqttsnClientApplication::addTask(){\n\tfor(int i = 0; theTaskList[i].sec; i++){\n\t\t_wdTimer.registerCallback(theTaskList[i].sec, theTaskList[i].callback);\n\t}\n}\n\nvoid MqttsnClientApplication::setKeepAlive(uint16_t sec){\n    _mqttsn.setKeepAlive(sec);\n}\n\n\nvoid MqttsnClientApplication::setWillTopic(MQString* willTopic){\n    _mqttsn.setWillTopic(willTopic);\n}\n\nvoid MqttsnClientApplication::setWillMessage(MQString* willMsg){\n    _mqttsn.setWillMessage(willMsg);\n}\n\nvoid MqttsnClientApplication::setRetain(bool retain){\n    _mqttsn.setRetain(retain);\n}\n\nvoid MqttsnClientApplication::setClean(bool clean){\n    _mqttsn.setClean(clean);\n}\n\nint MqttsnClientApplication::publish(MQString* topic, const char* data, int dataLength, uint8_t qos){\n\treturn _mqttsn.publish(topic, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos){\n    return _mqttsn.publish(predefinedId, data, dataLength, qos);\n}\n\nint MqttsnClientApplication::publish(MQString* topic, Payload* payload, uint8_t qos){\n\treturn _mqttsn.publish(topic, payload, qos);\n}\n\n\nint MqttsnClientApplication::subscribe(MQString* topic, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(topic, callback,qos);\n}\n\nint MqttsnClientApplication::subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos){\n    return _mqttsn.subscribe(predefinedId, callback, qos);\n}\n\n\nint MqttsnClientApplication::unsubscribe(MQString* topic){\n    return _mqttsn.unsubscribe(topic);\n}\n\nint MqttsnClientApplication::disconnect(uint16_t duration){\n    return _mqttsn.disconnect(duration);\n}\n\n/*-------------- Callback related functions ---------------*/\n\n\nvoid MqttsnClientApplication::refleshWdtCallbackTable(){\n  _wdTimer.refleshRegisterTable();\n}\n\n/*======================================\n               Class WdTimer\n========================================*/\nWdTimer::WdTimer(void) {\n    _timerTbls = 0;\n    _timerCnt = 0;\n    _initFlg = true;\n\n}\n\nvoid WdTimer::start(void) {    \n\t//MQwatchdogEnable();\n}\n\n\nvoid WdTimer::stop(void){\n    //\n}\n\n\nbool WdTimer::wakeUp(void){\n    bool rcflg = false;\n    int rc;\n\tfor(uint8_t i = 0; i < _timerCnt; i++) {\n\t\tif ((_timerTbls[i].prevTime + _timerTbls[i].interval < (uint32_t)time(0)) || _initFlg){\n\t\t\trc = (_timerTbls[i].callback)();\n\t\t\tif(rc == MQTTSN_ERR_REBOOT_REQUIRED){\n\t\t\t\ttheApplication->initialize(theAppConfig);\n\t\t\t}\n\t\t\t_timerTbls[i].prevTime = time(0);\n\t\t\trcflg = true;\n\t\t}\n\t}\n\t_initFlg = false;\n    return rcflg;\n}\n\nint WdTimer::registerCallback(uint32_t sec, int (*callback)(void)){\n    MQ_TimerTbl *savTbl = _timerTbls;\n    MQ_TimerTbl *newTbl = (MQ_TimerTbl*)calloc(_timerCnt + 1,sizeof(MQ_TimerTbl));\n\n    if ( newTbl != 0 ) {\n        _timerTbls = newTbl;\n        for(uint8_t i = 0; i < _timerCnt; i++ ){\n\t\t\t_timerTbls[i].prevTime = savTbl[i].prevTime;\n\t\t\t_timerTbls[i].interval = savTbl[i].interval;\n\t\t\t_timerTbls[i].callback = savTbl[i].callback;\n        }\n        free(savTbl);\n\n        _timerTbls[_timerCnt].prevTime = time(0);\n        _timerTbls[_timerCnt].interval = sec;\n        _timerTbls[_timerCnt].callback = callback;\n        _timerCnt++;\n        return MQTTSN_ERR_NO_ERROR;\n    }\n    return MQTTSN_ERR_OUT_OF_MEMORY;\n} \n\nvoid WdTimer::refleshRegisterTable(){\n    for(uint8_t i = 0; i < _timerCnt; i++) {\n        _timerTbls[i].prevTime = time(0);\n    }\n}\n\n\n#endif\n#endif\n\n\n\n"
  },
  {
    "path": "Client/src/lib/mqttsnClientAppFw4mbed.h",
    "content": "/*\r\n * mqttsnClientAppFw4mbed.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified: 2014/09/05\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 1.0.0\r\n */\r\n\r\n#ifdef MBED\r\n\r\n#ifndef MQTTSNCLIENTAPPLICATION_H_\r\n#define MQTTSNCLIENTAPPLICATION_H_\r\n\r\n#include \"mqttsnClient.h\"\r\n\r\n\r\nextern uint16_t getUint16(uint8_t* pos);\r\nextern uint32_t getUint32(uint8_t* pos);\r\nextern void setUint16(uint8_t* pos, uint16_t val);\r\nextern void setUint32(uint8_t* pos, uint32_t val);\r\n\r\n/*======================================\r\n               Class WdTimer\r\n========================================*/\r\nclass WdTimer:public XTimer {\r\npublic:\r\n\tWdTimer(void);\r\n\tint registerCallback(uint32_t sec, int (*proc)(void));\r\n\tvoid refleshRegisterTable();\r\n\tvoid start(void);\r\n\tvoid stop(void);\r\n\tbool wakeUp(void);\r\n\r\nprivate:\r\n\tMQ_TimerTbl *_timerTbls;\r\n\tuint8_t _timerCnt;\r\n\tbool _initFlg;\r\n};\r\n\r\n\r\n/*======================================\r\n       Class MqttsnClientApplication\r\n========================================*/\r\nclass MqttsnClientApplication{\r\npublic:\r\n\tMqttsnClientApplication();\r\n\t~MqttsnClientApplication();\r\n\tvoid refleshWdtCallbackTable();\r\n\tvoid initialize(APP_CONFIG config);\r\n\tvoid setSubscribe();\r\n\tvoid setKeepAlive(uint16_t msec);\r\n\tvoid setWillTopic(MQString* willTopic);\r\n\tvoid setWillMessage(MQString* willMsg);\r\n\tvoid setRetain(bool retain);\r\n\tvoid setClean(bool clean);\r\n\tvoid setClientId(MQString* id);\r\n\r\n\tint publish(MQString* topic, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(uint16_t predefinedId, const char* data, int dataLength, uint8_t qos = 1);\r\n\tint publish(MQString* topic, Payload* payload, uint8_t qos);\r\n\tint subscribe(MQString* topic, TopicCallback callback, uint8_t qos = 1);\r\n\tint subscribe(uint16_t predefinedId, TopicCallback callback, uint8_t qos = 1);\r\n\tint unsubscribe(MQString* topic);\r\n\tint disconnect(uint16_t duration);\r\n\r\n\tvoid addTask();\r\n\tvoid startWdt();\r\n\tvoid stopWdt();\r\n\tint  run();\r\n\r\n\r\nprivate:\r\n\tMqttsnClient _mqttsn;\r\n\tWdTimer _wdTimer;\r\n\tXTimer _keepAliveTimer;\r\n\tXTimer _advertiseTimer;\r\n\r\n};\r\n\r\nextern MqttsnClientApplication* theApplication;\r\n\r\n\r\n\r\n#else\r\n\r\n#endif /*LINUX*/\r\n\r\n\r\n\r\n\r\n#endif /* MQTTSCLIENTAPPLICATION_H_ */\r\n\r\n\r\n"
  },
  {
    "path": "Client/src/lib/udpStack.cpp",
    "content": "/*\n * udpStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef ARDUINO\n        #include \"MQTTSN_Application.h\"\n\t\t#include \"Network.h\"\n#else\n        #include <MQTTSN_Application.h>\n\t\t#include <Network.h>\n#endif\n\n#ifdef NETWORK_UDP\n\n#ifdef ARDUINO\n  #include <udpStack.h>\n  #include <mqUtil.h>\n  #include <SPI.h>\n  #include <Ethernet.h>\n  #include <EthernetUdp.h>\n\n  #if defined( NW_DEBUG) || defined(MQTTSN_DEBUG)\n        #include <SoftwareSerial.h>\n        extern SoftwareSerial debug;\n  #endif\n\n#endif  /* ARDUINO */\n\n#ifdef MBED\n        #include \"mbed.h\"\n        #include \"udpStack.h\"\n\t\t#include \"mqUtil.h\"\n#endif /* MBED */\n\n#ifdef LINUX\n        #include \"udpStack.h\"\n\t\t#include \"mqUtil.h\"\n        #include <stdio.h>\n        #include <sys/time.h>\n        #include <sys/types.h>\n\t\t#include <sys/socket.h>\n        #include <sys/stat.h>\n        #include <unistd.h>\n        #include <stdlib.h>\n        #include <string.h>\n        #include <fcntl.h>\n        #include <errno.h>\n        #include <termios.h>\n\n#endif /* LINUX */\n\nusing namespace std;\nusing namespace tomyClient;\n\nextern uint16_t getUint16(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern uint32_t getUint32(uint8_t* pos);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=========================================\n       Class Network\n =========================================*/\nNetwork::Network(){\n\t_sleepflg = false;\n\tresetGwAddress();\n}\n\nNetwork::~Network(){\n\n}\n\nvoid Network::send(uint8_t* xmitData, uint8_t dataLen, SendReqType type){\n\tif(type == BcastReq){\n\t\tmulticast(xmitData, (uint16_t)dataLen);\n\t}else if(type == UcastReq ){\n\t\tunicast(xmitData, (uint16_t)dataLen, _gwIpAddress, _gwPortNo);\n\t}\n}\n\nint  Network::readPacket(uint8_t type){\n\t_returnCode = 0;\n\n\tif(checkRecvBuf()){\n\t\tif(readApiFrame()){\n\t\t\tif(_nlResp.isAvailable()){\n\t\t\t\tif(_rxCallbackPtr){\n\t\t\t\t\t_rxCallbackPtr(&_nlResp, &_returnCode);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn _returnCode;\n}\n\n\nint  Network::readApiFrame(){\n\tuint16_t portNo = 0;\n\tuint32_t ipAddress = 0;\n\tuint16_t len;\n\n\tif (_nlResp.isAvailable() || _nlResp.isError()){\n\t   _nlResp.setAvailable(false);\n\t   _nlResp.setErrorCode(NO_ERROR);\n\t}\n\n\tuint16_t recvLen = recv(_rxFrameDataBuf, MQTTSN_MAX_FRAME_SIZE, false, &ipAddress, &portNo);\n\n\tif( recvLen > 0){\n\t\tif(*_rxFrameDataBuf == 0x01){\n\t\t\tlen = getUint16(_rxFrameDataBuf + 1);\n\t\t}else{\n\t\t\tlen = *_rxFrameDataBuf;\n\t\t}\n\n\t\tif( len != recvLen){\n\t\t\t_nlResp.setErrorCode(PACKET_EXCEEDS_LENGTH);\n\t\t\t\t\t\treturn false;\n\t\t}else if(_gwIpAddress && isUnicast() &&\n\t\t \t\t (_nlResp.getAddress64().getLsb() != _gwIpAddress) &&\n\t\t\t\t (_nlResp.getAddress16() != _gwPortNo)){\n\t\t\tD_NWSTACKW(\"  Sender is not Gateway!\\r\\n\" );\n\t\t\treturn false;\n\t\t}else{\n\t\t\t_nlResp.setLength(len);\n\t\t\t_nlResp.setAvailable(true);\n\t\t\t_nlResp.setFrame(_rxFrameDataBuf);\n\t\t\t_nlResp.setAddress16(portNo);\n\t\t\t_nlResp.setAddress64(0,ipAddress);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nvoid Network::setGwAddress(){\n\t_gwPortNo = _nlResp.getAddress16();\n\t_gwIpAddress = _nlResp.getAddress64().getLsb();\n}\n\nvoid Network::resetGwAddress(void){\n\t_gwIpAddress = 0;\n\t_gwPortNo = 0;\n}\n\nvoid Network::setRxHandler(void (*callbackPtr)(NWResponse* data, int* returnCode)){\n\t_rxCallbackPtr = callbackPtr;\n}\n\nint Network::initialize(UdpConfig  config){\n\treturn open(config);\n}\n\nvoid Network::setSleep(){\n\t_sleepflg = true;\n}\n\n/*=========================================\n       Class udpStack\n =========================================*/\n#ifdef ARDUINO\n/**\n *  For Arduino\n */\nUdpPort::UdpPort(){\n\n}\n\nUdpPort::~UdpPort(){\n    close();\n}\n\nvoid UdpPort::close(){\n\n}\n\n\nbool UdpPort::open(UdpConfig config){\n\t_gIpAddr = IPAddress(config.ipAddress);\n\t_cIpAddr = IPAddress(config.ipLocal);\n\t_gPortNo = config.gPortNo;\n\t_uPortNo = config.uPortNo;\n\n\tmemcpy(_macAddr, config.macAddr, 6);\n\n\tEthernet.begin(_macAddr, _cIpAddr);\n\n\tif(_udpMulticast.beginMulti(_gIpAddr, _gPortNo) == 0){\n\t\treturn false;\n\t}\n\tif(_udpUnicast.begin(_uPortNo) == 0){\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nint UdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port  ){\n\n\tIPAddress ip = IPAddress(ipAddress);\n\t_udpUnicast.beginPacket(ip, port);\n\t_udpUnicast.write(buf, length);\n\treturn _udpUnicast.endPacket();\n}\n\n\nint UdpPort::multicast( const uint8_t* buf, uint32_t length ){\n\t_udpMulticast.beginPacket(_gIpAddr, _gPortNo);\n\t_udpMulticast.write(buf, length);\n\treturn _udpMulticast.endPacket();\n}\n\nbool UdpPort::checkRecvBuf(){\n\tint ps = _udpUnicast.parsePacket();\n\tif(ps > 0){\n\t\t_castStat = STAT_UNICAST;\n\t\treturn true;\n\t}else if ( (ps = _udpMulticast.parsePacket()) > 0){\n\t\t_castStat = STAT_MULTICAST;\n\t\treturn true;\n\t}\n\t_castStat = 0;\n\treturn 0;\n}\n\nint UdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){\n\treturn recvfrom ( buf, len, 0, ipAddressPtr, portPtr );\n}\n\nint UdpPort::recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){\n\tIPAddress remoteIp;\n\tuint8_t packLen;\n\tif(_castStat == STAT_UNICAST){\n\t\tpackLen = _udpUnicast.read(buf, len);\n\t\t*portPtr = _udpUnicast.remotePort();\n\t\tremoteIp = _udpUnicast.remoteIP();\n\t}else if(_castStat == STAT_MULTICAST){\n\t\tpackLen = _udpMulticast.read(buf, len);\n\t\t*portPtr = _udpMulticast.remotePort();\n\t\tremoteIp = _udpMulticast.remoteIP();\n\t}else{\n\t\treturn 0;\n\t}\n\tmemcpy(ipAddressPtr,remoteIp.raw_address(), 4);\n\treturn packLen;\n}\n\nbool UdpPort::isUnicast(){\n\treturn ( _castStat == STAT_UNICAST);\n}\n\n#endif /* ARDUINO */\n\n\n#ifdef MBED\n/**\n *  For MBED\n */\n\n\n#endif /* MBED */\n\n#ifdef LINUX\n\nUdpPort::UdpPort(){\n    _disconReq = false;\n    _sockfdUcast = -1;\n    _sockfdMcast = -1;\n    _castStat = 0;\n}\n\nUdpPort::~UdpPort(){\n    close();\n}\n\n\nvoid UdpPort::close(){\n\tif(_sockfdMcast > 0){\n\t\t::close( _sockfdMcast);\n\t\t_sockfdMcast = -1;\n\tif(_sockfdUcast > 0){\n\t\t\t::close( _sockfdUcast);\n\t\t\t_sockfdUcast = -1;\n\t\t}\n\t}\n}\n\nbool UdpPort::open(UdpConfig config){\n\tconst int reuse = 1;\n\tchar loopch = 0;\n\n\t_gPortNo = htons(config.gPortNo);\n\t_gIpAddr = getUint32(config.ipAddress);\n\t_uPortNo = htons(config.uPortNo);\n\n\tif( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){\n\t\treturn false;\n\t}\n\n\t_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);\n\tif (_sockfdUcast < 0){\n\t\treturn false;\n\t}\n\n\tsetsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));\n\n\tstruct sockaddr_in addr;\n\taddr.sin_family = AF_INET;\n\taddr.sin_port = _uPortNo;\n\taddr.sin_addr.s_addr = INADDR_ANY;\n\n\tif( ::bind ( _sockfdUcast, (struct sockaddr*)&addr,  sizeof(addr)) <0){\n\t\treturn false;\n\t}\n\n\t_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n\tif (_sockfdMcast < 0){\n\t\treturn false;\n\t}\n\n\tstruct sockaddr_in addrm;\n\taddrm.sin_family = AF_INET;\n\taddrm.sin_port = _gPortNo;\n\taddrm.sin_addr.s_addr = INADDR_ANY;\n\n\tsetsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));\n\n\tif( ::bind ( _sockfdMcast, (struct sockaddr*)&addrm,  sizeof(addrm)) <0){\n\t\treturn false;\n\t}\n\n\tif(setsockopt(_sockfdUcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){\n\t\tD_NWSTACKW(\"error IP_MULTICAST_LOOP in UdpPort::open\\n\");\n\n\t\tclose();\n\t\treturn false;\n\t}\n\n\tif(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){\n\t\tD_NWSTACKW(\"error IP_MULTICAST_LOOP in UdpPPort::open\\n\");\n\t\tclose();\n\t\treturn false;\n\t}\n\n\tip_mreq mreq;\n\tmreq.imr_interface.s_addr = INADDR_ANY;\n\tmreq.imr_multiaddr.s_addr = getUint32(config.ipAddress);\n\n\tif( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){\n\t\tD_NWSTACKF(\"error IP_ADD_MEMBERSHIP in UdpPort::open\\n\");\n\t\tclose();\n\t\treturn false;\n\t}\n/*\n\tif( setsockopt(_sockfdUcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){\n\t\tD_NWSTACKF(\"error IP_ADD_MEMBERSHIP in UdpPort::open\\n\");\n\t\tclose();\n\t\treturn false;\n\t}\n*/\n\treturn true;\n}\n\nbool UdpPort::isUnicast(){\n\treturn ( _castStat == STAT_UNICAST);\n}\n\n\nint UdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port  ){\n\tstruct sockaddr_in dest;\n\tdest.sin_family = AF_INET;\n\tdest.sin_port = port;\n\tdest.sin_addr.s_addr = ipAddress;\n\n\tint status = ::sendto( _sockfdUcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );\n\tif( status < 0){\n\t\tD_NWSTACKF(\"errno == %d in UdpPort::unicast\\n\", errno);\n\t}else{\n\t\tD_NWSTACKF(\"sendto %s:%u  [\",inet_ntoa(dest.sin_addr),htons(port));\n\t\tfor(uint16_t i = 0; i < length ; i++){\n\t\t\tD_NWSTACKF(\" %02x\", *(buf + i));\n\t\t}\n\t\tD_NWSTACKF(\" ]\\n\");\n\t}\n\treturn status;\n}\n\n\nint UdpPort::multicast( const uint8_t* buf, uint32_t length ){\n\tstruct sockaddr_in dest;\n\tdest.sin_family = AF_INET;\n\tdest.sin_port = _gPortNo;\n\tdest.sin_addr.s_addr = _gIpAddr;\n\n\tint status = ::sendto( _sockfdMcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );\n\tif( status < 0){\n\t\tD_NWSTACKF(\"errno == %d in UdpPort::multicast\\n\", errno);\n\t}else{\n\t\tD_NWSTACKF(\"sendto %s:%u  [\",inet_ntoa(dest.sin_addr),htons(_gPortNo));\n\t\tfor(uint16_t i = 0; i < length ; i++){\n\t\t\tD_NWSTACKF(\" %02x\", *(buf + i));\n\t\t}\n\t\tD_NWSTACKF(\" ]\\n\");\n\t}\n\treturn errno;\n}\n\nbool UdpPort::checkRecvBuf(){\n\tstruct timeval timeout;\n\ttimeout.tv_sec = 0;\n\ttimeout.tv_usec = 500000;    // 500 msec\n\n\tuint8_t buf[2];\n\tfd_set recvfds;\n\tint maxSock = 0;\n\n\tFD_ZERO(&recvfds);\n\tFD_SET(_sockfdUcast, &recvfds);\n\tFD_SET(_sockfdMcast, &recvfds);\n\n\tif(_sockfdMcast > _sockfdUcast){\n\t\tmaxSock = _sockfdMcast;\n\t}else{\n\t\tmaxSock = _sockfdUcast;\n\t}\n\n\tselect(maxSock + 1, &recvfds, 0, 0, &timeout);\n\n\tif(FD_ISSET(_sockfdUcast, &recvfds)){\n\t\tif( ::recv(_sockfdUcast, buf, 1,  MSG_DONTWAIT | MSG_PEEK) > 0){\n\t\t\t_castStat = STAT_UNICAST;\n\t\t\treturn true;\n\t\t}\n\t}else if(FD_ISSET(_sockfdMcast, &recvfds)){\n\t\tif( ::recv(_sockfdMcast, buf, 1,  MSG_DONTWAIT | MSG_PEEK) > 0){\n\t\t\t_castStat = STAT_MULTICAST;\n\t\t\treturn true;\n\t\t}\n\t}\n\t_castStat = 0;\n\treturn false;\n}\n\nint UdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){\n\tint flags = flg ? MSG_DONTWAIT : 0;\n\treturn recvfrom (buf, len, flags, ipAddressPtr, portPtr );\n}\n\nint UdpPort::recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){\n\tstruct sockaddr_in sender;\n\tint status;\n\tsocklen_t addrlen = sizeof(sender);\n\tmemset(&sender, 0, addrlen);\n\n\tif(_castStat == STAT_UNICAST){\n\t\tstatus = ::recvfrom( _sockfdUcast, buf, len, flags, (struct sockaddr*)&sender, &addrlen );\n\t}else if(_castStat == STAT_MULTICAST){\n\t\tstatus = ::recvfrom( _sockfdMcast, buf, len, flags, (struct sockaddr*)&sender, &addrlen );\n\t}else{\n\t\treturn 0;\n\t}\n\n\tif (status < 0 && errno != EAGAIN)\t{\n\t\tD_NWSTACKF(\"errno == %d in UdpPort::recvfrom \\n\", errno);\n\t}else if(status > 0){\n\t\t*ipAddressPtr = sender.sin_addr.s_addr;\n\t\t*portPtr = sender.sin_port;\n\t\tD_NWSTACKF(\"recved from %s:%u [\",inet_ntoa(sender.sin_addr), htons(*portPtr));\n\t\tfor(uint16_t i = 0; i < status ; i++){\n\t\t\tD_NWSTACKF(\" %02x\", *(buf + i));\n\t\t}\n\t\tD_NWSTACKF(\" ]\\n\");\n\t}else{\n\t\treturn 0;\n\t}\n\treturn status;\n}\n\n\n#endif\n\n/*=========================================\n             Class NLLongAddress\n =========================================*/\nNWAddress64::NWAddress64(){\n    _msb = _lsb = 0;\n}\n\nNWAddress64::NWAddress64(uint32_t msb, uint32_t lsb){\n    _msb = msb;\n    _lsb = lsb;\n}\n\nuint32_t NWAddress64::getMsb(){\n    return _msb;\n}\n\nuint32_t NWAddress64::getLsb(){\n    return _lsb;\n}\n\nvoid NWAddress64::setMsb(uint32_t msb){\n    _msb = msb;\n}\n\nvoid NWAddress64::setLsb(uint32_t lsb){\n    _lsb = lsb;\n}\n\n/*=========================================\n             Class ZBResponse\n =========================================*/\nNWResponse::NWResponse(){\n    _addr16 = 0;\n}\n\nuint8_t  NWResponse::getFrameLength(){\n\treturn _len;\n}\n\nvoid NWResponse::setLength(uint16_t len){\n\t_len = len;\n}\n\nvoid NWResponse::setFrame(uint8_t* framePtr){\n\t_frameDataPtr = framePtr;\n}\n\nNWAddress64&  NWResponse::getAddress64(){\n    return _addr64;\n}\n\nuint16_t NWResponse::getAddress16(){\n  return _addr16;\n}\n\nvoid  NWResponse::setAddress64(uint32_t msb, uint32_t lsb){\n    _addr64.setMsb(msb);\n    _addr64.setLsb(lsb);\n}\n\nvoid  NWResponse::setAddress16(uint16_t addr16){\n\t_addr16 = addr16;\n}\n\nvoid NWResponse::setErrorCode(uint8_t errCode){\n\t_errorCode = errCode;\n}\n\nvoid NWResponse::setAvailable(bool complete){\n\t_complete = complete;\n}\n\nuint8_t NWResponse::getType(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr[3];\n\t}else{\n\t\treturn _frameDataPtr[1];\n\t}\n}\n\nuint8_t* NWResponse::getBody(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr + 4;\n\t}else{\n\t\treturn _frameDataPtr + 2;\n\t}\n}\n\nuint16_t NWResponse::getBodyLength(){\n\tif(_len > 255){\n\t\treturn getPayloadLength() - 4;\n\t}else{\n\t\treturn getPayloadLength() - 2;\n\t}\n}\n\nuint8_t NWResponse::getPayload(uint8_t index){\n\t\treturn _frameDataPtr[index];\n}\n\nuint8_t* NWResponse::getPayload(){\n\t\treturn _frameDataPtr;\n}\n\nuint8_t NWResponse::getPayloadLength(){\n\treturn _len;\n}\n\nvoid NWResponse::resetResponse(){\n\t_addr64.setLsb(0);\n\t_addr64.setMsb(0);\n\t_addr16 = 0;\n\t_len = 0;\n\t_errorCode = 0;\n\t_complete = false;;\n}\n\nbool NWResponse::isAvailable(){\n\treturn _complete;\n}\n\nuint8_t NWResponse::isError(){\n\treturn _errorCode;\n}\n\n#endif  /* NETWORK_UDP */\n"
  },
  {
    "path": "Client/src/lib/udpStack.h",
    "content": "/*\n * udpStack.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef UDPSTACK_H_\n#define UDPSTACK_H_\n\n#ifdef ARDUINO\n\t#include <MQTTSN_Application.h>\n\t#include <mqUtil.h>\n\t#include <Network.h>\n#else\n\t#include \"MQTTSN_Application.h\"\n\t#include \"mqUtil.h\"\n\t#include \"Network.h\"\n#endif\n\n#ifdef NETWORK_UDP\n\n#ifdef ARDUINO\n\t#include <SPI.h>\n\t#include <Ethernet.h>\n\t#include <EthernetUdp.h>\n    #if ARDUINO >= 100\n        #include \"Arduino.h\"\n        #include <inttypes.h>\n    #else\n        #if ARDUINO < 100\n            #include \"WProgram.h\"\n            #include <inttypes.h>\n        #endif\n    #endif\n#endif /* ARDUINO */\n\n\n#ifdef MBED\n    #include \"mbed.h\"\n#endif\n\n#ifdef LINUX\n    #include <sys/time.h>\n    #include <iostream>\n\t#include <sys/types.h>\n\t#include <sys/socket.h>\n\t#include <netinet/in.h>\n\t#include <netdb.h>\n\t#include <unistd.h>\n\t#include <string>\n\t#include <arpa/inet.h>\n#endif\n\n#define STAT_UNICAST   1\n#define STAT_MULTICAST 2\n\n#define SOCKET_MAXHOSTNAME  200\n#define SOCKET_MAXCONNECTIONS  5\n#define SOCKET_MAXRECV  500\n#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size\n\n#define PACKET_TIMEOUT_CHECK   200  // msec\n\nusing namespace std;\n\nnamespace tomyClient {\n\n/*============================================\n              NWAddress64\n =============================================*/\nclass NWAddress64 {\npublic:\n\tNWAddress64(uint32_t msb, uint32_t lsb);\n\tNWAddress64(void);\n\tuint32_t getMsb();\n\tuint32_t getLsb();\n\tvoid setMsb(uint32_t msb);\n\tvoid setLsb(uint32_t lsb);\nprivate:\n\tuint32_t _msb;\n\tuint32_t _lsb;\n};\n\n/*============================================\n               NWResponse\n =============================================*/\n\nclass NWResponse {\npublic:\n\tNWResponse();\n\tbool    isAvailable();\n\tuint8_t  isError();\n\tuint8_t  getType();\n\tuint8_t  getFrameLength();\n\tuint8_t  getPayload(uint8_t index);\n\tuint8_t* getPayload();\n\tuint8_t* getBody();\n\tuint16_t getBodyLength();\n\tuint8_t  getPayloadLength();\n\tuint16_t getAddress16();\n\tNWAddress64& getAddress64();\n\tvoid setLength(uint16_t len);\n//\tvoid setType(uint8_t type);\n\tvoid setFrame(uint8_t* framePtr);\n\tvoid setAddress64(uint32_t msb, uint32_t ipAddress);\n\tvoid setAddress16(uint16_t portNo);\n\tvoid setErrorCode(uint8_t);\n\tvoid setAvailable(bool);\n\tvoid resetResponse();\nprivate:\n\tNWAddress64 _addr64;\n\tuint16_t _addr16;\n\tuint16_t _len;\n\tuint8_t* _frameDataPtr;\n\tuint8_t  _type;\n\tuint8_t  _errorCode;\n\tbool    _complete;\n};\n\n\n/*========================================\n       Class UpdPort\n =======================================*/\nclass UdpPort{\npublic:\n\tUdpPort();\n\tvirtual ~UdpPort();\n\n\tbool open(NETWORK_CONFIG config);\n\n\tint unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port  );\n\tint multicast( const uint8_t* buf, uint32_t length );\n\tint recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, uint16_t* port );\n\tint recv(uint8_t* buf, uint16_t len, int flags);\n\tbool checkRecvBuf();\n\tbool isUnicast();\n\nprivate:\n\tvoid close();\n\tint recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, uint16_t* port );\n\n#ifdef LINUX\n\tint _sockfdUcast;\n\tint _sockfdMcast;\n\tuint16_t _gPortNo;\n\tuint16_t _uPortNo;\n\tuint32_t _gIpAddr;\n\tuint8_t  _castStat;\n#endif\n#ifdef ARDUINO\n\tEthernetUDP _udpUnicast;\n\tEthernetUDP _udpMulticast;\n\tIPAddress   _gIpAddr;\n\tIPAddress   _cIpAddr;\n\tuint16_t    _gPortNo;\n\tuint16_t    _uPortNo;\n\tuint8_t*    _macAddr;\n\tuint8_t     _castStat;\n#endif\n\n\tbool   _disconReq;\n\n};\n\n#define NO_ERROR\t0\n#define PACKET_EXCEEDS_LENGTH  1\n/*===========================================\n               Class  Network\n ============================================*/\nclass Network : public UdpPort {\npublic:\n    Network();\n    ~Network();\n\n    void send(uint8_t* xmitData, uint8_t dataLen, SendReqType type);\n    int  readPacket(uint8_t type = 0);\n    void setGwAddress();\n    void resetGwAddress(void);\n    void setRxHandler(void (*callbackPtr)(NWResponse* data, int* returnCode));\n    void setSleep();\n    int  initialize(UdpConfig  config);\nprivate:\n    int  readApiFrame();\n\n\tNWResponse _nlResp;\n    uint32_t _gwIpAddress;\n\tuint16_t _gwPortNo;\n    int     _returnCode;\n    bool _sleepflg;\n\tvoid (*_rxCallbackPtr)(NWResponse* data, int* returnCode);\n    uint8_t _rxFrameDataBuf[MQTTSN_MAX_FRAME_SIZE];\n\n};\n\n\n}    /* end of namespace */\n\n#endif\n#endif   /*  UDPSTACK_H__  */\n"
  },
  {
    "path": "Client/src/lib/zbeeStack.cpp",
    "content": "/*\n * zbeeStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified: 2014/09/05\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 1.0.0\n */\n\n#ifndef ARDUINO\n        #include \"MQTTSN_Application.h\"\n\t\t#include \"Network.h\"\n#else\n        #include <MQTTSN_Application.h>\n\t\t#include <Network.h>\n#endif\n\n#ifdef NETWORK_XBEE\n\n#ifdef ARDUINO\n  #include <zbeeStack.h>\n  #include <mqUtil.h>\n\n  #if defined(MQTTSN_DEBUG) || defined(NW_DEBUG) || defined(DEBUG)\n\t#include <SoftwareSerial.h>\n\textern SoftwareSerial debug;\n  #endif\n\n#endif  /* ARDUINO */\n\n#ifdef MBED\n        #include \"mbed.h\"\n        #include \"zbeeStack.h\"\n\t\t#include \"mqUtil.h\"\n#endif /* MBED */\n\n#ifdef LINUX\n        #include \"zbeeStack.h\"\n\t\t#include \"mqUtil.h\"\n        #include <stdio.h>\n        #include <sys/time.h>\n        #include <sys/types.h>\n        #include <sys/stat.h>\n        #include <unistd.h>\n        #include <stdlib.h>\n        #include <string.h>\n        #include <fcntl.h>\n        #include <errno.h>\n        #include <termios.h>\n\n#endif /* LINUX */\n\nusing namespace std;\nusing namespace tomyClient;\n\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=========================================\n       Class SerialPort\n =========================================*/\n#ifdef ARDUINO\n/**\n *  For Arduino\n */\nSerialPort::SerialPort(){\n\t_serialDev = 0;\n\tpinMode(XB_SLEEP_PIN, OUTPUT);\n\tdigitalWrite(XB_SLEEP_PIN, LOW);\n}\n\nint SerialPort::open(XBeeConfig config){ //Port num overload.\n\tif (config.portNo == 0){\n\tSerial.begin(config.baudrate);\n\t_serialDev = (Stream*) &Serial;\n\t}\n\t#if defined(UBRR1H)\n\telse if (config.portNo == 1){\n\tSerial1.begin(config.baudrate);\n\t_serialDev = (Stream*) &Serial1;\n\t}\n\t#endif\n\t#if defined(UBRR2H)\n\telse if (config.portNo == 2){\n\tSerial2.begin(config.baudrate);\n\t_serialDev = (Stream*) &Serial2;\n\t}\n\t#endif\n\t#if defined(UBRR3H)\n\telse if (config.portNo == 3){\n\tSerial3.begin(config.baudrate);\n\t_serialDev = (Stream*) &Serial3;\n\t}\n\t#endif\n\treturn 0;\n}\n\nbool SerialPort::checkRecvBuf(){\n    return _serialDev->available() > 0;\n}\n\nbool SerialPort::send(unsigned char b){\n\twhile(true){\n\t\tif(digitalRead(XB_CTS_PIN) == LOW){\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(_serialDev->write(b) != 1){\n\t  return false;\n\t}else{\n\t  D_NWSTACK(\" \");\n\t  D_NWSTACK(b,HEX);\n\t  return true;\n\t}\n}\n\n\nbool SerialPort::recv(unsigned char* buf){\n    if ( _serialDev->available() > 0 ){\n        buf[0] = _serialDev->read();\n\n        D_NWSTACK(\" \");\n        D_NWSTACK(*buf,HEX);\n        return true;\n\n    }else{\n        return false;\n    }\n}\n\nvoid SerialPort::flush(void){\n    _serialDev->flush();\n}\n\n#endif /* ARDUINO */\n\n#ifdef MBED\n/**\n *  For MBED\n */\nSerialPort::SerialPort(){\n  _serialDev = new Serial(ZB_MBED_SERIAL_TXPIN, ZB_MBED_SERIAL_RXPIN);\n  _head = _tail = 0;\n}\n\nvoid SerialPort::setBuff(void){\n    while(_serialDev->readable() > 0){\n        if( _tail != (_head + 1 == RING_BUFFER_SIZE ? 0 : _head + 1)){  // buffer full\n            _data[_head] = _serialDev->getc();\n            if( ++_head == RING_BUFFER_SIZE){\n                _head = 0;\n            }\n        }\n    }\n}\n\nint SerialPort::open(XBeeConfig config){\n  _serialDev->baud(config.baudrate);\n  _serialDev->format(8,Serial::None,1);\n  _serialDev->attach(this, &SerialPort::setBuff,Serial::RxIrq);\n  return 0;\n}\n\nbool SerialPort::checkRecvBuf(){\n    return _head != _tail;\n}\n\nbool SerialPort::send(unsigned char b){\n\t_serialDev->putc(b);\n\tD_NWSTACKF( \" %x\", b);\n\treturn true;\n}\n\n\nbool SerialPort::recv(unsigned char* buf){\n    if(_head != _tail){\n        *buf = _data[_tail];\n        D_NWSTACKF( \" %x\",*buf );\n        if(++_tail == RING_BUFFER_SIZE){\n            _tail = 0;\n        }\n        return true;\n    }\n    *buf = 0;\n    return false;\n}\n\n\n\nvoid SerialPort::flush(void){\n    _head = _tail = 0;\n}\n\n#endif /* MBED */\n\n#ifdef LINUX\n\nSerialPort::SerialPort(){\n    _tio.c_iflag = IGNBRK | IGNPAR;\n#ifdef XBEE_FLOWCTRL_CRTSCTS\n    _tio.c_cflag = CS8 | CLOCAL | CREAD | CRTSCTS;\n#else\n    _tio.c_cflag = CS8 | CLOCAL | CREAD;\n#endif\n    _tio.c_cc[VINTR] = 0;\n    _tio.c_cc[VTIME] = 0;\n    _tio.c_cc[VMIN] = 0;\n    _fd = 0;\n}\n\nSerialPort::~SerialPort(){\n  if (_fd){\n      close(_fd);\n  }\n}\n\nint SerialPort::open(XBeeConfig config){\n  return open(config.device, config.baudrate, false, 1);\n}\n\nint SerialPort::open(const char* devName, unsigned int boaurate,  bool parity, unsigned int stopbit){\n  _fd = ::open(devName, O_RDWR | O_NOCTTY);\n  if(_fd < 0){\n      return _fd;\n  }\n\n  if (parity){\n      _tio.c_cflag = _tio.c_cflag | PARENB;\n  }\n  if (stopbit == 2){\n      _tio.c_cflag = _tio.c_cflag | CSTOPB ;\n  }\n  switch(boaurate){\n    case B9600:\n    case B19200:\n    case B38400:\n    case B57600:\n    case B115200:\n      if( cfsetspeed(&_tio, boaurate)<0){\n        return errno;\n      }\n      break;\n    default:\n      return -1;\n  }\n    return tcsetattr(_fd, TCSANOW, &_tio);\n}\n\nbool SerialPort::checkRecvBuf(){\n    return true;\n}\n\nbool SerialPort::send(unsigned char b){\n  if (write(_fd, &b,1) != 1){\n      return false;\n  }else{\n      D_NWSTACKF( \" %x\", b);\n      return true;\n  }\n}\n\nbool SerialPort::recv(unsigned char* buf){\n  if(read(_fd, buf, 1) == 0){\n      return false;\n  }else{\n      D_NWSTACKF( \" %x\",*buf );\n      return true;\n  }\n}\n\nvoid SerialPort::flush(void){\n  tcsetattr(_fd, TCSAFLUSH, &_tio);\n}\n\n#endif\n\n/*=========================================\n             Class XBeeAddress64\n =========================================*/\nNWAddress64::NWAddress64(){\n    _msb = _lsb = 0;\n}\n\nNWAddress64::NWAddress64(uint32_t msb, uint32_t lsb){\n    _msb = msb;\n    _lsb = lsb;\n}\n\nuint32_t NWAddress64::getMsb(){\n    return _msb;\n}\n\nuint32_t NWAddress64::getLsb(){\n    return _lsb;\n}\n\nvoid NWAddress64::setMsb(uint32_t msb){\n    _msb = msb;\n}\n\nvoid NWAddress64::setLsb(uint32_t lsb){\n    _lsb = lsb;\n}\n\n/*=========================================\n             Class XBResponse\n =========================================*/\nXBResponse::XBResponse(){\n    reset();\n}\n\nuint8_t XBResponse::getApiId(){\n    return _apiId;\n}\n\nuint8_t XBResponse::getMsbLength(){\n    return _msbLength;\n}\n\nuint8_t XBResponse::getLsbLength(){\n    return _frameLength;\n}\n\nuint8_t XBResponse::getChecksum(){\n    return _checksum;\n}\n\nuint8_t XBResponse::getFrameLength(){\n    return _frameLength;\n}\n\nuint8_t* XBResponse::getFrameDataPtr(){\n    return _frameDataPtr;\n}\n\nvoid XBResponse::setMsbLength(uint8_t msbLength){\n    _msbLength = msbLength;\n}\n\nvoid XBResponse::setLsbLength(uint8_t lsbLength){\n\t_frameLength = lsbLength;\n}\n\nvoid XBResponse::setChecksum(uint8_t checksum){\n    _checksum = checksum;\n}\n\nvoid XBResponse::setFrameDataPtr(uint8_t* frameDataPtr){\n\t_frameDataPtr = frameDataPtr;\n}\nvoid XBResponse::setFrameLength(uint8_t frameLength){\n\t_frameLength = frameLength;\n}\n\nvoid XBResponse::setApiId(uint8_t api){\n    _apiId = api;\n}\n\nbool XBResponse::isAvailable(){\n    return _complete;\n}\n\nvoid XBResponse::setAvailable(bool complete){\n    _complete = complete;\n}\n\nbool XBResponse::isError(){\n    return _errorCode > 0;\n}\n\nuint8_t XBResponse::getErrorCode(){\n    return _errorCode;\n}\n\nvoid XBResponse::setErrorCode(uint8_t errorCode){\n    _errorCode = errorCode;\n}\n\n\nvoid XBResponse::reset(){\n      _apiId = 0;\n      _msbLength = 0;\n      _checksum = 0;\n      _frameLength = 0;\n      _errorCode = NO_ERROR;\n      _complete = false;\n}\n\n/*=========================================\n             Class XBModemStatus\n =========================================*/\nXBModemStatus::XBModemStatus(){\n}\n\nuint8_t XBModemStatus::getStatus(){\n\treturn *getFrameDataPtr();\n}\n\n/*=========================================\n             Class NWResponse\n =========================================*/\nNWResponse::NWResponse(){\n    reset();\n    _remoteAddress16 = 0;\n    _options = 0;\n}\n\nNWAddress64&  NWResponse::getRemoteAddress64(){\n    return _remoteAddress64;\n}\n\nuint16_t NWResponse::getRemoteAddress16(){\n  return _remoteAddress16;\n}\n\nvoid  NWResponse::setRemoteAddress64(NWAddress64& addr64){\n    _remoteAddress64 = addr64;\n}\n\nvoid  NWResponse::setRemoteAddress64(){\n\t_remoteAddress64.setMsb(getUint32(getFrameDataPtr()));\n\t_remoteAddress64.setLsb(getUint32(getFrameDataPtr() + 4));\n}\n\nvoid  NWResponse::setRemoteAddress16(uint16_t addr16){\n    _remoteAddress16 = addr16;\n}\n\nvoid  NWResponse::setRemoteAddress16(){\n    _remoteAddress16 = (uint16_t(getFrameDataPtr()[8]) << 8) + (getFrameDataPtr()[9]);\n}\n\nuint8_t NWResponse::getType(){\n\treturn _frameDataPtr[ZB_RSP_DATA_OFFSET + 1];\n}\n\nuint8_t NWResponse::getPayload(uint8_t index){\n    return _frameDataPtr[index + ZB_RSP_DATA_OFFSET];\n}\n\nuint8_t* NWResponse::getBody(){\n\tif(getFrameLength() > 255){\n\t\treturn _frameDataPtr + ZB_RSP_DATA_OFFSET + 4;\n\t}else{\n\t\treturn _frameDataPtr + ZB_RSP_DATA_OFFSET + 2;\n\t}\n}\n\nuint16_t NWResponse::getBodyLength(){\n\tif(getFrameLength() > 255){\n\t\treturn getPayloadLength() - 4;\n\t}else{\n\t\treturn getPayloadLength() - 2;\n\t}\n}\n\nuint8_t* NWResponse::getPayload(){\n    return _frameDataPtr + ZB_RSP_DATA_OFFSET;\n}\n\nuint8_t NWResponse::getPayloadLength(){\n    return getFrameLength() - ZB_RSP_DATA_OFFSET;\n}\n\nuint8_t NWResponse::getOption(){\n    return _options;\n}\n\nvoid NWResponse::setOption(uint8_t options){\n    _options = options;\n}\n\nvoid NWResponse::setOption(){\n    _options = *(_frameDataPtr + ZB_RSP_DATA_OFFSET - 1);\n}\n\nbool NWResponse::isBrodcast(){\n    return ( _options && 0x02);\n}\n\n/*=========================================\n           Class NWRequest\n =========================================*/\n\nNWRequest::NWRequest(){\n\n}\n\nuint8_t NWRequest::getFrameDataLength(){\n    return  _payloadLength + ZB_REQ_DATA_OFFSET;\n}\n\nuint8_t* NWRequest::getPayload(){\n    return _payloadPtr;\n}\n\nuint8_t NWRequest::getPayloadLength(){\n    return _payloadLength;\n}\n\nuint8_t NWRequest::getBroadcastRadius(){\n    return _broadcastRadius;\n}\n\nuint8_t NWRequest::getOption(){\n    return _option;\n}\n\nvoid NWRequest::setBroadcastRadius(uint8_t broadcastRadius){\n    _broadcastRadius = broadcastRadius;\n}\n\nvoid NWRequest::setOption(uint8_t option){\n    _option = option;\n}\n\nvoid NWRequest::setPayload(uint8_t *payload){\n    _payloadPtr = payload;\n}\n\nvoid NWRequest::setPayloadLength(uint8_t payLoadLength){\n    _payloadLength = payLoadLength;\n}\n\n\n/*===========================================\n              Class  Network\n ============================================*/\n\nNetwork::Network(){\n    _serialPort = new SerialPort();\n    _rxCallbackPtr = 0;\n    _returnCode = 0;\n    _response.setFrameDataPtr(_responsePayload);\n    _tm.stop();\n    _pos = 0;\n    _escape = false;\n    _checksumTotal = 0;\n    _gwAddress64.setMsb(0L);\n    _gwAddress64.setLsb(0L);\n    _gwAddress16 = 0;\n    _sleepflg = false;\n}\n\nNetwork::~Network(){\n\tdelete _serialPort;\n}\n\nint Network::initialize(XBeeConfig config){\n\treturn _serialPort->open(config);\n}\n\nvoid Network::setSleep(){\n\t_sleepflg = true;\n}\n\nvoid Network::setRxHandler(void (*callbackPtr)(NWResponse* data, int* returnCode)){\n    _rxCallbackPtr = callbackPtr;\n}\n\nNWAddress64& Network::getRxRemoteAddress64(){\n    return _rxResp.getRemoteAddress64();\n}\n\nuint16_t Network::getRxRemoteAddress16(){\n    return _rxResp.getRemoteAddress16();\n}\n\nvoid Network::setResponse(NWResponse& response){\n\tresponse.setApiId(_response.getApiId());\n\tresponse.setAvailable(_response.isAvailable());\n\tresponse.setChecksum(_response.getChecksum());\n\tresponse.setErrorCode(_response.getErrorCode());\n\tresponse.setFrameLength(_response.getFrameLength());\n\tresponse.setMsbLength(_response.getMsbLength());\n\tresponse.setLsbLength(_response.getLsbLength());\n\tresponse.setFrameDataPtr(_responsePayload);\n    response.setOption();\n    response.setRemoteAddress16();\n    response.setRemoteAddress64();\n}\n\n\nvoid Network::setGwAddress(){\n    _gwAddress64.setMsb(getRxRemoteAddress64().getMsb());\n    _gwAddress64.setLsb(getRxRemoteAddress64().getLsb());\n    _gwAddress16 = getRxRemoteAddress16();\n}\n\nvoid Network::resetGwAddress(void){\n    _gwAddress64.setMsb(0);\n    _gwAddress64.setLsb(0);\n    _gwAddress16 = 0;\n}\n\nvoid Network::setSerialPort(SerialPort *serialPort){\n  _serialPort = serialPort;\n}\n\n\nvoid Network::send(uint8_t* payload, uint8_t payloadLen, SendReqType type){\n    _txRequest.setOption(0);\n    _txRequest.setPayload(payload);\n    _txRequest.setPayloadLength(payloadLen);\n    sendZBRequest(_txRequest, type);\n}\n\nint Network::readPacket(uint8_t type){\n    _returnCode = 0;\n\n    if(_serialPort->checkRecvBuf()){\n\t\tif(readApiFrame(PACKET_TIMEOUT_CHECK)){\n\t\t\tif(_response.getApiId() == ZB_API_RESPONSE){\n\t\t\t\tif (_rxCallbackPtr != 0){\n\t\t\t\t\t_rxCallbackPtr(&_rxResp, &_returnCode);\n\t\t\t\t}\n\t\t\t}else if(_response.getApiId() == ZB_API_MODEMSTATUS){\n\t\t\t\tif(type){\n\t\t\t\t\t_returnCode = PACKET_MODEM_STATUS;\n\t\t\t\t}\n\t\t\t}\n        }\n    }\n    return _returnCode;\n}\n\nbool Network::readApiFrame(uint16_t timeoutMillsec){\n    _pos = 0;\n    _tm.start((uint32_t)timeoutMillsec);\n\n\n    while(!_tm.isTimeUp()){\n\n        readApiFrame();\n\n        if(_response.isAvailable()){\n            D_NWSTACKW(\"\\r\\n<=== CheckSum OK\\r\\n\\n\");\n            if(_response.getApiId() == ZB_API_RESPONSE){\n            \t//_rxResp.setFrameDataPtr(_rxFrameDataBuf);\n            \tsetResponse(_rxResp);\n\t\t\t\tif(_gwAddress16 &&\n\t\t\t\t\t(_rxResp.getOption() & 0x02 ) != 0x02 &&\n\t\t\t\t\t(_gwAddress64.getMsb() != _rxResp.getRemoteAddress64().getMsb()) &&\n\t\t\t\t\t(_gwAddress64.getLsb() != _rxResp.getRemoteAddress64().getLsb())){\n\t\t\t\t\tD_NWSTACKW(\"  Sender is not Gateway!\\r\\n\" );\n\t\t\t\t\treturn false;\n\t\t\t\t}\n            \treturn true;\n            }else if(_response.getApiId() == ZB_API_MODEMSTATUS){\n            \treturn true;\n            }\n        }else if(_response.isError()){\n            D_NWSTACKW(\"\\r\\n<=== Packet Error Code = \");\n            D_NWSTACKLN(_response.getErrorCode(), DEC);\n            D_NWSTACKF(\"%d\\r\\n\",_response.getErrorCode() );\n            return false;\n        }\n    }\n    return false;   //Timeout\n}\n\nvoid Network::readApiFrame(){\n\n    if (_response.isAvailable() || _response.isError()){\n      resetResponse();\n    }\n\n    while(read(&_byteData )){\n\n        if( _byteData == START_BYTE){\n            _pos = 1;\n            continue;\n        }\n        // Check ESC\n        if(_pos > 0 && _byteData == ESCAPE){\n          if(read(&_byteData )){\n              _byteData = 0x20 ^ _byteData;  // decode\n          }else{\n              _escape = true;\n              continue;\n          }\n        }\n\n        if(_escape){\n            _byteData = 0x20 ^ _byteData;\n            _escape = false;\n        }\n\n        if(_pos >= API_ID_POS){\n            _checksumTotal+= _byteData;\n        }\n\n        switch(_pos){\n        case 0:\n            break;\n\n        case 1:\n            _response.setMsbLength(_byteData);\n            break;\n\n        case 2:\n            _response.setLsbLength(_byteData);\n            break;\n        case 3:\n        \tD_NWSTACKW(\"\\r\\n===> Recv:    \");\n            _response.setApiId(_byteData);   // API\n            break;\n        default:\n            if(_pos > MQTTSN_MAX_FRAME_SIZE){\n              _response.setErrorCode(PACKET_EXCEEDS_BYTE_ARRAY_LENGTH);\n              _pos = 0;\n              return;\n            }else if(_pos == (_response.getFrameLength() + 3)){\n              if((_checksumTotal & 0xff) == 0xff){\n                  _response.setChecksum(_byteData);\n                  _response.setAvailable(true);\n                  _response.setErrorCode(NO_ERROR);\n              }else{\n                  _response.setErrorCode(CHECKSUM_FAILURE);\n              }\n              _response.setFrameLength(_pos - 4);    // 4 = 2(packet len) + 1(Api) + 1(checksum)\n              _pos = 0;\n              _checksumTotal = 0;\n              return;\n            }else{\n              _response.getFrameDataPtr()[_pos - 4] = _byteData;\n            }\n            break;\n        }\n        _pos++;\n\n    }\n}\n\nvoid Network::sendZBRequest(NWRequest& request, SendReqType type){\n    D_NWSTACKW(\"\\r\\n===> Send:    \");\n\n    sendByte(START_BYTE, false);           // Start byte\n\n    uint8_t msbLen = ((request.getFrameDataLength() + 1) >> 8) & 0xff; // 1  for Checksum\n    uint8_t lsbLen = (request.getFrameDataLength() + 1) & 0xff;\n    sendByte(msbLen, true);               // Message Length\n    sendByte(lsbLen, true);               // Message Length\n\n    sendByte(ZB_API_REQUEST, true);       // API\n    uint8_t checksum = 0;\n    checksum+= ZB_API_REQUEST;\n\n    sendByte(0x00, true);                 // Frame ID\n\n    for(int i = 0; i < 10; i++){\n        sendByte(getAddrByte(i,type), true);   // Gateway Address 64 & 16\n        checksum += getAddrByte(i,type);       //   or Broadcast Address\n    }\n\n    sendByte(request.getBroadcastRadius(), true);\n    checksum += request.getBroadcastRadius();\n\n    sendByte(request.getOption(), true);\n    checksum += request.getOption();\n\n    D_NWSTACKW(\"\\r\\n     Payload: \");\n\n    for( int i = 0; i < request.getPayloadLength(); i++ ){\n        sendByte(request.getPayload()[i], true);     // Payload\n        checksum+= request.getPayload()[i];\n    }\n    checksum = 0xff - checksum;\n    sendByte(checksum, true);\n\n    flush();  // clear receive buffer\n\n    D_NWSTACKW(\"\\r\\n<=== Send completed\\r\\n\\n\" );\n}\n\nvoid Network::sendByte(uint8_t b, bool escape){\n  if(escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)){\n      write(ESCAPE);\n      write(b ^ 0x20);\n  }else{\n      write(b);\n  }\n}\n\nvoid Network::resetResponse(){\n  _pos = 0;\n  _escape = 0;\n  _response.reset();\n  _addr16 = 0;\n  _addr32 = 0;\n}\n\nvoid Network::flush(){\n  _serialPort->flush();\n}\n\nbool Network::write(uint8_t val){\n\treturn (_serialPort->send(val) ? true : false );\n}\n\nbool Network::read(uint8_t *buff){\n\treturn  _serialPort->recv(buff);\n}\n\nuint8_t Network::getAddrByte(uint8_t pos, SendReqType type){\n\tuint8_t buf[4];\n\n    if(type == UcastReq){\n        if (pos == 0){\n\t\t\tsetUint32(buf, _gwAddress64.getMsb());\n\t\t\treturn buf[0];\n\t\t}else if (pos == 1){\n\t\t\tsetUint32(buf, _gwAddress64.getMsb());\n\t\t\treturn buf[1];\n\t\t}else if (pos == 2){\n\t\t\tsetUint32(buf, _gwAddress64.getMsb());\n\t\t\treturn buf[2];\n\t\t}else if (pos == 3){\n\t\t\tsetUint32(buf, _gwAddress64.getMsb());\n\t\t\treturn buf[3];\n\t\t}else if (pos == 4){\n\t\t\tsetUint32(buf, _gwAddress64.getLsb());\n\t\t\treturn buf[0];\n\t\t}else if (pos == 5){\n\t\t\tsetUint32(buf, _gwAddress64.getLsb());\n\t\t\treturn buf[1];\n\t\t}else if (pos == 6){\n\t\t\tsetUint32(buf, _gwAddress64.getLsb());\n\t\t\treturn buf[2];\n\t\t}else if (pos == 7){\n\t\t\tsetUint32(buf, _gwAddress64.getLsb());\n\t\t\treturn buf[3];\n\t\t}else if (pos == 8){\n\t\t\tsetUint16(buf,_gwAddress16);\n\t\t\treturn buf[0];\n\t\t}else if (pos == 9){\n\t\t\tsetUint16(buf,_gwAddress16);\n\t\t\treturn buf[1];\n\t\t}\n    }else if(type == BcastReq){\n        if(pos < 6){\n            return 0x00;\n        }else if((pos > 5) && (pos < 9)){\n            return 0xff;\n        }else if(pos == 9){\n            return 0xfe;\n        }\n    }\n    return 0;\n}\n\n#endif  /* NETWORK_XBEE */\n\n"
  },
  {
    "path": "Client/src/lib/zbeeStack.h",
    "content": "/*\r\n * zbeeStack.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified: 2014/09/05\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 1.0.0\r\n */\r\n\r\n#ifndef ZBEESTACK_H_\r\n#define ZBEESTACK_H_\r\n\r\n#ifdef ARDUINO\r\n\t#include <MQTTSN_Application.h>\r\n#else\r\n\t#include \"MQTTSN_Application.h\"\r\n\t#include \"mqUtil.h\"\r\n\t#include \"Network.h\"\r\n#endif\r\n\r\n#ifdef NETWORK_XBEE\r\n\r\n#if defined(ARDUINO)\r\n\t#include <MQTTSN_Application.h>\r\n    #include <Network.h>\r\n    #if ARDUINO >= 100\r\n        #include \"Arduino.h\"\r\n        #include <inttypes.h>\r\n\t\t#include <mqUtil.h>\r\n    #else\r\n        #if ARDUINO < 100\r\n            #include \"WProgram.h\"\r\n            #include <inttypes.h>\r\n\t\t\t#include <mqUtil.h>\r\n        #endif\r\n    #endif\r\n\r\n\t#define XB_CTS_PIN   3   // XBee CTS\r\n\t#define XB_SLEEP_PIN 4   // XBee Pinhybernate\r\n#endif\r\n\r\n\r\n#ifdef MBED\r\n    #include \"mbed.h\"\r\n    #define ZB_MBED_SERIAL_TXPIN  p13\r\n    #define ZB_MBED_SERIAL_RXPIN  p14\r\n#endif\r\n\r\n#ifdef LINUX\r\n    #include <sys/time.h>\r\n    #include <iostream>\r\n#endif\r\n\r\n\r\nnamespace tomyClient {\r\n\r\n#define START_BYTE 0x7e\r\n#define ESCAPE     0x7d\r\n#define XON        0x11\r\n#define XOFF       0x13\r\n\r\n\r\n#define ZB_API_REQUEST               0x10\r\n#define ZB_API_RESPONSE              0x90\r\n#define ZB_API_MODEMSTATUS           0x8A\r\n\r\n#define ZB_PACKET_ACKNOWLEGED        0x01\r\n#define ZB_BROADCAST_PACKET          0x02\r\n#define ZB_BROADCAST_RADIUS_MAX_HOPS 0\r\n#define ZB_RSP_DATA_OFFSET           11\r\n#define ZB_REQ_DATA_OFFSET           13\r\n\r\n#define API_ID_POS                    3\r\n#define PACKET_OVERHEAD_LENGTH        6\r\n\r\n#define ZB_MAX_NODEID  20\r\n\r\n\r\n/*====  STATUS ====== */\r\n#define SUCCESS           0x0\r\n\r\n#define NO_ERROR                          0\r\n#define CHECKSUM_FAILURE                  1\r\n#define PACKET_EXCEEDS_BYTE_ARRAY_LENGTH  2\r\n#define UNEXPECTED_START_BYTE             3\r\n\r\n\r\n/*\r\n *   Packet Read Constants\r\n */\r\n#if defined(ARDUINO) || defined(MBED)\r\n  #define PACKET_TIMEOUT_CHECK   300\r\n#else\r\n  #define PACKET_TIMEOUT_CHECK   200\r\n#endif\r\n\r\n#define RING_BUFFER_SIZE  256\r\n\r\n\r\n/*============================================\r\n              NWAddress64\r\n =============================================*/\r\nclass NWAddress64 {\r\npublic:\r\n  NWAddress64(uint32_t msb, uint32_t lsb);\r\n  NWAddress64(void);\r\n  uint32_t getMsb();\r\n  uint32_t getLsb();\r\n  void    setMsb(uint32_t msb);\r\n  void    setLsb(uint32_t lsb);\r\nprivate:\r\n  uint32_t _msb;\r\n  uint32_t _lsb;\r\n};\r\n\r\n /*============================================\r\n                XBResponse\r\n =============================================*/\r\n\r\nclass XBResponse {\r\npublic:\r\n    XBResponse();\r\n    uint8_t  getApiId();\r\n    uint8_t  getMsbLength();\r\n    uint8_t  getLsbLength();\r\n    uint8_t  getChecksum();\r\n    uint8_t  getFrameLength();\r\n    uint8_t* getFrameDataPtr();\r\n\r\n    void setApiId(uint8_t api);\r\n    void setMsbLength(uint8_t msbLength);\r\n    void setLsbLength(uint8_t lsbLength);\r\n    void setChecksum(uint8_t checksum);\r\n    void setFrameDataPtr(uint8_t* frameDataPtr);\r\n    void setFrameLength(uint8_t frameLength);\r\n\r\n    bool isAvailable();\r\n    void setAvailable(bool complete);\r\n    bool isError();\r\n    void setErrorCode(uint8_t errorCode);\r\n    void reset();\r\n    uint8_t getErrorCode();\r\n\r\nprotected:\r\n    uint8_t* _frameDataPtr;\r\n\r\nprivate:\r\n    uint8_t _msbLength;\r\n    uint8_t _frameLength;\r\n    uint8_t _apiId;\r\n    uint8_t _checksum;\r\n    uint8_t _errorCode;\r\n    bool   _complete;\r\n};\r\n\r\n/*============================================\r\n               XBModemStatus\r\n=============================================*/\r\nclass XBModemStatus : public XBResponse{\r\npublic:\r\n\tXBModemStatus();\r\n\tuint8_t getStatus();\r\n};\r\n\t\t\r\n/*============================================\r\n               NLResponse\r\n=============================================*/\r\n\r\nclass NWResponse : public XBResponse{\r\npublic:\r\n\tNWResponse();\r\n\tuint8_t  getPayload(uint8_t index);\r\n\tuint8_t  getPayloadLength();\r\n\tuint8_t  getType();\r\n\tuint8_t  getOption();\r\n\tuint8_t* getPayload();\r\n\tuint8_t* getBody();\r\n\tuint16_t getBodyLength();\r\n\tuint16_t getRemoteAddress16();\r\n\tNWAddress64& getRemoteAddress64();\r\n\r\n\tvoid setRemoteAddress64(NWAddress64& addr64);\r\n\tvoid setRemoteAddress64();\r\n\tvoid setRemoteAddress16(uint16_t addr16);\r\n\tvoid setRemoteAddress16();\r\n\tvoid setOption(uint8_t options);\r\n\tvoid setOption();\r\n\tbool isBrodcast();\r\n\r\nprivate:\r\n\tNWAddress64 _remoteAddress64;\r\n\tuint16_t    _remoteAddress16;\r\n\tuint8_t     _options;\r\n};\r\n\r\n/*============================================*\r\n                NLRequest\r\n =============================================*/\r\n\r\nclass NWRequest {\r\npublic:\r\n    NWRequest();\r\n    ~NWRequest(){};\r\n//    uint8_t getFrameData(uint8_t pos);\r\n    uint8_t  getFrameDataLength();\r\n    uint8_t  getBroadcastRadius();\r\n    uint8_t  getOption();\r\n    uint8_t  getPayloadLength();\r\n    uint8_t* getPayload();\r\n\r\n    void setBroadcastRadius(uint8_t broadcastRadius);\r\n    void setOption(uint8_t option);\r\n    void setPayload(uint8_t *payload);\r\n    void setPayloadLength(uint8_t payLoadLength);\r\n\r\nprivate:\r\n    uint8_t _broadcastRadius;\r\n    uint8_t _option;\r\n    uint8_t _payloadLength;\r\n    uint8_t* _payloadPtr;\r\n};\r\n\r\n\r\n/*===========================================\r\n                Serial Port\r\n ============================================*/\r\n\r\n#ifdef ARDUINO\r\n#include <Stream.h>\r\nclass SerialPort{\r\npublic:\r\n    SerialPort( );\r\n    int  open(NETWORK_CONFIG config);\r\n    bool send(unsigned char b);\r\n    bool recv(unsigned char* b);\r\n    void flush();\r\n    bool checkRecvBuf();\r\nprivate:\r\n    Stream* _serialDev;\r\n};\r\n#endif /* ARDUINO */\r\n\r\n#ifdef MBED\r\n/*-------------------------\r\n    For MBED\r\n --------------------------*/\r\nclass SerialPort{\r\npublic:\r\n    SerialPort( );\r\n    int  open(XBeeConfig config);\r\n    bool send(unsigned char b);\r\n    bool recv(unsigned char* b);\r\n    void flush();\r\n    bool checkRecvBuf();\r\n    void setBuff(void);\r\n    void putc(uint8_t c);\r\nprivate:\r\n\tSerial* _serialDev;\r\n\tuint8_t _data[RING_BUFFER_SIZE];\r\n\tint _head;\r\n\tint _tail;\r\n};\r\n#endif /* MBED */\r\n\r\n#ifdef LINUX\r\n/*-------------------------\r\n    For Linux\r\n --------------------------*/\r\n#include <termios.h>\r\nclass SerialPort{\r\npublic:\r\n    SerialPort();\r\n    ~SerialPort();\r\n    int  open(XBeeConfig  config);\r\n    bool send(unsigned char b);\r\n    bool recv(unsigned char* b);\r\n    bool checkRecvBuf();\r\n    void flush();\r\nprivate:\r\n    int open(const char* devName, unsigned int boaurate,  bool parity, unsigned int stopbit);\r\n    int _fd;  // file descriptor\r\n    struct termios _tio;\r\n};\r\n#endif /* LINUX */\r\n\r\n\r\n/*===========================================\r\n               Class  Network\r\n ============================================*/\r\nclass Network {\r\npublic:\r\n    Network();\r\n    ~Network();\r\n\r\n    void send(uint8_t* xmitData, uint8_t dataLen, SendReqType type);\r\n    int  readPacket(uint8_t type = 0);\r\n    void setGwAddress();\r\n    void resetGwAddress(void);\r\n    void setRxHandler(void (*callbackPtr)(NWResponse* data, int* returnCode));\r\n    int  initialize(XBeeConfig  config);\r\n\r\nprivate:\r\n    void setSleep();\r\n    NWAddress64& getRxRemoteAddress64();\r\n\tuint16_t       getRxRemoteAddress16();\r\n\tconst char*   getNodeId();\r\n\tvoid          setResponse(NWResponse& response);\r\n\r\n\tvoid setSerialPort(SerialPort *serialPort);\r\n\r\n    void sendZBRequest(NWRequest& request, SendReqType type);\r\n    int  packetHandle();\r\n    void execCallback();\r\n    void readApiFrame(void);\r\n    bool readApiFrame(uint16_t timeoutMillsec);\r\n    void flush();\r\n    void resetResponse();\r\n    bool read(uint8_t* buff);\r\n    bool write(uint8_t val);\r\n    void sendByte(uint8_t, bool escape);\r\n    uint8_t getAddrByte(uint8_t pos, SendReqType type);\r\n\r\n    NWRequest   _txRequest;\r\n    NWResponse  _rxResp;\r\n    XBResponse  _response;    //  Received data\r\n    uint8_t     _responsePayload[MQTTSN_MAX_FRAME_SIZE];\r\n    XTimer      _tm;\r\n    SerialPort* _serialPort;\r\n    NWAddress64 _gwAddress64;\r\n    uint16_t    _gwAddress16;\r\n    uint8_t     _pos;\r\n    uint8_t     _byteData;\r\n    uint8_t     _checksumTotal;\r\n    uint16_t    _addr16;\r\n    uint32_t    _addr32;\r\n    int  _returnCode;\r\n    bool _escape;\r\n    bool _sleepflg;\r\n\r\n    void (*_rxCallbackPtr)(NWResponse* data, int* returnCode);\r\n};\r\n\r\n}\r\n#endif\r\n#endif  /* ZBEESTACK_H_ */\r\n"
  },
  {
    "path": "Client/src/mbedClientSample.cpp",
    "content": "/*\n * mbedClientSample.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"lib/MQTTSN_Application.h\"\n\n#ifdef MBED\n#include \"lib/mqttsnClientAppFw4mbed.h\"\n\nusing namespace std;\nusing namespace tomyClient;\n\n/*============================================\n *\n *   MQTT-SN Client Application for mbed\n *\n *===========================================*/\nXBEE_APP_CONFIG = {\n\t{\n\t\t9600,           //Baudrate (bps)\n\t\t0,              //Serial PortNo\n\t\t0               //Device (for linux App)\n\t},\n\t{\n\t\t\"Node01\",       //NodeId\n\t\t300,            //KeepAlive (sec)\n\t\tfalse,          //Clean session\n\t\tfalse,          //EndDevice\n\t\t\"willTopic\",    //WillTopic   or 0   DO NOT USE 0 STRING!\n\t\t\"willMessage\"   //WillMessage or 0   DO NOT USE 0 STRING!\n\t}\n };\n/*------------------------------------------------------\n *             Create Topic\n *------------------------------------------------------*/\nMQString* topic1 = new MQString(\"dev/indicator\");\n\n\n/*------------------------------------------------------\n *             Tasks invoked by Timer\n *------------------------------------------------------*/\nbool led_flg = false;\n\nint task1(){\n\tif(led_flg){\n\t\tPUBLISH(topic1, \"off\", 3, QOS1);\n\t\tled_flg = false;\n\t}else{\n\t\tPUBLISH(topic1, \"on\", 2, QOS1);\n\t\tled_flg = true;\n\t}\n\treturn 0;\n}\n\n/*---------  Link Tasks to the Application ----------*/\nTASK_LIST = {\n\t{task1, 60},\nEND_OF_TASK_LIST};\n\n/*------------------------------------------------------\n *       Tasks invoked by PUBLISH command Packet\n *------------------------------------------------------*/\nDigitalOut indicator(LED1);\n\nint  blinkIndicator(MqttsnPublish* msg){\n\n  if( !strncmp(\"on\", (const char*)msg->getData(),2)){\n    indicator = 1;\n  }else if( !strncmp(\"off\", (const char*)msg->getData(),3)){\n    indicator = 0;\n  }\n  return 0;\n}\n/*-------------- Link Tasks to Topic -------------------*/\nSUBSCRIBE_LIST = {\n\t{topic1, blinkIndicator, QOS1},\nEND_OF_SUBSCRIBE_LIST};\n\n/*==================================================\n *      Application setup\n *=================================================*/\n void setup(){\n    // nop\n }\n\n#endif\n\n\n"
  },
  {
    "path": "Gateway/Makefile",
    "content": "PROGNAME := TomyGateway\nSRCDIR := src\nSUBDIR := src/lib\n\nSRCS := $(SRCDIR)/TomyGateway.cpp \\\n$(SRCDIR)/BrokerRecvTask.cpp \\\n$(SRCDIR)/BrokerSendTask.cpp \\\n$(SRCDIR)/ClientRecvTask.cpp \\\n$(SRCDIR)/ClientSendTask.cpp \\\n$(SRCDIR)/GatewayControlTask.cpp \\\n$(SRCDIR)/GatewayResourcesProvider.cpp \\\n$(SUBDIR)/ProcessFramework.cpp \\\n$(SUBDIR)/Messages.cpp \\\n$(SUBDIR)/TCPStack.cpp \\\n$(SUBDIR)/TLSStack.cpp \\\n$(SUBDIR)/Topics.cpp \\\n$(SUBDIR)/UDPStack.cpp \\\n$(SUBDIR)/XXXXXStack.cpp \\\n$(SUBDIR)/ZBStack.cpp \n\nCXX := g++\nCPPFLAGS += \nDEFS :=\nLDFLAGS += \nLIBS +=\n#LDADD := -lpthread -lrt -lssl -lcrypto\nLDADD := -lpthread -lrt -lwiringPi -lssl -lcrypto\n\nCXXFLAGS := -Wall -O3\n\nOUTDIR := Build\n\nPROG := $(OUTDIR)/$(PROGNAME)\nOBJS := $(SRCS:%.cpp=$(OUTDIR)/%.o)\nDEPS := $(SRCS:%.cpp=$(OUTDIR)/%.d)\n\n.PHONY: install clean distclean\n\nall: $(PROG)\n\n-include $(DEPS)\n\n$(PROG): $(OBJS)\n\t$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)\n\n$(OUTDIR)/%.o:%.cpp\n\t@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<\n\nclean:\n\trm -rf $(OUTDIR)\n\ninstall:\n\tcp -p $(PROG) ../../\n"
  },
  {
    "path": "Gateway/README.md",
    "content": "MQTT-SN Gateway\n======\nThis program is a Gateway over XBee and UDP.\nSelect from the network layer in lib/Defines.h, shown in below. \n\nIn case of UDP, Multicast is required for SEARCHGW and GWINFO messages.    \nClient multicasts the SEARCHGW to find the gateway.    \nGateway multicasts the GWINFO from unicast port.    \nClient can get the gateway IP and port using std::recvfrom() functions.    \n         \nIf your client does not support SEARCHGW and GWINFO, you can skip the search gateway procedure.    \nYou can CONNECT to a portNo specified with -u parameter and Gateway's IP address directly.    \n\nIf you want to change to your own networkStack, i.e bluetooth, just modify the XXXXXXStack.cpp, .h      \nand lib/Defines.h, ClientRecv.cpp, ClientSend.cpp files.  Templates are built in already.\n    \nSupported functions\n-------------------\n\n*  QOS Level 0, 1 and 2    \n*  CONNECT, WILLTOPICREQ, WILLTOPIC, WILLMSGREQ, WILLMSG    \n*  REGISTER, SUBSCRIBE, PUBLISH, UNSUBSCRIBE, DISCONNECT     \n*  CONNACK, REGACK, SUBACK, PUBACK, PUBREL, PUBCOMP, UNSUBACK    \n*  ADVERTIZE, GWINFO    \n\n\nUsage\n------\n####1) Minimum requirements\n*  Linux  ( Windows can not execute this program.)    \n*  pthread, rt liblaries to be linked.    \n*  wiringPi for Raspberry Pi (http://wiringpi.com/download-and-install/)\n*  In case of XBee, Three XBee S2 (one coordinator, one gateway and one client.)  \n*  or two XBee S1 (Digimesh, one for gateway and another for client)    \n\n####2) How to Build\n    for XBee DigiMesh\n    $ make    \n           \n    for UDP\n    $ make DEFS=-DNETWORK_UDP     \n    \n  Makefile is in Gateway directory.  \n  TomyGateway (Executable) is created in Build directory.\n\n    $ make install\n  TomyGateway is copied to the directory repo located.    \n\n    $ make clean\n  remove the Build directory.    \n    \n####3)  Start Gateway  \n  Prepare parameter file   /usr/local/etc/tomygateway/config/param.conf\n    \n    BrokerName=test.mosquitto.org     \n    BrokerPortNo=1883    \n    #LoginID=    \n    #Password=    \n    SerialDevice=/dev/ttyUSB0     \n    BaudRate=57600\n    BroadcastIP=225.1.1.1     \n    GatewayPortNo=2000      \n    BroadcastPortNo=1883     \n    GatewayID=1    \n    KeepAlive=900     \n\n  Prepare Key files for semaphore and sheared memory.  file's contents is emply.     \n\n    /usr/local/etc/tomygateway/config/rbmutex.key    \n    /usr/local/etc/tomygateway/config/ringbuffer.key     \n    /usr/local/etc/tomygateway/config/semaphore.key    \n\n  Execute      \n        $ TomyGateway     \n\n   \n\nXBee configurations\n----------------------\n  Serial interfacing  of gateway.  \n  Coordinator is default setting.\n  \n    [BD] 6   57600 bps\n    [D7] 1   CTS-Flow Control\n    [D6] 1   RTS-Flow Control\n    [AP] 2   API Enable\n\n  Other values are defaults.\n  \nGateway configurations\n----------------------\n  lib/Defines.h\n\n    /*=================================\n     *    CPU TYPE\n     ==================================*/\n    #define CPU_LITTLEENDIANN\n    //#define CPU_BIGENDIANN\n    \n    /*=================================\n     *    Debug LOG\n     ==================================*/\n    //#define DEBUG_NWSTACK     // show network layer transactions.     \n\nRaspberry Pi SD card img file    \n----------------------    \n  \n    1) Download from https://drive.google.com/a/tomy-tech.com/?tab=mo#folders/0ByWDD8Fur4QcMGpuRWd2RWVtMDA    \n    2) unzip and copy to SD card    \n    3) root's password is root    \n    4) Login ID is \"gw\" and password is \"gw\".    xxx.xxx... is IP address DHCP assigned.    \n        $ ssh xxx.xxx.xxx.xxx -l gw -p 22022  \n    5) Download latest version from github & compile  as follows  \n    6) $ rm -rf MQTT-SN    \n    7) $ git clone https://github.com/ty4tw/MQTT-SN.git     \n    8) $ cd MQTT-SN/Gateway      \n    9) $ make CXXFLAGS=-DRASPBERRY_PI \n       or \n       $ make CXXFLAGS=-DRASPBERRY_PI DEFS=-DNETWORK_UDP     \n    10) $ make install    \n    11)  reboot\n              \n\n    \nHow to connect XBee to Raspberry Pi    \n----------------------    \n    XBee Vcc ---> Raspberry Pi  Pin  1    \n    XBee Gnd ---> Raspberry Pi  Pin  6    \n    XBee RX  ---> Raspberry Pi  Pin  8    \n    XBee TX  ---> Raspberry Pi  Pin 10    \n\n\nHow to connect Indicators and power off switch    \n----------------------    \n    Green LED   ---> Raspberry Pi  Pin 16  (Broker connected)    \n    RED   LED   ---> Raspberry Pi  Pin 18  (Broker disconnected)    \n    Blue  LED   ---> Raspberry Pi  Pin 22  (Sending/Receiving)    \n    PWR Off SW  ---> Raspberry Pi  Pin 11  (shutdown safely)   \n    \n    \n     Pin 11  -----+-----/\\/\\/\\/----- +Vcc 3.3V    \n                  |       10K   \n                   |     \n                   |+ SW     \n                   |    \n                  |    \n                 GND     \n   \n\nHow to monitor the Gateway    \n----------------------\n    $ sudo /home/gw/LogMonitor    \n\n    \n\n\n  \n  \n  \n\n\n"
  },
  {
    "path": "Gateway/src/BrokerRecvTask.cpp",
    "content": "/*\n * BrokerRecvTask.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"BrokerRecvTask.h\"\n#include \"GatewayResourcesProvider.h\"\n#include \"GatewayDefines.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include <string.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nextern char* currentDateTime();\n\n\nBrokerRecvTask::BrokerRecvTask(GatewayResourcesProvider* res){\n\t_res = res;\n\t_res->attach(this);\n\t_stableNetwork = true;\n}\n\nBrokerRecvTask::~BrokerRecvTask(){\n\n}\n\n\nvoid BrokerRecvTask::run(){\n\tchar param[TOMYFRAME_PARAM_MAX];\n\tif(_res->getParam(\"NetworkIsStable\",param) == 0){\n\t\tif(!strcasecmp(param, \"NO\")){\n\t\t\t_stableNetwork = false;\n\t\t}\n\t}\n\n\tstruct timeval timeout;\n\n\tLightIndicator* lightIndicator = _res->getLightIndicator();\n\tClientList* clist = _res->getClientList();\n\tfd_set rset;\n\tfd_set wset;\n\n\twhile(true){\n\t\ttimeout.tv_sec = 0;\n\t\ttimeout.tv_usec = 500000;    // 500 msec\n\t\tFD_ZERO(&rset);\n\t\tFD_ZERO(&wset);\n\t\tint maxSock = 0;\n\t\tint sockfd = 0;\n\n\t\t/*------- Prepare socket list to check -------*/\n\t\tfor( int i = 0; i < clist->getClientCount(); i++){\n\t\t\tif((*clist)[i]){\n\t\t\t\tif((*clist)[i]->getStack()->isValid()){\n\t\t\t\t\tsockfd = (*clist)[i]->getStack()->getSock();\n\t\t\t\t\tFD_SET(sockfd, &rset);\n\t\t\t\t\tFD_SET(sockfd, &wset);\n\t\t\t\t\tif(sockfd > maxSock){\n\t\t\t\t\t\tmaxSock = sockfd;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(maxSock == 0){\n\t\t\tlightIndicator->greenLight(false);\n\t\t}else{\n\n\t\t\t/*------- Check socket to receive -------*/\n\t\t\tint activity =  select( maxSock + 1 , &rset , 0 , 0 , &timeout);\n\n\t\t\tif (activity > 0){\n\t\t\t\tfor( int i = 0; i < clist->getClientCount(); i++){\n\t\t\t\t\tif((*clist)[i]){\n\t\t\t\t\t\tif((*clist)[i]->getStack()->isValid()){\n\t\t\t\t\t\t\tint sockfd = (*clist)[i]->getStack()->getSock();\n\t\t\t\t\t\t\tif(FD_ISSET(sockfd, &rset)){\n\t\t\t\t\t\t\t\trecvAndFireEvent((*clist)[i]);\n\t\t\t\t\t\t\t\tlightIndicator->greenLight(true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}else{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n/*-----------------------------------------\n     Recv socket & Create MQTT Messages\n -----------------------------------------*/\nvoid BrokerRecvTask::recvAndFireEvent(ClientNode* clnode){\n\n\tuint8_t sbuff[SOCKET_MAXBUFFER_LENGTH * 5];\n\tuint8_t buffer[SOCKET_MAXBUFFER_LENGTH];\n\tmemset(buffer, 0, SOCKET_MAXBUFFER_LENGTH);\n\tint recvLength = 0;\n\tuint8_t* packet = buffer;\n\n\trecvLength = clnode->getStack()->recv(packet,SOCKET_MAXBUFFER_LENGTH);\n\n\tif (recvLength == -1){\n\t\tLOGWRITE(\" Client : %s Error: BrokerRecvTask can't Receive data from Broker\\n\", clnode->getNodeId()->c_str());\n\t\tclnode->disconnected();\n\t}\n\n\twhile(recvLength > 0){\n\n\t\tif((*packet & 0xf0) == MQTT_TYPE_PUBACK){\n\t\t\tMQTTPubAck* puback = new MQTTPubAck();\n\t\t\tpuback->deserialize(packet);\n\t\t\tpuback->serialize(sbuff);\n\t\t\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBACK\", LEFTARROW, BROKER, msgPrint(sbuff, puback));\n\n\t\t\tclnode->setBrokerRecvMessage(puback);\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_PUBREC){\n\t\t\tMQTTPubRec* pubRec = new MQTTPubRec();\n\t\t\tpubRec->deserialize(packet);\n\t\t\tpubRec->serialize(sbuff);\n\t\t\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBREC\", LEFTARROW, BROKER, msgPrint(sbuff, pubRec));\n\n\t\t\tclnode->setBrokerRecvMessage(pubRec);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_PUBREL){\n\t\t\tMQTTPubRel* pubRel = new MQTTPubRel();\n\t\t\tpubRel->deserialize(packet);\n\t\t\tpubRel->serialize(sbuff);\n\t\t\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBREL\", LEFTARROW, BROKER, msgPrint(sbuff, pubRel));\n\n\t\t\tclnode->setBrokerRecvMessage(pubRel);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_PUBCOMP){\n\t\t\tMQTTPubComp* pubComp = new MQTTPubComp();\n\t\t\tpubComp->deserialize(packet);\n\t\t\tpubComp->serialize(sbuff);\n\t\t\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBCOMP\", LEFTARROW, BROKER, msgPrint(sbuff, pubComp));\n\n\t\t\tclnode->setBrokerRecvMessage(pubComp);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_PUBLISH){\n\t\t\tMQTTPublish* publish = new MQTTPublish();\n\t\t\tif(!publish->deserialize(packet)){\n\t\t\t\tclnode->disconnected();\n\t\t\t\tclnode->getStack()->disconnect();\n\t\t\t\tLOGWRITE(\"%s ill-formed UTF-8\\n\",currentDateTime());\n\t\t\t}\n\t\t\tpublish->serialize(sbuff);\n\t\t\tLOGWRITE(GREEN_FORMAT2, currentDateTime(), \"PUBLISH\", LEFTARROW, BROKER, msgPrint(sbuff, publish));\n\n\t\t\tclnode->setBrokerRecvMessage(publish);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_SUBACK){\n\t\t\tMQTTSubAck* suback = new MQTTSubAck();\n\t\t\tsuback->deserialize(packet);\n\t\t\tsuback->serialize(sbuff);\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"SUBACK\", LEFTARROW, BROKER, msgPrint(sbuff, suback));\n\n\t\t\tclnode->setBrokerRecvMessage(suback);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_PINGRESP){\n\t\t\tMQTTPingResp* pingresp = new MQTTPingResp();\n\t\t\tpingresp->deserialize(packet);\n\t\t\tpingresp->serialize(sbuff);\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"PINGRESP\", LEFTARROW, BROKER, msgPrint(sbuff, pingresp));\n\n\t\t\tclnode->setBrokerRecvMessage(pingresp);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_UNSUBACK){\n\t\t\tMQTTUnsubAck* unsuback = new MQTTUnsubAck();\n\t\t\tunsuback->deserialize(packet);\n\t\t\tunsuback->serialize(sbuff);\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"UNSUBACK\", LEFTARROW, BROKER, msgPrint(sbuff, unsuback));\n\n\t\t\tclnode->setBrokerRecvMessage(unsuback);\n\n\t\t}else if((*packet & 0xf0) == MQTT_TYPE_CONNACK){\n\t\t\tMQTTConnAck* connack = new MQTTConnAck();\n\t\t\tconnack->deserialize(packet);\n\t\t\tconnack->serialize(sbuff);\n\t\t\tLOGWRITE(CYAN_FORMAT1, currentDateTime(), \"CONNACK\", LEFTARROW, BROKER, msgPrint(sbuff, connack));\n\n\t\t\tclnode->setBrokerRecvMessage(connack);\n\n\t\t}else{\n\t\t\tLOGWRITE(\"%s UNKOWN_TYPE  packetLength=%d\\n\",currentDateTime(), recvLength);\n\t\t\treturn;\n\t\t}\n\n\t\tEvent* ev = new Event();\n\t\tev->setBrokerRecvEvent(clnode);\n\t\t_res->getGatewayEventQue()->post(ev);\n\n\t\tRemainingLength rl;\n\t\trl.deserialize(packet + 1);\n\t\tuint16_t  packetLength = 1 + rl.getSize() + rl.decode();\n\t\trecvLength -= packetLength;\n\t\tpacket += packetLength;\n\t}\n}\n\n\nchar*  BrokerRecvTask::msgPrint(uint8_t* buffer, MQTTMessage* msg){\n\tchar* buf = _printBuf;\n\n\t_res->getLightIndicator()->blueLight(true);\n\n\tsprintf(buf, \" %02X\", *buffer);\n\tbuf += 3;\n\n\tfor(int i = 0; i < msg->getRemainLength() + msg->getRemainLengthSize(); i++){\n\t\tsprintf(buf, \" %02X\", *( buffer + 1 + i));\n\t\tbuf += 3;\n\t}\n\t*buf = 0;\n\t_res->getLightIndicator()->blueLight(false);\n\treturn _printBuf;\n}\n"
  },
  {
    "path": "Gateway/src/BrokerRecvTask.h",
    "content": "/*\n * BrokerRecvTask.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef BROKERRECVTASK_H_\n#define BROKERRECVTASK_H_\n\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"GatewayResourcesProvider.h\"\n\n\nclass BrokerRecvTask : public Thread{\n\tMAGIC_WORD_FOR_TASK;\npublic:\n\tBrokerRecvTask(GatewayResourcesProvider* res);\n\t~BrokerRecvTask();\n\tvoid initialize();\n\tvoid run();\n\tchar* msgPrint(uint8_t* buf, MQTTMessage* msg);\n\nprivate:\n\tvoid recvAndFireEvent(ClientNode*);\n\tGatewayResourcesProvider* _res;\n\tchar _printBuf[SOCKET_MAXBUFFER_LENGTH * 5];\n\tbool _stableNetwork;\n};\n\n\n#endif /* BROKERRECVTASK_H_ */\n"
  },
  {
    "path": "Gateway/src/BrokerSendTask.cpp",
    "content": "/*\n * BrokerSendTask.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"BrokerSendTask.h\"\n#include \"GatewayResourcesProvider.h\"\n#include \"GatewayDefines.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"lib/Defines.h\"\n#include <string.h>\n#include <errno.h>\n#include <iostream>\n#include <sys/types.h>\n#include <sys/socket.h>\n\nextern char* currentDateTime();\n\n\nBrokerSendTask::BrokerSendTask(GatewayResourcesProvider* res){\n\t_res = res;\n\t_res->attach(this);\n}\n\nBrokerSendTask::~BrokerSendTask(){\n\tif(_host){\n\t\tdelete _host;\n\t}\n\tif(_service){\n\t\tdelete _service;\n\t}\n}\n\nvoid BrokerSendTask::run(){\n\tEvent* ev = 0;\n\tMQTTMessage* srcMsg = 0;\n\tClientNode* clnode = 0;\n\tchar param[TOMYFRAME_PARAM_MAX];\n\n\t\tif(_res->getParam(\"BrokerName\",param) == 0){\n\t\t\t_host = strdup(param);\n\t\t}\n\t\tif(_res->getParam(\"BrokerPortNo\",param) == 0){\n\t\t\t_service =strdup( param);\n\t\t}\n\t\t_light = _res->getLightIndicator();\n\n\n\twhile(true){\n\n\t\tuint16_t length = 0;\n\t\tmemset(_buffer, 0, SOCKET_MAXBUFFER_LENGTH);\n\n\t\tev = _res->getBrokerSendQue()->wait();\n\n\t\tclnode = ev->getClientNode();\n\t\tsrcMsg = clnode->getBrokerSendMessage();\n\n\t\tif(srcMsg->getType() == MQTT_TYPE_PUBLISH){\n\t\t\tMQTTPublish* msg = static_cast<MQTTPublish*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(BLUE_FORMAT, currentDateTime(), \"PUBLISH\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_PUBACK){\n\t\t\tMQTTPubAck* msg = static_cast<MQTTPubAck*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(GREEN_FORMAT, currentDateTime(), \"PUBACK\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_PUBREL){\n\t\t\tMQTTPubRel* msg = static_cast<MQTTPubRel*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(GREEN_FORMAT, currentDateTime(), \"PUBREL\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_PINGREQ){\n\t\t\tMQTTPingReq* msg = static_cast<MQTTPingReq*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(FORMAT, currentDateTime(), \"PINGREQ\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_SUBSCRIBE){\n\t\t\tMQTTSubscribe* msg = static_cast<MQTTSubscribe*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(FORMAT, currentDateTime(), \"SUBSCRIBE\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_UNSUBSCRIBE){\n\t\t\tMQTTUnsubscribe* msg = static_cast<MQTTUnsubscribe*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(FORMAT, currentDateTime(), \"UNSUBSCRIBE\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_CONNECT){\n\t\t\tMQTTConnect* msg = static_cast<MQTTConnect*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(FORMAT, currentDateTime(), \"CONNECT\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tclnode->connectSended();\n\t\t\tsend(clnode, length);\n\n\t\t}else if(srcMsg->getType() == MQTT_TYPE_DISCONNECT){\n\t\t\tMQTTDisconnect* msg = static_cast<MQTTDisconnect*>(srcMsg);\n\t\t\tlength = msg->serialize(_buffer);\n\t\t\tLOGWRITE(FORMAT, currentDateTime(), \"DISCONNECT\", RIGHTARROW, GREEN_BROKER, msgPrint(msg));\n\t\t\tsend(clnode, length);\n\n\t\t\tclnode->getStack()->disconnect();\n\t\t}\n\n\t\tdelete ev;\n\t}\n}\n\n\nint BrokerSendTask::send(ClientNode* clnode, int length){\n\tint rc = -1;\n\n\tif(length <= 0){\n\t\treturn rc;\n\t}\n\n\tif( clnode->getStack()->isValid()){\n\t\trc = clnode->getStack()->send(_buffer, length);\n\t\tif(rc != length){\n\t\t\tLOGWRITE(\"\\n%s   \\x1b[0m\\x1b[31merror:\\x1b[0m\\x1b[37m Can't Xmit to the Broker. errno=%d\\n\", currentDateTime(), rc == -1 ? errno : 0);\n\t\t\tclnode->getStack()->disconnect();\n\t\t\tclnode->disconnected();\n\t\t}else{\n\t\t\t_light->greenLight(true);\n\t\t}\n\t}else{\n\t\tif(clnode->getStack()->connect(_host, _service)){\n\t\t\trc = clnode->getStack()->send(_buffer, length);\n\t\t\tif(rc != length){\n\t\t\t\tLOGWRITE(\"\\n%s   \\x1b[0m\\x1b[31merror:\\x1b[0m\\x1b[37m Can't Xmit to the Broker. errno=%d\\n\", currentDateTime(), rc == -1 ? errno : 0);\n\t\t\t\tclnode->getStack()->disconnect();\n\t\t\t\tclnode->disconnected();\n\t\t\t}else{\n\t\t\t\t_light->greenLight(true);\n\t\t\t}\n\t\t}else{\n\t\t\tLOGWRITE(\"\\n%s   \\x1b[0m\\x1b[31merror:\\x1b[0m\\x1b[37m Can't connect to the Broker.\\n\", currentDateTime());\n\t\t\tclnode->getStack()->disconnect();\n\t\t\tclnode->disconnected();\n\t\t}\n\t}\n\treturn rc;\n}\n\nchar*  BrokerSendTask::msgPrint(MQTTMessage* msg){\n\tchar* buf = _printBuf;\n\t_light->blueLight(true);\n\n\tsprintf(buf, \" %02X\", *_buffer);\n\tbuf += 3;\n\n\tfor(int i = 0; i < msg->getRemainLength() + msg->getRemainLengthSize(); i++){\n\t\tsprintf(buf, \" %02X\", *( _buffer + 1  + i));\n\t\tbuf += 3;\n\t}\n\t*buf = 0;\n\t_light->blueLight(false);\n\treturn _printBuf;\n}\n\n"
  },
  {
    "path": "Gateway/src/BrokerSendTask.h",
    "content": "/*\n * BrokerSendTask.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef BROKERSENDTASK_H_\n#define BROKERSENDTASK_H_\n\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"GatewayResourcesProvider.h\"\n\nclass BrokerSendTask : public Thread{\n\tMAGIC_WORD_FOR_TASK;\npublic:\n\tBrokerSendTask(GatewayResourcesProvider* res);\n\t~BrokerSendTask();\n\tvoid run();\n\nprivate:\n\tchar* msgPrint(MQTTMessage* msg);\n\tint   send(ClientNode* clnode, int length);\n\n\tGatewayResourcesProvider* _res;\n\tchar _printBuf[SOCKET_MAXBUFFER_LENGTH * 5];\n\tuint8_t _buffer[SOCKET_MAXBUFFER_LENGTH];\n\tconst char* _host;\n\tconst char* _service;\n\tLightIndicator* _light;\n};\n\n\n#endif /* BROKERSENDTASK_H_ */\n"
  },
  {
    "path": "Gateway/src/ClientRecvTask.cpp",
    "content": "/*\n * ClientRecvTask.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#include \"ClientRecvTask.h\"\n#include \"GatewayResourcesProvider.h\"\n#include \"GatewayDefines.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"lib/ZBStack.h\"\n#include \"ErrorMessage.h\"\n\n\n#include <unistd.h>\n#include <iostream>\n#include <fcntl.h>\n#include <stdlib.h>\n#include <string.h>\n#include <termios.h>\n\nextern char* currentDateTime();\n\nClientRecvTask::ClientRecvTask(GatewayResourcesProvider* res){\n\t_res = res;\n\t_res->attach(this);\n}\n\nClientRecvTask::~ClientRecvTask(){\n\n}\n\n\n\nvoid ClientRecvTask::run(){\n\tNETWORK_CONFIG config;\n\tchar param[TOMYFRAME_PARAM_MAX];\n\tbool secure = false;   // TCP\n\n#ifdef NETWORK_XBEE\n\n\tif(_res->getParam(\"BaudRate\",param) == 0){\n\n\t\tint val = atoi(param);\n\t\tswitch(val){\n\t\tcase 9600:\n\t\t\tconfig.baudrate = B9600;\n\t\t\tbreak;\n\t\tcase 19200:\n\t\t\tconfig.baudrate =B19200;\n\t\t\tbreak;\n\t\tcase 38400:\n\t\t\tconfig.baudrate =B38400;\n\t\t\tbreak;\n\t\tcase 57600:\n\t\t\tconfig.baudrate =B57600;\n\t\t\tbreak;\n\t\tcase 115200:\n\t\t\tconfig.baudrate = B115200;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_01, \"Invalid baud rate!\");  // ABORT\n\t\t}\n\t}else{\n\t\tconfig.baudrate = B57600;\n\t}\n\tconfig.flag = O_RDONLY;\n\tif(_res->getParam(\"SerialDevice\",param) == 0){\n\t\tconfig.device = strdup(param);\n\t}\n\n\tif(_res->getParam(\"SecureConnection\",param) == 0){\n\t\tif(!strcasecmp(param, \"YES\")){\n\t\t\tsecure = true;  // TLS\n\t\t}\n\t}\n\n\t_res->getClientList()->authorize(FILE_NAME_CLIENT_LIST, secure);\n\t_network = new Network();\n\n#endif\n\n#ifdef NETWORK_UDP\n\tif(_res->getParam(\"BroadcastIP\", param) == 0){\n\t\tconfig.ipAddress = strdup(param);\n\t}\n\tif(_res->getParam(\"BroadcastPortNo\",param) == 0){\n\t\tconfig.gPortNo = atoi(param);\n\t}\n\tif(_res->getParam(\"GatewayPortNo\",param) == 0){\n\t\tconfig.uPortNo = atoi(param);\n\t}\n\t_network = _res->getNetwork();\n#endif\n\n#ifdef NETWORK_XXXXX\n\t_network = _res->getNetwork();\n#endif\n\tif(_network->initialize(config) < 0){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_01, \"can't open the client port.\");  // ABORT\n\t}\n\n\twhile(true){\n\n\t\tNWResponse* resp = new NWResponse();\n\t\tbool eventSetFlg = true;\n\n\t\tif(_network->getResponse(resp)){\n\t\t\tEvent* ev = new Event();\n\t\t\tClientNode* clnode = _res->getClientList()->getClient(resp->getClientAddress64(),\n\t\t\t\t\t                                              resp->getClientAddress16());\n\n\t\t\tif(!clnode){\n\t\t\t\tif(resp->getMsgType() == MQTTSN_TYPE_CONNECT){\n\n\t\t\t\t#ifdef NETWORK_XBEE\n\t\t\t\t\tClientNode* node = _res->getClientList()->createNode(secure, resp->getClientAddress64(),0);\n\t\t\t\t#endif\n\t\t\t\t#ifdef NETWORK_UDP\n\t\t\t\t\tClientNode* node = _res->getClientList()->createNode(secure, resp->getClientAddress64(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tresp->getClientAddress16());\n\t\t\t\t#endif\n\t\t\t\t#ifdef NETWORK_XXXXX\n\t\t\t\t\tClientNode* node = _res->getClientList()->createNode(secure, resp->getClientAddress64(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tresp->getClientAddress16());\n\t\t\t\t#endif\n\n\t\t\t\t\tif(!node){\n\t\t\t\t\t\tdelete ev;\n\t\t\t\t\t\tLOGWRITE(\"Client is not authorized.\\n\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tMQTTSnConnect* msg = new MQTTSnConnect();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tnode->setClientAddress16(resp->getClientAddress16());\n\t\t\t\t\tif(msg->getClientId()->size() > 0){\n\t\t\t\t\t\tnode->setNodeId(msg->getClientId());\n\t\t\t\t\t}\n\t\t\t\t\tnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(node);\n\t\t\t\t}else if(resp->getMsgType() == MQTTSN_TYPE_SEARCHGW){\n\t\t\t\t\tMQTTSnSearchGw* msg = new MQTTSnSearchGw();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tev->setEvent(msg);\n\n\t\t\t\t}else{\n\t\t\t\t\teventSetFlg = false;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tif (resp->getMsgType() == MQTTSN_TYPE_CONNECT){\n\t\t\t\t\tMQTTSnConnect* msg = new MQTTSnConnect();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tclnode->setClientAddress16(resp->getClientAddress16());\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if(resp->getMsgType() == MQTTSN_TYPE_PUBLISH){\n\t\t\t\t\tMQTTSnPublish* msg = new MQTTSnPublish();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if(resp->getMsgType() == MQTTSN_TYPE_PUBACK){\n\t\t\t\t\tMQTTSnPubAck* msg = new MQTTSnPubAck();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if(resp->getMsgType() == MQTTSN_TYPE_PUBREL){\n\t\t\t\t\tMQTTSnPubRel* msg = new MQTTSnPubRel();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_CONNECT){\n\t\t\t\t\tMQTTSnConnect* msg = new MQTTSnConnect();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_PINGREQ){\n\t\t\t\t\tMQTTSnPingReq* msg = new MQTTSnPingReq();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_DISCONNECT){\n\t\t\t\t\tMQTTSnDisconnect* msg = new MQTTSnDisconnect();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_REGISTER){\n\t\t\t\t\tMQTTSnRegister* msg = new MQTTSnRegister();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_REGACK){\n\t\t\t\t\tMQTTSnRegAck* msg = new MQTTSnRegAck();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_UNSUBSCRIBE){\n\t\t\t\t\tMQTTSnUnsubscribe* msg = new MQTTSnUnsubscribe();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_SUBSCRIBE){\n\t\t\t\t\tMQTTSnSubscribe* msg = new MQTTSnSubscribe();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_WILLTOPIC){\n\t\t\t\t\tMQTTSnWillTopic* msg = new MQTTSnWillTopic();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if (resp->getMsgType() == MQTTSN_TYPE_WILLMSG){\n\t\t\t\t\tMQTTSnWillMsg* msg = new MQTTSnWillMsg();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tclnode->setClientRecvMessage(msg);\n\t\t\t\t\tev->setClientRecvEvent(clnode);\n\n\t\t\t\t}else if(resp->getMsgType() == MQTTSN_TYPE_SEARCHGW){\n\t\t\t\t\tMQTTSnSearchGw* msg = new MQTTSnSearchGw();\n\t\t\t\t\tclnode->disconnected();\n\t\t\t\t\tmsg->absorb(resp);\n\t\t\t\t\tev->setEvent(msg);\n\t\t\t\t}else{\n\t\t\t\t\teventSetFlg = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(eventSetFlg){\n\t\t\t\t_res->getGatewayEventQue()->post(ev);\n\t\t\t}else{\n\t\t\t\tdelete ev;\n\t\t\t}\n\t\t}\n\t\tdelete resp;\n\t}\n}\n\n\n\n\n\n"
  },
  {
    "path": "Gateway/src/ClientRecvTask.h",
    "content": "/*\n * ClientRecvTask.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef CLIENTRECVTASK_H_\n#define CLIENTRECVTASK_H_\n\n#include \"lib/ProcessFramework.h\"\n#include \"GatewayResourcesProvider.h\"\n\n/*=====================================\n     Class ClientRecvTask\n =====================================*/\nclass ClientRecvTask:public Thread{\n\tMAGIC_WORD_FOR_TASK;\npublic:\n\tClientRecvTask(GatewayResourcesProvider*);\n\t~ClientRecvTask();\n\tvoid run();\n\nprivate:\n\tGatewayResourcesProvider* _res;\n\tNetwork* _network;\n};\n\n\n#endif /* CLIENTRECVTASK_H_ */\n\n\n"
  },
  {
    "path": "Gateway/src/ClientSendTask.cpp",
    "content": "/*\n * ClientSendTask.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#include \"ClientSendTask.h\"\n#include \"GatewayResourcesProvider.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"ErrorMessage.h\"\n\n#include <unistd.h>\n#include <iostream>\n#include <fcntl.h>\n#include <stdlib.h>\n#include <string.h>\n#include <termios.h>\n\n\nClientSendTask::ClientSendTask(GatewayResourcesProvider* res){\n\t_res = res;\n\t_res->attach(this);\n}\n\nClientSendTask::~ClientSendTask(){\n\n}\n\n\nvoid ClientSendTask::run(){\n\tNETWORK_CONFIG config;\n#ifdef NETWORK_XBEE\n\n\tchar param[TOMYFRAME_PARAM_MAX];\n\tbool secure = true;\n\n\tif(_res->getParam(\"BaudRate\",param) == 0){\n\n\t\tint val = atoi(param);\n\t\tswitch(val){\n\t\tcase 9600:\n\t\t\tconfig.baudrate = B9600;\n\t\t\tbreak;\n\t\tcase 19200:\n\t\t\tconfig.baudrate =B19200;\n\t\t\tbreak;\n\t\tcase 38400:\n\t\t\tconfig.baudrate =B38400;\n\t\t\tbreak;\n\t\tcase 57600:\n\t\t\tconfig.baudrate =B57600;\n\t\t\tbreak;\n\t\tcase 115200:\n\t\t\tconfig.baudrate = B115200;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_01, \"Invalid baud rate!\");  // ABORT\n\t\t}\n\t}else{\n\t\tconfig.baudrate = B57600;\n\t}\n\tconfig.flag = O_WRONLY;\n\tif(_res->getParam(\"SerialDevice\", param) == 0){\n\t\tconfig.device = strdup(param);\n\t}\n\tif(_res->getParam(\"SecureConnection\",param) == 0){\n\t\tif(strcmp(param, \"YES\")){\n\t\t\tsecure = false;  // TCP\n\t\t}\n\t}\n\t_res->getClientList()->authorize(FILE_NAME_CLIENT_LIST, secure);\n\t_network = new Network();\n\n\tif(_network->initialize(config) < 0){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_01, \"can't open the client port.\");  // ABORT\n\t}\n\n#endif\n\n#ifdef NETWORK_UDP\n\t_network = _res->getNetwork();\n\n#endif\n\n#ifdef NETWORK_XXXXX\n\t_network = _res->getNetwork();\n#endif\n\n\n\twhile(true){\n\t\tEvent* ev = _res->getClientSendQue()->wait();\n\n\t\tif(ev->getEventType() == EtClientSend){\n\t\t\tMQTTSnMessage msg = MQTTSnMessage();\n\t\t\tClientNode* clnode = ev->getClientNode();\n\t\t\tmsg.absorb( clnode->getClientSendMessage() );\n\n\t\t\t_network->unicast(clnode->getAddress64Ptr(), clnode->getAddress16(),\n\t\t\t\t\tmsg.getMessagePtr(), msg.getMessageLength());\n\t\t}else if(ev->getEventType() == EtBroadcast){\n\t\t\tMQTTSnMessage msg = MQTTSnMessage();\n\t\t\tmsg.absorb( ev->getMqttSnMessage() );\n\t\t\t_network->broadcast(msg.getMessagePtr(), msg.getMessageLength());\n\t\t}\n\t\tdelete ev;\n\t}\n}\n\n\n"
  },
  {
    "path": "Gateway/src/ClientSendTask.h",
    "content": "/*\n * ClientSendTask.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef CLIENTSENDTASK_H_\n#define CLIENTSENDTASK_H_\n\n#include \"lib/ProcessFramework.h\"\n#include \"GatewayResourcesProvider.h\"\n\nclass ClientSendTask:public Thread{\n\tMAGIC_WORD_FOR_TASK;\npublic:\n\tClientSendTask(GatewayResourcesProvider* res);\n\t~ClientSendTask();\n\n\tvoid run();\n\nprivate:\n\tGatewayResourcesProvider* _res;\n\tNetwork* _network;\n};\n\n\n#endif /* CLIENTSENDTASK_H_ */\n\n\n"
  },
  {
    "path": "Gateway/src/ErrorMessage.h",
    "content": "/*\n * ErrorMessage.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef ERRORMESSAGE_H_\n#define ERRORMESSAGE_H_\n\n\n#define ERRNO_APL_01  1001   // can't open device.\n#define ERRNO_APL_02  1002   // Socket error\n#define ERRNO_APL_03  1003   // can't create a clientNode.\n#define ERRNO_APL_04  1004   // invalid GatewayId\n#define ERRNO_APL_05  1005   // KeepAliveTime is grater than 65536 Secs\n\n#endif /* ERRORMESSAGE_H_ */\n"
  },
  {
    "path": "Gateway/src/GatewayControlTask.cpp",
    "content": "/*\n * GatewayControlTask.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include <stdio.h>\n#include <iostream>\n#include <string.h>\n#include <time.h>\n#include \"GatewayControlTask.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"GatewayResourcesProvider.h\"\n#include \"GatewayDefines.h\"\n#include \"lib/Messages.h\"\n#include \"ErrorMessage.h\"\n\nextern char* currentDateTime();\nextern uint16_t getUint16(uint8_t* pos);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=====================================\n        Class GatewayControlTask\n =====================================*/\n\nGatewayControlTask::GatewayControlTask(GatewayResourcesProvider* res){\n\t_res = res;\n\t_res->attach(this);\n\t_eventQue = 0;\n\t_protocol = MQTT_PROTOCOL_VER4;\n\t_loginId = \"\";\n\t_password = \"\";\n\t_secure = false;\n\t_stableNetwork = true;\n}\n\nGatewayControlTask::~GatewayControlTask(){\n\n}\n\n\nvoid GatewayControlTask::run(){\n\tTimer advertiseTimer;\n\tTimer sendUnixTimer;\n\tEvent* ev = 0;\n\tchar param[TOMYFRAME_PARAM_MAX];\n\n\tif( _res->getParam(\"GatewayID\", param) == 0){\n\t\t_gatewayId = atoi(param);\n\t}else{\n\t\t_gatewayId = 0;\n\t}\n\tif (_gatewayId == 0 || _gatewayId > 255){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_04, \"Invalid Gateway Id\");  // ABORT\n\t}\n\n\tint keepAlive = KEEP_ALIVE_TIME;\n\tif( _res->getParam(\"KeepAlive\", param) == 0){\n\t\tkeepAlive =atoi(param);\n\t}\n\tif (keepAlive > 65536){\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_APL_05, \"KeepAliveTime is grater than 65536 Secs\");  // ABORT\n\t}\n\n\tif(_res->getParam(\"LoginID\", param) == 0){\n\t\t_loginId = strdup(param);\n\t}\n\tif(_res->getParam(\"Password\", param) == 0){\n\t\t_password = strdup(param);\n\t}\n\n\tif(_res->getParam(\"SecureConnection\",param) == 0){\n\t\tif(!strcasecmp(param, \"YES\")){\n\t\t\t_secure = true;  // TLS\n\t\t}\n\t}\n\tif(_res->getParam(\"NetworkIsStable\",param) == 0){\n\t\tif(!strcasecmp(param, \"NO\")){\n\t\t\t_stableNetwork = false;\n\t\t}\n\t}\n\n\t_eventQue = _res->getGatewayEventQue();\n\n\tadvertiseTimer.start(keepAlive * 1000UL);\n\n\tLOGWRITE(\"%s TomyGateway started. %s %s\\n\", currentDateTime(),GATEWAY_NETWORK,GATEWAY_VERSION);\n\n\n\twhile(true){\n\n\t\tev = _eventQue->timedwait(TIMEOUT_PERIOD);\n\n\t\t/*------     Check Client is Lost    ---------*/\n\t\tif(ev->getEventType() == EtTimeout){\n\t\t\tClientList* clist = _res->getClientList();\n\n\t\t\tfor( int i = 0; i < clist->getClientCount(); i++){\n\t\t\t\tif((*clist)[i]){\n\t\t\t\t\t(*clist)[i]->checkTimeover();\n\t\t\t\t}else{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*------ Check Keep Alive Timer & send Advertise ------*/\n\t\t\tif(advertiseTimer.isTimeup()){\n\t\t\t\tMQTTSnAdvertise* adv = new MQTTSnAdvertise();\n\t\t\t\tadv->setGwId(_gatewayId);\n\t\t\t\tadv->setDuration(keepAlive);\n\t\t\t\tEvent* ev1 = new Event();\n\t\t\t\tev1->setEvent(adv);  //broadcast\n\t\t\t\tLOGWRITE(YELLOW_FORMAT2, currentDateTime(), \"ADVERTISE\", LEFTARROW, GATEWAY, msgPrint(adv));\n\n\t\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\t\tadvertiseTimer.start(keepAlive * 1000UL);\n\t\t\t\tsendUnixTimer.start(SEND_UNIXTIME_TIME * 1000UL);\n\t\t\t}\n\n\t\t\t/*------ Check Timer & send UixTime ------*/\n\t\t\tif(sendUnixTimer.isTimeup()){\n\t\t\t\tuint8_t buf[4];\n\t\t\t\tuint32_t tm = time(0);\n\t\t\t\tsetUint32(buf,tm);\n\n\t\t\t\tMQTTSnPublish* msg = new MQTTSnPublish();\n\n\t\t\t\tmsg->setTopicId(MQTTSN_TOPICID_PREDEFINED_TIME);\n\t\t\t\tmsg->setTopicIdType(MQTTSN_TOPIC_TYPE_PREDEFINED);\n\t\t\t\tmsg->setData(buf, 4);\n\t\t\t\tmsg->setQos(0);\n\n\t\t\t\tEvent* ev1 = new Event();\n\t\t\t\tev1->setEvent(msg);\n\t\t\t\tLOGWRITE(YELLOW_FORMAT2, currentDateTime(), \"PUBLISH\", LEFTARROW, GATEWAY, msgPrint(msg));\n\n\t\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\t\tsendUnixTimer.stop();\n\t\t\t}\n\t\t}\n\n\t\t/*------   Check  SEARCHGW & send GWINFO      ---------*/\n\t\telse if(ev->getEventType() == EtBroadcast){\n\t\t\tMQTTSnMessage* msg = ev->getMqttSnMessage();\n\t\t\tLOGWRITE(YELLOW_FORMAT2, currentDateTime(), \"SERCHGW\", LEFTARROW, CLIENT, msgPrint(msg));\n\n\t\t\tif(msg->getType() == MQTTSN_TYPE_SEARCHGW){\n\t\t\t\tif(_res->getClientList()->getClientCount() <  MAX_CLIENT_NODES ){\n\t\t\t\t\tMQTTSnGwInfo* gwinfo = new MQTTSnGwInfo();\n\t\t\t\t\tgwinfo->setGwId(_gatewayId);\n\t\t\t\t\tEvent* ev1 = new Event();\n\t\t\t\t\tev1->setEvent(gwinfo);\n\t\t\t\t\tLOGWRITE(YELLOW_FORMAT1, currentDateTime(), \"GWINFO\", RIGHTARROW, CLIENT, msgPrint(gwinfo));\n\n\t\t\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\t\n\t\t/*------   Message form Clients      ---------*/\n\t\telse if(ev->getEventType() == EtClientRecv){\n\n\t\t\tClientNode* clnode = ev->getClientNode();\n\t\t\tMQTTSnMessage* msg = clnode->getClientRecvMessage();\n\n\t\t\tclnode->updateStatus(msg);\n\n\t\t\tif(msg->getType() == MQTTSN_TYPE_PUBLISH){\n\t\t\t\thandleSnPublish(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_SUBSCRIBE){\n\t\t\t\thandleSnSubscribe(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_UNSUBSCRIBE){\n\t\t\t\thandleSnUnsubscribe(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_PINGREQ){\n\t\t\t\thandleSnPingReq(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_PUBACK){\n\t\t\t\thandleSnPubAck(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_WILLTOPIC){\n\t\t\t\thandleSnWillTopic(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_WILLMSG){\n\t\t\t\thandleSnWillMsg(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_CONNECT) {\n\t\t\t\thandleSnConnect(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_DISCONNECT){\n\t\t\t\thandleSnDisconnect(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_REGISTER){\n\t\t\t\thandleSnRegister(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_PUBREC){\n\t\t\t\thandleSnPubRec(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_PUBREL){\n\t\t\t\thandleSnPubRel(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTTSN_TYPE_PUBCOMP){\n\t\t\t\thandleSnPubComp(ev, clnode, msg);\n\t\t\t}else{\n\t\t\t\tLOGWRITE(\"%s   Irregular ClientRecvMessage\\n\", currentDateTime());\n\t\t\t}\n\n\t\t}\n\t\t/*------   Message form Broker      ---------*/\n\t\telse if(ev->getEventType() == EtBrokerRecv){\n\n\t\t\tClientNode* clnode = ev->getClientNode();\n\t\t\tMQTTMessage* msg = clnode->getBrokerRecvMessage();\n\t\t\t\n\t\t\tif(msg->getType() == MQTT_TYPE_PUBACK){\n\t\t\t\thandlePuback(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_PINGRESP){\n\t\t\t\thandlePingresp(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_SUBACK){\n\t\t\t\thandleSuback(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_UNSUBACK){\n\t\t\t\thandleUnsuback(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_CONNACK){\n\t\t\t\thandleConnack(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_PUBLISH){\n\t\t\t\thandlePublish(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_DISCONNECT){\n\t\t\t\thandleDisconnect(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_PUBREC){\n\t\t\t\thandlePubRec(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_PUBREL){\n\t\t\t\thandlePubRel(ev, clnode, msg);\n\t\t\t}else if(msg->getType() == MQTT_TYPE_PUBCOMP){\n\t\t\t\thandlePubComp(ev, clnode, msg);\n\t\t\t}else{\n\t\t\t\tLOGWRITE(\"%s   Irregular BrokerRecvMessage\\n\", currentDateTime());\n\t\t\t}\n\t\t}\n\n\t\tdelete ev;\n\t}\n}\n\n/*=======================================================\n                     Upstream\n ========================================================*/\n\n/*-------------------------------------------------------\n *               Upstream MQTTSnPublish\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPublish(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(BLUE_FORMAT2, currentDateTime(), \"PUBLISH\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnPublish* sPublish = new MQTTSnPublish();\n\tMQTTPublish* mqMsg = new MQTTPublish();\n\tsPublish->absorb(msg);\n\n\tTopic* tp = clnode->getTopics()->getTopic(sPublish->getTopicId());\n\n\tif(tp || ((sPublish->getFlags() && MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_SHORT)){\n\t\tif(tp){\n\t\t\tmqMsg->setTopic(tp->getTopicName());\n\t\t}else{\n\t\t\tstring str;\n\t\t\tmqMsg->setTopic(sPublish->getTopic(&str));\n\t\t}\n\t\tif(sPublish->getMsgId()){\n\t\t\tMQTTSnPubAck* sPuback = new MQTTSnPubAck();\n\t\t\tsPuback->setMsgId(sPublish->getMsgId());\n\t\t\tsPuback->setTopicId(sPublish->getTopicId());\n\t\t\tif(clnode->getWaitedPubAck()){\n\t\t\t\tdelete clnode->getWaitedPubAck();\n\t\t\t}\n\t\t\tclnode->setWaitedPubAck(sPuback);\n\n\t\t\tmqMsg->setMessageId(sPublish->getMsgId());\n\t\t}\n\n\t\tmqMsg->setQos(sPublish->getQos());\n\n\t\tif(sPublish->getFlags() & MQTTSN_FLAG_DUP){\n\t\t\tmqMsg->setDup();\n\t\t}\n\t\tif(sPublish->getFlags() & MQTTSN_FLAG_RETAIN){\n\t\t\tmqMsg->setRetain();\n\t\t}\n\n\t\tmqMsg->setPayload(sPublish->getData() , sPublish->getDataLength());\n\n\t\tclnode->setBrokerSendMessage(mqMsg);\n\t\tEvent* ev1 = new Event();\n\t\tev1->setBrokerSendEvent(clnode);\n\t\t_res->getBrokerSendQue()->post(ev1);\n\n\t}else{\n\t\tif(sPublish->getMsgId()){\n\t\t\tMQTTSnPubAck* sPuback = new MQTTSnPubAck();\n\t\t\tsPuback->setMsgId(sPublish->getMsgId());\n\t\t\tsPuback->setTopicId(sPublish->getTopicId());\n\t\t\tsPuback->setReturnCode(MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);\n\n\t\t\tclnode->setClientSendMessage(sPuback);\n\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setClientSendEvent(clnode);\n\t\t\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sPuback));\n\n\t\t\t_res->getClientSendQue()->post(ev1);  // Send PubAck INVALID_TOPIC_ID\n\t\t}\n\t}\n\tdelete sPublish;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnSubscribe\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnSubscribe(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\tLOGWRITE(FORMAT2, currentDateTime(), \"SUBSCRIBE\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnSubscribe* sSubscribe = new MQTTSnSubscribe();\n\tMQTTSubscribe* subscribe = new MQTTSubscribe();\n\tsSubscribe->absorb(msg);\n\n\tuint8_t topicIdType = sSubscribe->getFlags() & 0x03;\n\n\tsubscribe->setMessageId(sSubscribe->getMsgId());\n\n\tif(sSubscribe->getFlags() & MQTTSN_FLAG_DUP ){\n\t\tsubscribe->setDup();\n\t}\n\tif(sSubscribe->getFlags() & MQTTSN_FLAG_RETAIN){\n\t\tsubscribe->setRetain();\n\t}\n\tsubscribe->setQos(sSubscribe->getQos());\n\n\tif(topicIdType != MQTTSN_FLAG_TOPICID_TYPE_RESV){\n\t\tif(topicIdType == MQTTSN_FLAG_TOPICID_TYPE_PREDEFINED){\n\t\t\t/*----- Predefined TopicId ------*/\n\t\t\tMQTTSnSubAck* sSuback = new MQTTSnSubAck();\n\n\t\t\tif(sSubscribe->getMsgId()){       // MessageID\n\t\t\t\tsSuback->setQos(sSubscribe->getQos());\n\t\t\t\tsSuback->setTopicId(sSubscribe->getTopicId());\n\t\t\t\tsSuback->setMsgId(sSubscribe->getMsgId());\n\n\t\t\t\tif(sSubscribe->getTopicId() == MQTTSN_TOPICID_PREDEFINED_TIME){\n\t\t\t\t\tsSuback->setReturnCode(MQTT_RC_ACCEPTED);\n\t\t\t\t}else{\n\t\t\t\t\tsSuback->setReturnCode(MQTT_RC_REFUSED_IDENTIFIER_REJECTED);\n\t\t\t\t}\n\n\t\t\t\tclnode->setClientSendMessage(sSuback);\n\n\t\t\t\tEvent* evsuback = new Event();\n\t\t\t\tevsuback->setClientSendEvent(clnode);\n\t\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"SUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sSuback));\n\n\t\t\t\t_res->getClientSendQue()->post(evsuback);\n\t\t\t}\n\n\t\t\tif(sSubscribe->getTopicId() == MQTTSN_TOPICID_PREDEFINED_TIME){\n\n\t\t\t\tMQTTSnPublish* pub = new MQTTSnPublish();\n\t\t\t\tpub->setTopicIdType(1);  // pre-defined\n\t\t\t\tpub->setTopicId(MQTTSN_TOPICID_PREDEFINED_TIME);\n\t\t\t\tpub->setMsgId(clnode->getNextSnMsgId());\n\n\t\t\t\tuint8_t buf[4];\n\t\t\t\tuint32_t tm = time(0);\n\t\t\t\tsetUint32(buf,tm);\n\n\t\t\t\tpub->setData(buf, 4);\n\t\t\t\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBLISH\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(pub));\n\n\t\t\t\tclnode->setClientSendMessage(pub);\n\n\t\t\t\tEvent *evpub = new Event();\n\t\t\t\tevpub->setClientSendEvent(clnode);\n\t\t\t\t_res->getClientSendQue()->post(evpub);\n\t\t\t}\n\t\t\tdelete subscribe;\n\t\t}else{\n\t\t\tuint16_t tpId;\n\n\t\t\tTopic* tp = clnode->getTopics()->getTopic(sSubscribe->getTopicName());\n\t\t\tif (tp){\n\t\t\t\ttpId = tp->getTopicId();\n\t\t\t}else{\n\t\t\t\ttpId = clnode->getTopics()->createTopic(sSubscribe->getTopicName());\n\t\t\t}\n\n\t\t\tsubscribe->setTopic(sSubscribe->getTopicName(), sSubscribe->getQos());\n\t\t\tif(sSubscribe->getMsgId()){\n\t\t\t\tMQTTSnSubAck* sSuback = new MQTTSnSubAck();\n\t\t\t\tsSuback->setMsgId(sSubscribe->getMsgId());\n\t\t\t\tsSuback->setTopicId(tpId);\n\t\t\t\tclnode->setWaitedSubAck(sSuback);\n\t\t\t}\n\n\t\t\tclnode->setBrokerSendMessage(subscribe);\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setBrokerSendEvent(clnode);\n\t\t\t_res->getBrokerSendQue()->post(ev1);\n\t\t\tdelete sSubscribe;\n\t\t\treturn;\n\t\t}\n\n\t}else{\n\t\t/*-- Irregular TopicIdType --*/\n\t\tif(sSubscribe->getMsgId()){\n\t\t\tMQTTSnSubAck* sSuback = new MQTTSnSubAck();\n\t\t\tsSuback->setMsgId(sSubscribe->getMsgId());\n\t\t\tsSuback->setTopicId(sSubscribe->getTopicId());\n\t\t\tsSuback->setReturnCode(MQTT_RC_REFUSED_IDENTIFIER_REJECTED);\n\n\t\t\tclnode->setClientSendMessage(sSuback);\n\n\t\t\tEvent* evun = new Event();\n\t\t\tevun->setClientSendEvent(clnode);\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"SUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sSuback));\n\n\t\t\t_res->getClientSendQue()->post(evun);  // Send SUBACK to Client\n\t\t}\n\t\tdelete subscribe;\n\t}\n\tdelete sSubscribe;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnUnsubscribe\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnUnsubscribe(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT2, currentDateTime(), \"UNSUBSCRIBE\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnUnsubscribe* sUnsubscribe = new MQTTSnUnsubscribe();\n\tMQTTUnsubscribe* unsubscribe = new MQTTUnsubscribe();\n\tsUnsubscribe->absorb(msg);\n\n\tuint8_t topicIdType = sUnsubscribe->getFlags() & 0x03;\n\n\tunsubscribe->setMessageId(sUnsubscribe->getMsgId());\n\n\tif(topicIdType != MQTTSN_FLAG_TOPICID_TYPE_RESV){\n\n\t\tif(topicIdType == MQTTSN_FLAG_TOPICID_TYPE_SHORT){\n\t\t\tunsubscribe->setTopicName(sUnsubscribe->getTopicName()); // TopicName\n\n\t\t}else if(clnode->getTopics()->getTopic(sUnsubscribe->getTopicId())){\n\n\t\t\tif(topicIdType == MQTTSN_FLAG_TOPICID_TYPE_PREDEFINED) goto uslbl1;\n\n\t\t\tunsubscribe->setTopicName(sUnsubscribe->getTopicName());\n\t\t}\n\n\t\tclnode->setBrokerSendMessage(unsubscribe);\n\n\t\tEvent* ev1 = new Event();\n\t\tev1->setBrokerSendEvent(clnode);\n\t\t_res->getBrokerSendQue()->post(ev1);    //  UNSUBSCRIBE to Broker\n\t\tdelete sUnsubscribe;\n\t\treturn;\n\t}\n\n\t/*-- Irregular TopicIdType or MQTTSN_FLAG_TOPICID_TYPE_PREDEFINED --*/\nuslbl1:\n\tif(sUnsubscribe->getMsgId()){\n\t\tMQTTSnUnsubAck* sUnsuback = new MQTTSnUnsubAck();\n\t\tsUnsuback->setMsgId(sUnsubscribe->getMsgId());\n\n\t\tclnode->setClientSendMessage(sUnsuback);\n\n\t\tEvent* evun = new Event();\n\t\tevun->setClientSendEvent(clnode);\n\t\tLOGWRITE(FORMAT1, currentDateTime(), \"UNSUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(sUnsuback));\n\n\t\t_res->getClientSendQue()->post(evun);  // Send UNSUBACK to Client\n\t}\n\n\tdelete sUnsubscribe;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnPingReq\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPingReq(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT2, currentDateTime(), \"PINGREQ\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTPingReq* pingReq = new MQTTPingReq();\n\n\tclnode->setBrokerSendMessage(pingReq);\n\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnPubAck\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPubAck(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBACK\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnPubAck* sPubAck = new MQTTSnPubAck();\n\tMQTTPubAck* pubAck = new MQTTPubAck();\n\tsPubAck->absorb(msg);\n\n\tpubAck->setMessageId(sPubAck->getMsgId());\n\n\tclnode->setBrokerSendMessage(pubAck);\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n\tdelete sPubAck;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnPubRec\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPubRec(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBREC\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnPubRec* sPubRec = new MQTTSnPubRec();\n\tMQTTPubRec* pubRec = new MQTTPubRec();\n\tsPubRec->absorb(msg);\n\n\tpubRec->setMessageId(sPubRec->getMsgId());\n\n\tclnode->setBrokerSendMessage(pubRec);\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n\tdelete sPubRec;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnPubRel\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPubRel(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBREL\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnPubRel* sPubRel = new MQTTSnPubRel();\n\tMQTTPubRel* pubRel = new MQTTPubRel();\n\tsPubRel->absorb(msg);\n\n\tpubRel->setMessageId(sPubRel->getMsgId());\n\n\tclnode->setBrokerSendMessage(pubRel);\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n\tdelete sPubRel;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnPubComp\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnPubComp(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBREL\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnPubComp* sPubComp= new MQTTSnPubComp();\n\tMQTTPubComp* pubComp = new MQTTPubComp();\n\tsPubComp->absorb(msg);\n\n\tpubComp->setMessageId(sPubComp->getMsgId());\n\n\tclnode->setBrokerSendMessage(pubComp);\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n\tdelete sPubComp;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnConnect\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnConnect(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT2, currentDateTime(), \"CONNECT\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\tMQTTConnect* mqMsg = 0;\n\tTopics* topics = clnode->getTopics();\n\tMQTTSnConnect* sConnect = new MQTTSnConnect();\n\tsConnect->absorb(msg);\n\n\tif (!_res->getClientList()->isAuthorized()){\n\t\tclnode->setNodeId(sConnect->getClientId());\n\t}\n\n\tif(clnode->isConnectSendable()){\n\t\tmqMsg = new MQTTConnect();\n\n\t\tmqMsg->setProtocol(_protocol);\n\t\tmqMsg->setClientId(clnode->getNodeId());\n\t\tmqMsg->setKeepAliveTime(sConnect->getDuration());\n\n\t\tif(_loginId != \"\" && _password != \"\"){\n\t\t\tmqMsg->setUserName(&_loginId);\n\t\t\tmqMsg->setPassword(&_password);\n\t\t}\n\t\tclnode->setConnectMessage(mqMsg);\n\n\t\tif(sConnect->isCleanSession()){\n\t\t\tif(topics){\n\t\t\t\tdelete topics;\n\t\t\t}\n\t\t\ttopics = new Topics();\n\t\t\tclnode->setTopics(topics);\n\t\t\tmqMsg->setCleanSessionFlg();\n\t\t}\n\t}\n\n\tif(sConnect->isWillRequired()){\n\t\tMQTTSnWillTopicReq* reqTopic = new MQTTSnWillTopicReq();\n\t\tEvent* evwr = new Event();\n\n\t\tclnode->setClientSendMessage(reqTopic);\n\t\tevwr->setClientSendEvent(clnode);\n\t\tLOGWRITE(FORMAT1, currentDateTime(), \"WILLTOPICREQ\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(reqTopic));\n\t\tif(!clnode->isConnectSendable()){\n\t\t\tclnode->setConnAckSaveFlg();\n\t\t}\n\t\t_res->getClientSendQue()->post(evwr);  // Send WILLTOPICREQ to Client\n\t}else{\n\t\tif(clnode->isConnectSendable()){\n\t\t\tclnode->setConnectMessage(0);\n\t\t\tEvent* ev1 = new Event();\n\t\t\tclnode->connectQued();\n\t\t\tclnode->setBrokerSendMessage(mqMsg);\n\t\t\tev1->setBrokerSendEvent(clnode);\n\t\t\t_res->getBrokerSendQue()->post(ev1);\n\t\t}\n\t}\n\tdelete sConnect;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnWillTopic\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnWillTopic(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT1, currentDateTime(), \"WILLTOPIC\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnWillTopic* snMsg = new MQTTSnWillTopic();\n\tMQTTSnWillMsgReq* reqMsg = new MQTTSnWillMsgReq();\n\tsnMsg->absorb(msg);\n\n\tif(clnode->getConnectMessage()){\n\t\tclnode->getConnectMessage()->setWillTopic(snMsg->getWillTopic());\n\t\tclnode->getConnectMessage()->setWillQos(snMsg->getQos());\n\t}\n\n\tclnode->setClientSendMessage(reqMsg);\n\tEvent* evt = new Event();\n\tevt->setClientSendEvent(clnode);\n\tLOGWRITE(FORMAT1, currentDateTime(), \"WILLMSGREQ\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(reqMsg));\n\n\t_res->getClientSendQue()->post(evt);  // Send WILLMSGREQ to Client\n\n\tdelete snMsg;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnWillMsg\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnWillMsg(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT1, currentDateTime(), \"WILLMSG\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnWillMsg* snMsg = new MQTTSnWillMsg();\n\tsnMsg->absorb(msg);\n\n\tif(clnode->getConnectMessage() && clnode->isConnectSendable()){\n\t\tclnode->getConnectMessage()->setWillMessage(snMsg->getWillMsg());\n\t\tclnode->connectQued();\n\t\tclnode->setBrokerSendMessage(clnode->getConnectMessage());\n\t\tclnode->setConnectMessage(0);\n\n\t\tEvent* ev1 = new Event();\n\t\tev1->setBrokerSendEvent(clnode);\n\t\t_res->getBrokerSendQue()->post(ev1);\n\t}else{\n\t\tMQTTSnConnack* connack = 0;\n\n\t\tif(!_secure && _stableNetwork){\n\t\t\tconnack = new MQTTSnConnack();\n\t\t\tconnack->setReturnCode(MQTTSN_RC_REJECTED_CONGESTION);\n\t\t\tclnode->setClientSendMessage(connack);\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t//clnode->connackSended(connack->getReturnCode());\n\t\t\tclnode->disconnected();\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"*CONNACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(connack));\n\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t}else{\n\t\t\tconnack = clnode->checkGetConnAck();\n\t\t\tif(connack != 0){\n\t\t\t\tLOGWRITE(CYAN_FORMAT1, currentDateTime(), \"CONNACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(connack));\n\t\t\t\tEvent* ev1 = new Event();\n\t\t\t\tclnode->setClientSendMessage(connack);\n\t\t\t\tclnode->connackSended(connack->getReturnCode());\n\t\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\t}else if(clnode->isDisconnect() || clnode->isActive()){\n\t\t\t\tconnack = new MQTTSnConnack();\n\t\t\t\tconnack->setReturnCode(MQTTSN_RC_REJECTED_CONGESTION);\n\t\t\t\tclnode->setClientSendMessage(connack);\n\t\t\t\tEvent* ev1 = new Event();\n\t\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t\tclnode->connackSended(connack->getReturnCode());\n\t\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"*CONNACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(connack));\n\t\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\t}\n\t\t}\n\t}\n\tdelete snMsg;\n}\n\n/*-------------------------------------------------------\n                Upstream MQTTSnDisconnect\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnDisconnect(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT2, currentDateTime(), \"DISCONNECT\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnDisconnect* snMsg = new MQTTSnDisconnect();\n\tMQTTDisconnect* mqMsg = new MQTTDisconnect();\n\tsnMsg->absorb(msg);\n\n\tclnode->setBrokerSendMessage(mqMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setBrokerSendEvent(clnode);\n\t_res->getBrokerSendQue()->post(ev1);\n\n\tdelete snMsg;\n}\n\n\n/*-------------------------------------------------------\n                Upstream MQTTSnRegister\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSnRegister(Event* ev, ClientNode* clnode, MQTTSnMessage* msg){\n\n\tLOGWRITE(FORMAT2, currentDateTime(), \"REGISTER\", LEFTARROW, clnode->getNodeId()->c_str(), msgPrint(msg));\n\n\tMQTTSnRegister* snMsg = new MQTTSnRegister();\n\tMQTTSnRegAck* respMsg = new MQTTSnRegAck();\n\tsnMsg->absorb(msg);\n\n\trespMsg->setMsgId(snMsg->getMsgId());\n\n\tuint16_t tpId = clnode->getTopics()->createTopic(snMsg->getTopicName());\n\n\trespMsg->setTopicId(tpId);\n\trespMsg->setReturnCode(MQTTSN_RC_ACCEPTED);\n\n\tclnode->setClientSendMessage(respMsg);\n\n\tEvent* evrg = new Event();\n\tevrg->setClientSendEvent(clnode);\n\tLOGWRITE(FORMAT1, currentDateTime(), \"REGACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(respMsg));\n\n\t_res->getClientSendQue()->post(evrg);\n\n\tdelete snMsg;\n}\n\t\n\n/*=======================================================\n                     Downstream\n ========================================================*/\n\n/*-------------------------------------------------------\n                Downstream MQTTPubAck\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePuback(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTPubAck* mqMsg = static_cast<MQTTPubAck*>(msg);\n\tMQTTSnPubAck* snMsg = clnode->getWaitedPubAck();\n\n\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\tif(snMsg){\n\t\tif(snMsg->getMsgId() == mqMsg->getMessageId()){\n\t\t\tclnode->setWaitedPubAck(0);\n\t\t\tclnode->setClientSendMessage(snMsg);\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t\treturn;\n\t\t}\n\t}\n\tLOGWRITE(\"PUBACK MessageID is not the same as PUBLISH or PUBACK is not expected\\n\");\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTPubRec\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePubRec(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\tMQTTSnPubRec* snMsg = new MQTTSnPubRec();\n\tMQTTPubRec* mqMsg = static_cast<MQTTPubRec*>(msg);\n\tsnMsg->setMsgId(mqMsg->getMessageId());\n\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBREC\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\tclnode->setClientSendMessage(snMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTPubRel\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePubRel(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\tMQTTSnPubRel* snMsg = new MQTTSnPubRel();\n\tMQTTPubRel* mqMsg = static_cast<MQTTPubRel*>(msg);\n\tsnMsg->setMsgId(mqMsg->getMessageId());\n\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBREL\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\tclnode->setClientSendMessage(snMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTPubComp\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePubComp(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\tMQTTSnPubComp* snMsg = new MQTTSnPubComp();\n\tMQTTPubComp* mqMsg = static_cast<MQTTPubComp*>(msg);\n\tsnMsg->setMsgId(mqMsg->getMessageId());\n\tLOGWRITE(BLUE_FORMAT1, currentDateTime(), \"PUBCOMP\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\tclnode->setClientSendMessage(snMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n\n/*-------------------------------------------------------\n                Downstream MQTTPingResp\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePingresp(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTSnPingResp* snMsg = new MQTTSnPingResp();\n\t//MQTTPingResp* mqMsg = static_cast<MQTTPingResp*>(msg);\n\tLOGWRITE(FORMAT1, currentDateTime(), \"PINGRESP\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\tclnode->setClientSendMessage(snMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTSubAck\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleSuback(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTSubAck* mqMsg = static_cast<MQTTSubAck*>(msg);\n\tMQTTSnSubAck* snMsg = clnode->getWaitedSubAck();\n\tif(snMsg){\n\t\tif(snMsg->getMsgId() == mqMsg->getMessageId()){\n\t\t\tclnode->setWaitedSubAck(0);\n\t\t\tif(mqMsg->getGrantedQos() == 0x80){\n\t\t\t\tsnMsg->setReturnCode(MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);\n\t\t\t}else{\n\t\t\t\tsnMsg->setReturnCode(MQTTSN_RC_ACCEPTED);\n\t\t\t\tsnMsg->setQos(mqMsg->getGrantedQos());\n\t\t\t}\n\t\t\tLOGWRITE(FORMAT1, currentDateTime(), \"SUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\t\t\tclnode->setClientSendMessage(snMsg);\n\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t}\n\t}\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTUnsubAck\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleUnsuback(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTUnsubAck* mqMsg = static_cast<MQTTUnsubAck*>(msg);\n\tMQTTSnUnsubAck* snMsg = new MQTTSnUnsubAck();\n\n\tsnMsg->setMsgId(mqMsg->getMessageId());\n\tLOGWRITE(FORMAT1, currentDateTime(), \"UNSUBACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\tclnode->setClientSendMessage(snMsg);\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n\n/*-------------------------------------------------------\n                Downstream MQTTConnAck\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleConnack(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTConnAck* mqMsg = static_cast<MQTTConnAck*>(msg);\n\tMQTTSnConnack* snMsg = new MQTTSnConnack();\n\n\tif(mqMsg->getReturnCd() == 0){\n\t\tsnMsg->setReturnCode(MQTTSN_RC_ACCEPTED);\n\t}else if(mqMsg->getReturnCd() == MQTT_RC_REFUSED_PROTOCOL_VERSION){\n\t\tsnMsg->setReturnCode(MQTTSN_RC_REJECTED_NOT_SUPPORTED);\n\t\t_protocol = (_protocol == MQTT_PROTOCOL_VER4) ? MQTT_PROTOCOL_VER3 : MQTT_PROTOCOL_VER4;\n\t}else if(mqMsg->getReturnCd() == MQTT_RC_REFUSED_SERVER_UNAVAILABLE){\n\t\tsnMsg->setReturnCode(MQTTSN_RC_REJECTED_CONGESTION);\n\t}else{\n\t\tsnMsg->setReturnCode(MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);\n\t}\n\tif( clnode->checkConnAck(snMsg) == 0){\n\t\tLOGWRITE(CYAN_FORMAT1, currentDateTime(), \"CONNACK\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\t\tclnode->connackSended(snMsg->getReturnCode());\n\t\tclnode->setClientSendMessage(snMsg);\n\t\tEvent* ev1 = new Event();\n\t\tev1->setClientSendEvent(clnode);\n\t\t_res->getClientSendQue()->post(ev1);\n\t}\n\n\t// Send saved messages while sleeping\n\tif(clnode->isActive()){\n\t\twhile(clnode->getClientSleepMessage()){\n\t\t\tEvent* ev1 = new Event();\n\t\t\tclnode->setClientSendMessage(clnode->getClientSleepMessage());\n\t\t\tev1->setClientSendEvent(clnode);\n\t\t\t_res->getClientSendQue()->post(ev1);\n\t\t}\n\t}\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTDisconnect\n -------------------------------------------------------*/\nvoid GatewayControlTask::handleDisconnect(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\tMQTTSnDisconnect* snMsg = new MQTTSnDisconnect();\n\t//MQTTDisconnect* mqMsg = static_cast<MQTTDisconnect*>(msg);\n\tclnode->setClientSendMessage(snMsg);\n\tLOGWRITE(FORMAT1, currentDateTime(), \"DISCONNECT\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\tEvent* ev1 = new Event();\n\tev1->setClientSendEvent(clnode);\n\t_res->getClientSendQue()->post(ev1);\n}\n\n/*-------------------------------------------------------\n                Downstream MQTTPublish\n -------------------------------------------------------*/\nvoid GatewayControlTask::handlePublish(Event* ev, ClientNode* clnode, MQTTMessage* msg){\n\n\tMQTTPublish* mqMsg = static_cast<MQTTPublish*>(msg);\n\tMQTTSnPublish* snMsg = new MQTTSnPublish();\n\n\tstring* tp = mqMsg->getTopic();\n\tuint16_t tpId;\n\n\tif(tp->size() == 2){\n\t\ttpId = getUint16((uint8_t*)tp);\n\t\tsnMsg->setFlags(MQTTSN_TOPIC_TYPE_SHORT);\n\t}else{\n\t\ttpId = clnode->getTopics()->getTopicId(tp);\n\t\tsnMsg->setFlags(MQTTSN_TOPIC_TYPE_NORMAL);\n\t}\n\tif(tpId == 0){\n\t\t/* ----- may be a publish message response of subscribed with '#' or '+' -----*/\n\t\ttpId = clnode->getTopics()->createTopic(tp);\n\n\t\tif(tpId > 0){\n\t\t\tMQTTSnRegister* regMsg = new MQTTSnRegister();\n\t\t\tregMsg->setTopicId(tpId);\n\t\t\tregMsg->setTopicName(tp);\n\t\t\tif(clnode->isSleep()){\n\t\t\t\tclnode->setClientSleepMessage(regMsg);\n\t\t\t\tLOGWRITE(FORMAT2, currentDateTime(), \"REGISTER\", RIGHTARROW, clnode->getNodeId()->c_str(), \"is sleeping. Message was saved.\");\n\t\t\t}else if(clnode->isActive()){\n\t\t\t\tLOGWRITE(FORMAT2, currentDateTime(), \"REGISTER\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(regMsg));\n\t\t\t\tif(clnode->isSleep()){\n\t\t\t\t\tclnode->setClientSleepMessage(regMsg);\n\t\t\t\t}\n\t\t\t\tclnode->setClientSendMessage(regMsg);\n\t\t\t\tEvent* evrg = new Event();\n\t\t\t\tevrg->setClientSendEvent(clnode);\n\t\t\t\t_res->getClientSendQue()->post(evrg);   // Send Register first.\n\t\t\t}\n\t\t}else{\n\t\t\tLOGWRITE(\"GatewayControlTask Can't create Topic   %s\\n\", tp->c_str());\n\t\t\treturn;\n\t\t}\n\t}\n\n\tsnMsg->setTopicId(tpId);\n\tsnMsg->setMsgId(mqMsg->getMessageId());\n\tsnMsg->setData(mqMsg->getPayload(),mqMsg->getPayloadLength());\n\tsnMsg->setQos(mqMsg->getQos());\n\n\tif(mqMsg->isDup()){\n\t\tsnMsg->setDup();\n\t}\n\n\tif(mqMsg->isRetain()){\n\t\tsnMsg->setDup();\n\t}\n\n\tif(clnode->isSleep()){\n\t\tclnode->setClientSleepMessage(snMsg);\n\t\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBLISH\", RIGHTARROW, clnode->getNodeId()->c_str(), \"is sleeping. Message was saved.\");\n\t\tif(snMsg->getQos() == MQTTSN_FLAG_QOS_1){\n\t\t\tsnMsg->setQos(MQTTSN_FLAG_QOS_0);\n\t\t\tsnMsg->setMsgId(0);\n\n\t\t\tMQTTPubAck* pubAck = new MQTTPubAck();\n\t\t\tpubAck->setMessageId(mqMsg->getMessageId());\n\n\t\t\tclnode->setBrokerSendMessage(pubAck);\n\t\t\tEvent* ev1 = new Event();\n\t\t\tev1->setBrokerSendEvent(clnode);\n\t\t\t_res->getBrokerSendQue()->post(ev1);\n\t\t}\n\t}else if(clnode->isActive()){\n\t\tclnode->setClientSendMessage(snMsg);\n\t\tLOGWRITE(GREEN_FORMAT1, currentDateTime(), \"PUBLISH\", RIGHTARROW, clnode->getNodeId()->c_str(), msgPrint(snMsg));\n\n\t\tEvent* ev1 = new Event();\n\t\tev1->setClientSendEvent(clnode);\n\t\t_res->getClientSendQue()->post(ev1);\n\t}\n\n}\n\nchar*  GatewayControlTask::msgPrint(MQTTSnMessage* msg){\n\n\tchar* buf = _printBuf;\n\tfor(int i = 0; i < msg->getBodyLength(); i++){\n\t\tsprintf(buf,\" %02X\", *(msg->getBodyPtr() + i));\n\t\tbuf += 3;\n\t}\n\t*buf = 0;\n\treturn _printBuf;\n}\n\nchar*  GatewayControlTask::msgPrint(MQTTMessage* msg){\n\tuint8_t sbuf[512];\n\tchar* buf = _printBuf;\n\tmsg->serialize(sbuf);\n\n\tfor(int i = 0; i < msg->getRemainLength() + msg->getRemainLengthSize(); i++){\n\t\tsprintf(buf, \" %02X\", *( sbuf + i));\n\t\tbuf += 3;\n\t}\n\t*buf = 0;\n\treturn _printBuf;\n}\n\n"
  },
  {
    "path": "Gateway/src/GatewayControlTask.h",
    "content": "/*\n * GatewayControlTask.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef GATEWAYCONTROLTASK_H_\n#define GATEWAYCONTROLTASK_H_\n\n#include \"lib/ZBStack.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"GatewayResourcesProvider.h\"\n\n/*=====================================\n        Class GatewayControlTask\n =====================================*/\nclass GatewayControlTask : public Thread{\n\tMAGIC_WORD_FOR_TASK;\npublic:\n\tGatewayControlTask(GatewayResourcesProvider* res);\n\t~GatewayControlTask();\n\n\tvoid run();\nprivate:\n\tEventQue<Event>* _eventQue;\n\tGatewayResourcesProvider* _res;\n\tchar _printBuf[512];\n\tuint8_t _protocol;\n\tuint8_t _gatewayId;\n\tstring _loginId;\n\tstring _password;\n\tbool _secure;\n\tbool _stableNetwork;\n\n\tvoid handleClientMessage(Event*);\n\tvoid handleBrokerMessage(Event*);\n\n\tvoid handleSnPublish(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnSubscribe(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnUnsubscribe(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnPingReq(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnPubAck(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnConnect(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnWillTopic(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnWillMsg(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnDisconnect(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnRegister(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnPubRec(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnPubRel(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\tvoid handleSnPubComp(Event* ev, ClientNode* clnode, MQTTSnMessage* msg);\n\n\tvoid handlePuback(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handlePingresp(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handleSuback(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handleUnsuback(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handleConnack(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handlePublish(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handleDisconnect(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handlePubRec(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handlePubRel(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tvoid handlePubComp(Event* ev, ClientNode* clnode, MQTTMessage* msg);\n\tchar* msgPrint(MQTTSnMessage* msg);\n\tchar* msgPrint(MQTTMessage* msg);\n};\n\n#endif /* GATEWAYCONTROLTASK_H_ */\n"
  },
  {
    "path": "Gateway/src/GatewayDefines.h",
    "content": "/*\n * GatewayDefines.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef GATEWAYDEFINES_H_\n#define GATEWAYDEFINES_H_\n\n#define GATEWAY_VERSION \"(Ver 1.1.7)\"\n\n#define BROKER      \"Broker\"\n#define GREEN_BROKER \"\\x1b[0m\\x1b[32mBroker\\x1b[0m\\x1b[37m\"\n#define GATEWAY     \"Gateway\"\n#define CLIENT      \"Client\"\n#define LEFTARROW   \"<---\"\n#define RIGHTARROW  \"--->\"\n\n#define FORMAT      \"%s   %-14s%-8s%-44s%s\\n\"\n#define FORMAT1     \"%s   %-14s%-8s%-26s%s\\n\"\n#define FORMAT2     \"\\n%s   %-14s%-8s%-26s%s\\n\"\n\n#define RED_FORMAT1      \"%s   \\x1b[0m\\x1b[31m%-14s%-8s%-44s\\x1b[0m\\x1b[37m%s\\n\"\n#define RED_FORMAT2    \"\\n%s   \\x1b[0m\\x1b[31m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n\n#define GREEN_FORMAT     \"%s   \\x1b[0m\\x1b[32m%-14s%-8s%-44s\\x1b[0m\\x1b[37m%s\\n\"\n#define GREEN_FORMAT1    \"%s   \\x1b[0m\\x1b[32m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n#define GREEN_FORMAT2  \"\\n%s   \\x1b[0m\\x1b[32m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n\n#define YELLOW_FORMAT1   \"%s   \\x1b[0m\\x1b[33m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n#define YELLOW_FORMAT2 \"\\n%s   \\x1b[0m\\x1b[33m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n\n#define BLUE_FORMAT      \"%s   \\x1b[0m\\x1b[34m%-14s%-8s%-44s\\x1b[0m\\x1b[37m%s\\n\"\n#define BLUE_FORMAT1     \"%s   \\x1b[0m\\x1b[34m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n#define BLUE_FORMAT2   \"\\n%s   \\x1b[0m\\x1b[34m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n\n#define CYAN_FORMAT1     \"%s   \\x1b[0m\\x1b[36m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n#define SYAN_FORMAT2   \"\\n%s   \\x1b[0m\\x1b[36m%-14s%-8s%-26s\\x1b[0m\\x1b[37m%s\\n\"\n\n/*===========================================\n *   Gateway Control Constants\n ===========================================*/\n\n#define BROKER_HOST_NAME  \"localhost\"\n#define BROKER_PORT       \"1883\"\n\n\n#define KEEP_ALIVE_TIME   900    // 900 sec = 15 min\n\n#define TIMEOUT_PERIOD     10    //  10 sec = 10 sec\n\n#define SEND_UNIXTIME_TIME 30    // 30sec after KEEP_ALIVE_TIME\n\n\n\n#define MAX_CLIENT_NODES  500\n\n/*==========================================================\n *           Light Indicators\n ===========================================================*/\n\n#define LIGHT_INDICATOR_GREEN   4    // RPi connector 16\n#define LIGHT_INDICATOR_RED     5    // RPi connector 18\n#define LIGHT_INDICATOR_BLUE    6    // RPi connector 22\n\n#endif /* GATEWAYDEFINES_H_ */\n"
  },
  {
    "path": "Gateway/src/GatewayResourcesProvider.cpp",
    "content": "/*\n * GatewayResourcesProvider.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#include \"GatewayResourcesProvider.h\"\n#include \"GatewayDefines.h\"\n#include \"lib/ProcessFramework.h\"\n#include \"ErrorMessage.h\"\n#include <iostream>\n#include <stdio.h>\n#include <string.h>\n#include <string>\n\n#ifdef RASPBERRY_PI\n#include <wiringPi.h>\n#endif\n\nusing namespace std;\n\nextern Process* theProcess;\nextern char* currentDateTime();\nextern void setUint32(uint8_t* pos, uint32_t val);\n\nextern \"C\"{\n\tint wiringPiSetup(void);\n\tvoid pinMode(int gpioNo, int mode);\n\tvoid digitalWrite(int gpioNo, int val);\n}\n\nGatewayResourcesProvider* theGatewayResources = 0;\n\n/*=====================================\n     Class GatewayResourcesProvider\n =====================================*/\nGatewayResourcesProvider::GatewayResourcesProvider(): MultiTaskProcess(){\n\ttheMultiTask = this;\n\ttheProcess = this;\n\tresetRingBuffer();\n\t_lightIndicator.greenLight(false);\n}\n\nGatewayResourcesProvider::~GatewayResourcesProvider(){\n\tLOGWRITE(\"%s TomyGateway stop\\n\", currentDateTime());\n\t_lightIndicator.greenLight(false);\n\t_lightIndicator.redLightOff();\n}\n\nEventQue<Event>* GatewayResourcesProvider::getGatewayEventQue(){\n\treturn &_gatewayEventQue;\n}\n\nEventQue<Event>* GatewayResourcesProvider::getClientSendQue(){\n\treturn &_clientSendQue;\n}\n\nEventQue<Event>* GatewayResourcesProvider::getBrokerSendQue(){\n\treturn &_brokerSendQue;\n}\n\nClientList* GatewayResourcesProvider::getClientList(){\n\treturn &_clientList;\n}\n\nNetwork* GatewayResourcesProvider::getNetwork(){\n\treturn &_network;\n}\n\nLightIndicator* GatewayResourcesProvider::getLightIndicator(){\n\treturn &_lightIndicator;\n}\n\n/*=====================================\n        Class Client\n =====================================*/\nClientNode::ClientNode(){\n\tClientNode(false);\n}\n\nClientNode::ClientNode(bool secure){\n\t_msgId = 0;\n\t_snMsgId = 0;\n\t_status = Cstat_Disconnected;\n\t_keepAliveMsec = 0;\n\t_topics = new Topics();\n\n\t_address64 = NWAddress64();\n\t_nodeId = \"\";\n\t_address16 = 0;\n\n\t_mqttConnect = 0;\n\n\t_waitedPubAck = 0;\n\t_waitedSubAck = 0;\n\tif(secure){\n\t\t_stack = new TLSStack(true);\n\t}else{\n\t\t_stack = new TLSStack(false);\n\t}\n\t_connAckSaveFlg = false;\n\t_connAck = 0;\n\t_waitWillMsgFlg = false;\n}\n\nClientNode::~ClientNode(){\n\tdelete _topics;\n\tif(_mqttConnect){\n\t\tdelete _mqttConnect;\n\t}\n\tif(_waitedPubAck){\n\t\tdelete _waitedPubAck;\n\t}\n\tif(_waitedSubAck){\n\t\tdelete _waitedSubAck;\n\t}\n\tif(_stack){\n\t\tdelete _stack;\n\t}\n}\n\nvoid ClientNode::setWaitedPubAck(MQTTSnPubAck* msg){\n\t_waitedPubAck = msg;\n}\n\nvoid ClientNode::setWaitedSubAck(MQTTSnSubAck* msg){\n\t_waitedSubAck = msg;\n}\n\nMQTTSnPubAck* ClientNode::getWaitedPubAck(){\n\treturn _waitedPubAck;\n}\n\nMQTTSnSubAck* ClientNode::getWaitedSubAck(){\n\treturn _waitedSubAck;\n}\n\nuint16_t ClientNode::getNextMessageId(){\n\t_msgId++;\n\tif (_msgId == 0){\n\t\t_msgId++;\n\t}\n\treturn _msgId;\n}\n\nuint8_t ClientNode::getNextSnMsgId(){\n\t_snMsgId++;\n\t\tif (_snMsgId == 0){\n\t\t\t_snMsgId++;\n\t\t}\n\t\treturn _snMsgId;\n}\n\n\nMQTTMessage* ClientNode::getBrokerSendMessage(){\n\treturn _brokerSendMessageQue.getMessage();\n}\n\nMQTTMessage* ClientNode::getBrokerRecvMessage(){\n\treturn _brokerRecvMessageQue.getMessage();\n}\n\nMQTTSnMessage* ClientNode::getClientSendMessage(){\n\treturn _clientSendMessageQue.getMessage();\n}\n\nMQTTSnMessage* ClientNode::getClientSleepMessage(){\n\treturn _clientSleepMessageQue.getMessage();\n}\n\nMQTTSnMessage* ClientNode::getClientRecvMessage(){\n\treturn _clientRecvMessageQue.getMessage();\n}\n\nMQTTConnect*   ClientNode::getConnectMessage(){\n\treturn _mqttConnect;\n}\n\nTLSStack* ClientNode::getStack(){\n\treturn _stack;\n}\n\n\nvoid ClientNode::setBrokerSendMessage(MQTTMessage* msg){\n\t_brokerSendMessageQue.push(msg);\n}\n\nvoid ClientNode::setBrokerRecvMessage(MQTTMessage* msg){\n\t_brokerRecvMessageQue.push(msg);\n}\n\nvoid ClientNode::setClientSendMessage(MQTTSnMessage* msg){\n\t_clientSendMessageQue.push(msg);\n\n}\n\nvoid ClientNode::setClientRecvMessage(MQTTSnMessage* msg){\n\tupdateStatus(msg);\n\t_clientRecvMessageQue.push(msg);\n}\n\nvoid ClientNode::setClientSleepMessage(MQTTSnMessage* msg){\n\tupdateStatus(msg);\n\t_clientSleepMessageQue.push(msg);\n}\n\nvoid ClientNode::setConnectMessage(MQTTConnect* msg){\n\t_mqttConnect = msg;\n}\n\n\nvoid ClientNode::checkTimeover(){\n\tif(_status == Cstat_Active && _keepAliveTimer.isTimeup()){\n\t\t_status = Cstat_Lost;\n\t\t_stack->disconnect();\n\t}\n}\n\nvoid ClientNode::setKeepAlive(MQTTSnMessage* msg){\n\tMQTTSnConnect* cm = static_cast<MQTTSnConnect*>(msg);\n\t_keepAliveMsec = cm->getDuration() * 1000UL;\n\t_keepAliveTimer.start(_keepAliveMsec * 1.5);\n}\n\nbool ClientNode::isConnectSendable(){\n\tif(_status == Cstat_Connecting || _status == Cstat_TryConnecting){\n\t\treturn false;\n\t}else{\n\t\treturn true;\n\t}\n}\n\nvoid ClientNode::updateStatus(ClientStatus stat){\n\t_status = stat;\n}\n\nvoid ClientNode::connectSended(){\n\tif(_status == Cstat_TryConnecting){\n\t\t_status = Cstat_Connecting;\n\n\t\tif(_mqttConnect){\n\t\t\tdelete _mqttConnect;\n\t\t}\n\t\t_mqttConnect = 0;\n\t}\n}\n\nvoid ClientNode::connectQued(){\n\tif(_status == Cstat_Disconnected || _status == Cstat_Lost){\n\t\t_status = Cstat_TryConnecting;\n\t}\n}\n\nvoid ClientNode::disconnected(){\n\t_status = Cstat_Disconnected;\n\t_connAckSaveFlg = false;\n\t_waitWillMsgFlg = false;\n}\n\nbool ClientNode::isDisconnect(){\n\treturn (_status == Cstat_Disconnected);\n}\n\nbool ClientNode::isActive(){\n\treturn (_status == Cstat_Active);\n}\n\nbool ClientNode::isSleep(){\n\treturn (_status == Cstat_Asleep);\n}\n\nvoid ClientNode::connackSended(int rc){\n\tif(_status == Cstat_Connecting){\n\t\tif(rc == MQTTSN_RC_ACCEPTED){\n\t\t\t_status = Cstat_Active;\n\t\t}else{\n\t\t\tdisconnected();\n\t\t}\n\t}\n}\n\nvoid ClientNode::updateStatus(MQTTSnMessage* msg){\n\tif(((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && \n         msg->getType() == MQTTSN_TYPE_CONNECT){\n\t\tsetKeepAlive(msg);\n\t}else if(_status == Cstat_Active){\n\t\tswitch(msg->getType()){\n\t\tcase MQTTSN_TYPE_PINGREQ:\n\t\tcase MQTTSN_TYPE_PUBLISH:\n\t\tcase MQTTSN_TYPE_SUBSCRIBE:\n\t\tcase MQTTSN_TYPE_UNSUBSCRIBE:\n\t\tcase MQTTSN_TYPE_PUBACK:\n\t\tcase MQTTSN_TYPE_PUBCOMP:\n\t\tcase MQTTSN_TYPE_PUBREL:\n\t\tcase MQTTSN_TYPE_PUBREC:\n\t\t\t _keepAliveTimer.start(_keepAliveMsec * 1.5);\n\t\t\t break;\n\t\tcase MQTTSN_TYPE_DISCONNECT:{\n\t\t\tMQTTSnDisconnect* dcm = static_cast<MQTTSnDisconnect*>(msg);\n\t\t\tif(dcm->getDuration()){\n\t\t\t\t_status = Cstat_Asleep;\n\t\t\t\t_keepAliveMsec = dcm->getDuration() * 1000UL;\n\t\t\t}else{\n\t\t\t\tdisconnected();\n\t\t\t}\n\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\n\t}else if(_status == Cstat_Asleep){\n\t\tif(msg->getType() == MQTTSN_TYPE_CONNECT){\n\t\t\tsetKeepAlive(msg);\n\t\t\t_status = Cstat_Connecting;\n\t\t}else if( msg->getType() == MQTTSN_TYPE_PINGREQ ){\n\t\t\tMQTTSnPingReq* pr = static_cast<MQTTSnPingReq*>(msg);\n\t\t\tif(pr->getClientId()) {\n\t\t\t\t_status = Cstat_Awake;\n\t\t\t}\n\t\t}\n\t}else if(_status == Cstat_Awake){\n\t\tswitch(msg->getType()){\n\t\t\tcase MQTTSN_TYPE_CONNECT:\n\t\t\t\t_status = Cstat_Connecting;\n\t\t\t\tsetKeepAlive(msg);\n\t\t\t\tbreak;\n\t\t\tcase MQTTSN_TYPE_DISCONNECT:\n\t\t\t\tdisconnected();\n\t\t\t\tbreak;\n\t\t\tcase MQTTSN_TYPE_PINGRESP:\n\t\t\t\t_status = Cstat_Asleep;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nint  ClientNode::checkConnAck(MQTTSnConnack* msg){\n\tif(_connAckSaveFlg || _waitWillMsgFlg){\n\t\t_connAck = msg;\n\t\treturn -1;\n\t}else{\n\t\treturn 0;\n\t}\n}\n\nMQTTSnConnack*  ClientNode::checkGetConnAck(){\n\tMQTTSnConnack* connAck = 0;\n\n\tif(!_connAck){\n\t\t_waitWillMsgFlg = true;\n\t}else if(_connAckSaveFlg || _waitWillMsgFlg){\n\t\t_connAckSaveFlg = 0;\n\t\t_waitWillMsgFlg = false;\n\t\tconnAck = _connAck;\n\t\t_connAck = 0;\n\t\treturn connAck;\n\t}\n\treturn 0;\n}\n\nvoid ClientNode::setConnAckSaveFlg(){\n\t_connAckSaveFlg = true;\n\t_connAck = 0;\n}\n\nvoid ClientNode::setWaitWillMsgFlg(){\n\t_waitWillMsgFlg = true;\n}\n\nvoid ClientNode::deleteBrokerSendMessage(){\n\t_brokerSendMessageQue.pop();\n}\n\nvoid ClientNode::deleteBrokerRecvMessage(){\n\t_brokerRecvMessageQue.pop();\n}\n\nvoid ClientNode::deleteClientSendMessage(){\n\t_clientSendMessageQue.pop();\n}\n\nvoid ClientNode::deleteClientRecvMessage(){\n\t_clientRecvMessageQue.pop();\n}\n\nTopics* ClientNode::getTopics(){\n\treturn _topics;\n}\n\n\nNWAddress64* ClientNode::getAddress64Ptr(){\n\treturn &_address64;\n}\n\nuint16_t ClientNode::getAddress16(){\n    return _address16;\n}\n\nstring* ClientNode::getNodeId(){\n    return &_nodeId;\n}\n\nvoid ClientNode::setMsb(uint32_t msb){\n    _address64.setMsb(msb);\n}\n\nvoid ClientNode::setLsb(uint32_t lsb){\n    _address64.setLsb(lsb);\n}\n\nvoid ClientNode::setClientAddress64(NWAddress64* addr){\n\t setMsb(addr->getMsb());\n\t setLsb(addr->getLsb());\n}\n\nvoid ClientNode::setClientAddress16(uint16_t addr){\n    _address16 = addr;\n}\n\nvoid ClientNode::setNodeId(string* id){\n\t_nodeId.assign(*id);\n}\n\nvoid ClientNode::setTopics(Topics* topics){\n\t_topics = topics;\n}\n\n\n/*=====================================\n        Class ClientList\n =====================================*/\nClientList::ClientList(){\n\t_clientVector = new vector<ClientNode*>();\n\t_clientVector->reserve(MAX_CLIENT_NODES);\n\t_clientCnt = 0;\n\t_authorize = false;\n}\n\nClientList::~ClientList(){\n\t_mutex.lock();\n\tvector<ClientNode*>::iterator client = _clientVector->begin();\n\twhile((!_clientVector->empty()) && *client){\n\t\tdelete *client;\n\t\t_clientVector->erase(client);\n\t}\n\t_mutex.unlock();\n}\n\nvoid ClientList::authorize(const char* fname, bool secure){\n\tFILE* fp;\n\tchar buf[258];\n\tsize_t pos;\n\n\tif((fp = fopen(fname, \"r\")) != 0){\n\t\twhile(fgets(buf, 256, fp) != 0){\n\t\t\tstring data = string(buf);\n\t\t\twhile((pos = data.find_first_of(\" 　\\t\\n\")) != string::npos){\n\t\t\t\tdata.erase(pos, 1);\n\t\t\t}\n\t\t\tif(data.empty()){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tpos = data.find_first_of(\",\");\n\t\t\tstring addr = data.substr(0,pos);\n\t\t\tif(addr.size() == 16){\n\t\t\t\tunsigned long msb, lsb;\n\t\t\t\tchar hex[9];\n\t\t\t\tstrncpy(hex,addr.c_str(),8);\n\t\t\t\tmsb = strtoul(hex,0,16);\n\t\t\t\tlsb = strtoul(addr.c_str() + 8,0,16);\n\t\t\t\tNWAddress64 addr64 = NWAddress64(msb, lsb);\n\n\t\t\t\tstring id = data.substr(pos + 1);\n\t\t\t\tcreateNode(secure, &addr64,0,&id);\n\t\t\t}else{\n\t\t\t\tLOGWRITE(\"Invalid address     %s\\n\",data.c_str());\n\t\t\t}\n\t\t}\n\t\tfclose(fp);\n\t\t_authorize = true;\n\t\tLOGWRITE(\"Clients are authorized.\\n\");\n\t}\n}\n\nClientNode* ClientList::createNode(bool secure, NWAddress64* addr64, uint16_t addr16, string* nodeId){\n\tif(_clientCnt < MAX_CLIENT_NODES && !_authorize){\n\t\t_mutex.lock();\n\t\tvector<ClientNode*>::iterator client = _clientVector->begin();\n\t\twhile( client != _clientVector->end()){\n\t\t\tif(((*client)->getAddress64Ptr() == addr64) && ((*client)->getAddress16() == addr16)){\n\t\t\t\treturn 0;\n\t\t\t}else{\n\t\t\t\t++client;\n\t\t\t}\n\t\t}\n\t\tClientNode* node = new ClientNode(secure);\n\t\tnode->setClientAddress64(addr64);\n\t\tnode->setClientAddress16(addr16);\n\t\tif (nodeId){\n\t\t\tnode->setNodeId(nodeId);\n\t\t}\n\t\t_clientVector->push_back(node);\n\t\t_clientCnt++;\n\t\t_mutex.unlock();\n\t\treturn node;\n\t}else{\n\t\treturn getClient(addr64, addr16);\n\t}\n}\n\nvoid ClientList::erase(ClientNode* clnode){\n\n\tuint16_t pos = 0;\n\t_mutex.lock();\n\tvector<ClientNode*>::iterator client = _clientVector->begin();\n\n\twhile( (client != _clientVector->end()) && *client){\n\n\t\tif((*client) == clnode){\n\t\t\tdelete(*client);\n\t\t\t_clientVector->erase(client);\n\t\t\t_clientCnt--;\n\t\t\tfor(; pos < _clientCnt; pos++){\n\t\t\t\t_clientVector[pos] = _clientVector[pos + 1];\n\t\t\t}\n\t\t}else{\n\t\t\t++client;\n\t\t\t++pos;\n\t\t}\n\t}\n\t_mutex.unlock();\n}\n\nClientNode* ClientList::getClient(NWAddress64* addr64, uint16_t addr16){\n\t_mutex.lock();\n\tvector<ClientNode*>::iterator client = _clientVector->begin();\n\twhile( (client != _clientVector->end()) && *client){\n\t\t\tif(*((*client)->getAddress64Ptr()) == *addr64 &&\n\t\t\t\t\t(*client)->getAddress16() == addr16){\n\t\t\t\t_mutex.unlock();\n\t\t\t\treturn *client;\n\t\t\t}else{\n\t\t\t\t++client;\n\t\t\t}\n\t}\n\t_mutex.unlock();\n\treturn 0;\n}\n\nuint16_t ClientList::getClientCount(){\n\treturn _clientCnt;\n}\n\nClientNode* ClientList::operator[](int pos){\n\t_mutex.lock();\n\tClientNode* node = (*_clientVector)[pos];\n\t_mutex.unlock();\n\treturn node;\n}\n\nbool ClientList::isAuthorized(){\n\treturn _authorize;\n}\n\n/*=====================================\n        Class Event\n =====================================*/\nEvent::Event(){\n\t_eventType = Et_NA;\n\t_clientNode = 0;\n\t_mqttSnMessage = 0;\n}\n\nEvent::Event(EventType type){\n\t_eventType = type;\n\t_clientNode = 0;\n\t_mqttSnMessage = 0;\n}\n\nEvent::~Event(){\n\tswitch(_eventType){\n\tcase EtClientRecv:\n\t\tif(_clientNode){\n\t\t\t_clientNode->deleteClientRecvMessage();\n\t\t}\n\t\tbreak;\n\tcase EtClientSend:\n\t\t\tif(_clientNode){\n\t\t\t\t_clientNode->deleteClientSendMessage();\n\t\t\t}\n\t\t\tbreak;\n\tcase EtBrokerRecv:\n\t\t\tif(_clientNode){\n\t\t\t\t_clientNode->deleteBrokerRecvMessage();\n\t\t\t}\n\t\t\tbreak;\n\tcase EtBrokerSend:\n\t\t\tif(_clientNode){\n\t\t\t\t_clientNode->deleteBrokerSendMessage();\n\t\t\t}\n\t\t\tbreak;\n\tcase EtBroadcast:\n\t\tif(_mqttSnMessage){\n\t\t\tdelete _mqttSnMessage;\n\t\t}\n\t\tbreak;\n\tdefault:     // Et_NA, EtTimeout\n\t\tbreak;\n\t}\n}\n\nEventType Event::getEventType(){\n\treturn  _eventType;\n}\n\nvoid Event::setClientSendEvent(ClientNode* client){\n\t_clientNode = client;\n\t_eventType = EtClientSend;\n}\n\nvoid Event::setClientRecvEvent(ClientNode* client){\n\t_clientNode = client;\n\t_eventType = EtClientRecv;\n}\n\nvoid Event::setBrokerSendEvent(ClientNode* client){\n\t_clientNode = client;\n\t_eventType = EtBrokerSend;\n}\n\nvoid Event::setBrokerRecvEvent(ClientNode* client){\n\t_clientNode = client;\n\t_eventType = EtBrokerRecv;\n}\n\nvoid Event::setTimeout(){\n\t_eventType = EtTimeout;\n}\n\nvoid Event::setEvent(MQTTSnMessage* msg){\n\t_mqttSnMessage = msg;\n\t_eventType = EtBroadcast;\n}\n\n\nClientNode* Event::getClientNode(){\n\treturn _clientNode;\n}\n\n\nMQTTSnMessage* Event::getMqttSnMessage(){\n\treturn _mqttSnMessage;\n}\n\n/*=====================================\n        Class LightIndicator\n =====================================*/\nLightIndicator::LightIndicator(){\n\t_gpioAvailable = false;\n\tinit();\n\t_greenStatus = true;\n\t_blueStatus = true;\n\tgreenLight(false);\n\tblueLight(false);\n}\n\nLightIndicator::~LightIndicator(){\n\n}\n\nvoid LightIndicator::init(){\n#ifdef RASPBERRY_PI\n\tif(wiringPiSetup() != -1){\n\t\tpinMode(LIGHT_INDICATOR_GREEN, OUTPUT);\n\t\tpinMode(LIGHT_INDICATOR_RED, OUTPUT);\n\t\tpinMode(LIGHT_INDICATOR_BLUE, OUTPUT);\n\t\t_gpioAvailable = true;\n\t}\n#endif\n}\n\nvoid LightIndicator::greenLight(bool on){\n\tif(on){\n\t\tif(_greenStatus == 0){\n\t\t\t_greenStatus = 1;\n\t\t\t//Turn Green on & turn Red off\n\t\t\tlit(LIGHT_INDICATOR_GREEN, 1);\n\t\t\tlit(LIGHT_INDICATOR_RED, 0);\n\t\t}\n\t}else{\n\t\tif(_greenStatus == 1){\n\t\t\t_greenStatus = 0;\n\t\t\t//Turn Green off & turn Red on\n\t\t\tlit(LIGHT_INDICATOR_GREEN, 0);\n\t\t\tlit(LIGHT_INDICATOR_RED, 1);\n\t\t}\n\t}\n}\n\nvoid LightIndicator::redLightOff(){\n\tlit(LIGHT_INDICATOR_RED, 0);\n}\n\nvoid LightIndicator::blueLight(bool on){\n\tif(on){\n\t\tif(_blueStatus == 0){\n\t\t\t_blueStatus = 1;\n\t\t\tlit(LIGHT_INDICATOR_BLUE, 1);\n\t\t}\n\t}else{\n\t\tif(_blueStatus == 1){\n\t\t\t_blueStatus = 0;\n\t\t\tlit(LIGHT_INDICATOR_BLUE, 0);\n\t\t}\n\t}\n}\n\nvoid LightIndicator::lit(int gpioNo, int onoff){\n#ifdef RASPBERRY_PI\n\tif(_gpioAvailable){\n\t\tdigitalWrite(gpioNo,onoff);\n\t}\n#endif\n}\n"
  },
  {
    "path": "Gateway/src/GatewayResourcesProvider.h",
    "content": "/*\n * GatewayResourcesProvider.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef GATEWAY_RESOURCES_PROVIDER_H_\n#define GATEWAY_RESOURCES_PROVIDER_H_\n\n#include \"lib/ProcessFramework.h\"\n#include \"lib/Messages.h\"\n#include \"lib/Topics.h\"\n#include \"lib/TLSStack.h\"\n\n#define FILE_NAME_CLIENT_LIST \"/usr/local/etc/tomygateway/config/clientList.conf\"\n\n/*=====================================\n        Class MessageQue\n =====================================*/\ntemplate<class T> class MessageQue{\npublic:\n\tMessageQue();\n\t~MessageQue();\n\tT* getMessage();\n\tvoid push(T*);\n\tvoid pop();\n\tvoid clear();\nprivate:\n\tqueue<T*> _que;\n\tMutex  _mutex;\n};\n\n\nenum ClientStatus {\n\tCstat_Disconnected = 0,\n\tCstat_TryConnecting,\n\tCstat_Connecting,\n\tCstat_Active,\n\tCstat_Asleep,\n\tCstat_Awake,\n\tCstat_Lost\n};\n\n/*=====================================\n        Class ClientNode\n =====================================*/\nclass ClientNode{\npublic:\n\tClientNode();\n\tClientNode(bool secure);\n\t~ClientNode();\n\n\tMQTTMessage*   getBrokerSendMessage();\n\tMQTTMessage*   getBrokerRecvMessage();\n\tMQTTSnMessage* getClientSendMessage();\n\tMQTTSnMessage* getClientRecvMessage();\n\tMQTTConnect*   getConnectMessage();\n\tMQTTSnPubAck*  getWaitedPubAck();\n\tMQTTSnSubAck*  getWaitedSubAck();\n\tMQTTSnMessage* getClientSleepMessage();\n\n\tvoid setBrokerSendMessage(MQTTMessage*);\n\tvoid setBrokerRecvMessage(MQTTMessage*);\n\tvoid setClientSendMessage(MQTTSnMessage*);\n\tvoid setClientRecvMessage(MQTTSnMessage*);\n\tvoid setConnectMessage(MQTTConnect*);\n\tvoid setWaitedPubAck(MQTTSnPubAck* msg);\n\tvoid setWaitedSubAck(MQTTSnSubAck* msg);\n\tvoid setClientSleepMessage(MQTTSnMessage*);\n\n\tvoid deleteBrokerSendMessage();\n\tvoid deleteBrokerRecvMessage();\n\tvoid deleteClientSendMessage();\n\tvoid deleteClientRecvMessage();\n\n\tvoid checkTimeover();\n\tvoid updateStatus(MQTTSnMessage*);\n\tvoid updateStatus(ClientStatus);\n\tvoid connectSended();\n\tvoid connackSended(int rc);\n\tvoid connectQued();\n\tvoid disconnected();\n\tbool isConnectSendable();\n\tuint16_t getNextMessageId();\n\tuint8_t getNextSnMsgId();\n\tTopics* getTopics();\n\n\tTLSStack* getStack();\n\tNWAddress64* getAddress64Ptr();\n\tuint16_t  getAddress16();\n\tstring* getNodeId();\n\tvoid setMsb(uint32_t);\n\tvoid setLsb(uint32_t);\n\tvoid setClientAddress16(uint16_t addr);\n\tvoid setClientAddress64(NWAddress64* addr);\n\tvoid setTopics(Topics* topics);\n\tvoid setNodeId(string* id);\n\tint  checkConnAck(MQTTSnConnack* msg);\n\tMQTTSnConnack*  checkGetConnAck();\n\tvoid setConnAckSaveFlg();\n\tvoid setWaitWillMsgFlg();\n\tbool isDisconnect();\n\tbool isActive();\n\tbool isSleep();\n\nprivate:\n\tvoid setKeepAlive(MQTTSnMessage* msg);\n\n\tMessageQue<MQTTMessage>   _brokerSendMessageQue;\n\tMessageQue<MQTTMessage>   _brokerRecvMessageQue;\n\tMessageQue<MQTTSnMessage> _clientSendMessageQue;\n\tMessageQue<MQTTSnMessage> _clientRecvMessageQue;\n\tMessageQue<MQTTSnMessage> _clientSleepMessageQue;\n\n\tMQTTConnect*   _mqttConnect;\n\n\tMQTTSnPubAck*  _waitedPubAck;\n\tMQTTSnSubAck*  _waitedSubAck;\n\n\tuint16_t _msgId;\n\tuint8_t _snMsgId;\n\tTopics* _topics;\n\tClientStatus _status;\n\tuint32_t _keepAliveMsec;\n\tTimer _keepAliveTimer;\n\n\tTLSStack* _stack;\n\n\tNWAddress64 _address64;\n    uint16_t _address16;\n    string _nodeId;\n    bool _connAckSaveFlg;\n    bool _waitWillMsgFlg;\n    MQTTSnConnack*  _connAck;\n\n};\n\n/*=====================================\n        Class ClientList\n =====================================*/\nclass ClientList{\npublic:\n\tClientList();\n\t~ClientList();\n\tvoid authorize(const char* fileName, bool secure);\n\tvoid erase(ClientNode*);\n\tClientNode* getClient(NWAddress64* addr64, uint16_t addr16);\n\tClientNode* createNode(bool secure, NWAddress64* addr64, uint16_t addr16, string* nodeId = 0);\n\tuint16_t getClientCount();\n\tClientNode* operator[](int);\n\tbool isAuthorized();\nprivate:\n\tvector<ClientNode*>*  _clientVector;\n\tMutex _mutex;\n\tuint16_t _clientCnt;\n\tbool _authorize;\n};\n\n/*=====================================\n         Class Event\n  ====================================*/\nenum EventType{\n\tEt_NA = 0,\n\tEtTimeout,\n\n\tEtBrokerSend,\n\tEtBrokerRecv,\n\tEtClientSend,\n\tEtClientRecv,\n\tEtBroadcast,\n\tEtSocketAlive\n};\n\nclass Event{\npublic:\n\tEvent();\n\tEvent(EventType);\n\t~Event();\n\tEventType getEventType();\n\tvoid setClientSendEvent(ClientNode*);\n\tvoid setBrokerSendEvent(ClientNode*);\n\tvoid setClientRecvEvent(ClientNode*);\n\tvoid setBrokerRecvEvent(ClientNode*);\n\tvoid setEvent(MQTTSnMessage*);\n\tvoid setTimeout();\n\tClientNode* getClientNode();\n\tMQTTSnMessage* getMqttSnMessage();\nprivate:\n\tEventType   _eventType;\n\tClientNode* _clientNode;\n\tMQTTSnMessage* _mqttSnMessage;\n};\n\n/*=====================================\n     Class LightIndicator\n =====================================*/\nclass LightIndicator{\npublic:\n\tLightIndicator();\n\t~LightIndicator();\n\tvoid greenLight(bool);\n\tvoid blueLight(bool);\n\tvoid redLightOff();\nprivate:\n\tvoid init();\n\tvoid lit(int gpioNo, int onoff);\n\tbool _greenStatus;\n\tbool _blueStatus;\n\tbool _gpioAvailable;\n};\n\n/*=====================================\n     Class GatewayResourcesProvider\n =====================================*/\nclass GatewayResourcesProvider: public MultiTaskProcess{\npublic:\n\tGatewayResourcesProvider();\n\t~GatewayResourcesProvider();\n\n\tEventQue<Event>* getGatewayEventQue();\n\tEventQue<Event>* getClientSendQue();\n\tEventQue<Event>* getBrokerSendQue();\n\tClientList* getClientList();\n\tNetwork* getNetwork();\n\tLightIndicator* getLightIndicator();\nprivate:\n\tClientList _clientList;\n\tEventQue<Event> _gatewayEventQue;\n\tEventQue<Event> _brokerSendQue;\n\tEventQue<Event> _clientSendQue;\n\tNetwork _network;\n\tLightIndicator _lightIndicator;\n};\n\n\n\n/*=====================================\n    Class MessageQue Implementation\n =====================================*/\ntemplate<class T> MessageQue<T>::MessageQue(){\n\n}\n\ntemplate<class T> MessageQue<T>::~MessageQue(){\n\tclear();\n}\n\ntemplate<class T> T* MessageQue<T>::getMessage(){\n\tT* msg;\n\tif(!_que.empty()){\n\t\t_mutex.lock();\n\t\tmsg = _que.front();\n\t\t_mutex.unlock();\n\t\treturn msg;\n\t}else{\n\t\treturn 0;\n\t}\n}\n\ntemplate<class T> void MessageQue<T>::push(T* msg){\n\t_mutex.lock();\n\t_que.push(msg);\n\t_mutex.unlock();\n}\n\ntemplate<class T> void MessageQue<T>::pop(){\n\tif(!_que.empty()){\n\t\t_mutex.lock();\n\t\tdelete _que.front();\n\t\t_que.pop();\n\t\t_mutex.unlock();\n\t}\n}\n\ntemplate<class T> void MessageQue<T>::clear(){\n\t_mutex.lock();\n\twhile(!_que.empty()){\n\t\tdelete _que.front();\n\t\t_que.pop();\n\t}\n\t_mutex.unlock();\n}\n\n#endif /* GATEWAY_RESOURCES_PROVIDER_H_ */\n"
  },
  {
    "path": "Gateway/src/TomyGateway.cpp",
    "content": "/*\n * A_ProgramStructure.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"GatewayResourcesProvider.h\"\n#include \"ClientRecvTask.h\"\n#include \"ClientSendTask.h\"\n#include \"BrokerRecvTask.h\"\n#include \"BrokerSendTask.h\"\n#include \"GatewayControlTask.h\"\n#include \"lib/ProcessFramework.h\"\n\nconst char* theCmdlineParameter = \"b:d:i:h:p:g:u:l:w:k:\";\n\n/**************************************\n *       Gateway Application\n **************************************/\n\nGatewayResourcesProvider gwR = GatewayResourcesProvider();\n\nGatewayControlTask th0 = GatewayControlTask(&gwR);\nClientRecvTask th1 = ClientRecvTask(&gwR);\nClientSendTask th2 = ClientSendTask(&gwR);\nBrokerRecvTask th3 = BrokerRecvTask(&gwR);\nBrokerSendTask th4 = BrokerSendTask(&gwR);\n"
  },
  {
    "path": "Gateway/src/lib/Defines.h",
    "content": "/*\n *   Defines.h\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef  DEFINES_H_\n#define  DEFINES_H_\n\n/*=================================\n *    Network  Selection\n =================================*/\n\n#if ! defined(NETWORK_UDP) && ! defined (NETWORK_XXXXX)\n#define NETWORK_XBEE\n#define GATEWAY_NETWORK  \"Network is XBee.\"\n#endif\n\n#ifdef NETWORK_UDP\n#define GATEWAY_NETWORK  \"Network is UDP.\"\n#endif\n\n#ifdef NETWORK_XXXXX\n#define GATEWAY_NETWORK  \"Network is XXXXX.\"\n#endif\n/*=================================\n *    CPU TYPE\n ==================================*/\n#define CPU_LITTLEENDIANN\n//#define CPU_BIGENDIANN\n\n/*=================================\n *    Debug LOG\n ==================================*/\n//#define DEBUG_NWSTACK\n\n/*=================================\n      Debug Print functions\n ==================================*/\n#ifdef  DEBUG_NWSTACK\n  #define D_NWSTACK(...)  printf(__VA_ARGS__)\n#else\n  #define D_NWSTACK(...)\n#endif\n\n/*=================================\n *    Data Type\n ==================================*/\ntypedef unsigned char  uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int   uint32_t;\n\n\ntypedef struct {\n\tlong baudrate;\n\tchar* device;\n\tunsigned int flag;\n}XBeeConfig;\n\ntypedef struct {\n\tchar* ipAddress;\n\tuint16_t gPortNo;\n\tuint16_t uPortNo;\n}UdpConfig;\n\ntypedef struct {\n\tuint8_t  param1;\n\tuint16_t param2;\n\tuint16_t param3;\n}XXXXXConfig;\n\n#ifdef NETWORK_XBEE\n#define NETWORK_CONFIG  XBeeConfig\n#endif\n\n#ifdef NETWORK_UDP\n#define NETWORK_CONFIG UdpConfig\n#endif\n\n#ifdef NETWORK_XXXXX\n#define NETWORK_CONFIG XXXXXConfig\n#endif\n\n#endif  /*  DEFINES_H_  */\n"
  },
  {
    "path": "Gateway/src/lib/Messages.cpp",
    "content": "/*\n * Messages.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n#include \"ZBStack.h\"\n#include \"UDPStack.h\"\n#include \"ProcessFramework.h\"\n#include \"Messages.h\"\n\n#include <string>\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n\nextern uint16_t getUint16(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\nextern uint8_t* mqcalloc(uint8_t length);\nextern void utfSerialize(uint8_t* pos, string str);\n\nusing namespace tomyGateway;\n\nbool isUtf8Valid(string& string)\n{\n    int c,i,ix,n,j;\n    for (i=0, ix=string.length(); i < ix; i++)\n    {\n        c = (uint8_t) string[i];\n        if (0x00 <= c && c <= 0x7f){\n        \tn=0; // 0bbbbbbb\n        }else if ((c & 0xE0) == 0xC0){\n        \tn=1; // 110bbbbb\n        }else if ( c==0xed && i<(ix-1) && ((uint8_t)string[i+1] & 0xa0)==0xa0){\n        \treturn false; //U+D800 to U+DFFF\n        }else if ((c & 0xF0) == 0xE0){\n        \tn=2; // 1110bbbb\n        }else if ((c & 0xF8) == 0xF0){\n        \tn=3; // 11110bbb\n        }else{\n        \treturn false;\n        }\n        for (j=0; j<n && i<ix; j++) {\n            if ((++i == ix) || (( (uint8_t)string[i] & 0xC0) != 0x80))\n                return false;\n        }\n    }\n    return true;\n}\n\n\n/*=====================================\n        Class MQTTSnMessage\n ======================================*/\nMQTTSnMessage::MQTTSnMessage(){\n    _message = 0;\n    _length = 0;\n    _type = 0;\n}\n\nMQTTSnMessage::~MQTTSnMessage(){\n    if (_message){\n        free(_message);\n    }\n}\n\nvoid MQTTSnMessage::setType(uint8_t type){\n    _type = type;\n}\n\nvoid MQTTSnMessage::setMessageLength(uint16_t length){\n    _length = length;\n}\n\nvoid MQTTSnMessage::setBody(uint8_t* body, uint16_t bodyLength){\n\tif(_length > 255){\n\t\t_length = bodyLength + 4;\n\t}else{\n\t\t_length = bodyLength + MQTTSN_HEADER_SIZE;\n\t}\n    allocate();\n\tmemcpy(getBodyPtr(), body, bodyLength);\n}\n\nvoid MQTTSnMessage::allocate(){\n\t\tif ( _length ) {\n\t\t\tif (_message){\n\t\t\t\t  free(_message);\n\t\t\t}\n\t\t\t_message = mqcalloc(_length);\n\t\t\tif(_length > 255){\n\t\t\t\t*_message = 0x01;\n\t\t\t\tsetUint32(_message + 1, _length);\n\t\t\t\t*(_message + 3) = _type;\n\t\t\t}else{\n\t\t\t\t*_message = _length;\n\t\t\t\t*(_message + 1) = _type;\n\t\t\t}\n\t\t}\n}\n\nuint16_t MQTTSnMessage::getMessageLength(){\n    return _length;\n}\n\nuint8_t MQTTSnMessage::getType(){\n    return _type;\n}\n\nuint8_t* MQTTSnMessage::getBodyPtr(){\n\tif( _length > 255){\n\t\treturn _message + 4;\n\t}else{\n\t\treturn _message + MQTTSN_HEADER_SIZE;\n\t}\n}\n\nuint16_t MQTTSnMessage::getBodyLength(){\n\tif(_length > 255){\n\t\treturn _length - 4;\n\t}else{\n\t\treturn _length - MQTTSN_HEADER_SIZE;\n\t}\n}\n\nbool MQTTSnMessage::getMessage(uint16_t pos, uint8_t& val){\n\tif(pos < 0 || pos >= _length){\n\t\treturn false;\n\t}else{\n\t\tval = *(getMessagePtr() + pos);\n\t\treturn true;\n\t}\n}\n\nuint8_t* MQTTSnMessage::getMessagePtr(){\n\treturn _message;\n}\n\nvoid MQTTSnMessage::absorb(MQTTSnMessage* src){\n    setMessageLength(src->getMessageLength());\n    setType(src->getType());\n    allocate();\n    memcpy(getBodyPtr(), src->getBodyPtr(), (size_t)src->getBodyLength());\n}\n\nvoid MQTTSnMessage::absorb(NWResponse* src){\n\tsetMessageLength(src->getPayloadLength());\n\tsetType(src->getMsgType());\n\tallocate();\n\tmemcpy(_message,src->getPayloadPtr(), (size_t)src->getPayloadLength());\n}\n\n\n/*=====================================\n        Class MQTTSnAdvertise\n ======================================*/\nMQTTSnAdvertise::MQTTSnAdvertise():MQTTSnMessage(){\n    setMessageLength(5);\n    setType(MQTTSN_TYPE_ADVERTISE);\n    allocate();\n}\n\nMQTTSnAdvertise::~MQTTSnAdvertise(){\n\n}\n\nvoid MQTTSnAdvertise::setGwId(uint8_t id){\n    getBodyPtr()[0] = id;\n}\n\nvoid MQTTSnAdvertise::setDuration(uint16_t sec){\n    uint8_t* pos = getBodyPtr() + 1;\n    setUint16(pos, sec);\n}\n\nuint8_t MQTTSnAdvertise::getGwId(){\n    return getBodyPtr()[0];\n}\n\nuint16_t MQTTSnAdvertise::getDuration(){\n  uint8_t* pos = getBodyPtr() + 1;\n    return getUint16(pos);\n}\n\n/*=====================================\n        Class MQTTSnSearchGw\n ======================================*/\nMQTTSnSearchGw::MQTTSnSearchGw(){\n    setMessageLength(3);\n    setType(MQTTSN_TYPE_SEARCHGW);\n    allocate();\n}\n\nMQTTSnSearchGw::~MQTTSnSearchGw(){\n\n}\n\nvoid MQTTSnSearchGw::setRadius(uint8_t radius){\n  getBodyPtr()[0] = radius;\n}\n\nuint8_t MQTTSnSearchGw::getRadius(){\n  return getBodyPtr()[0];\n}\n\nvoid MQTTSnSearchGw::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n        Class MQTTSnGwInfo\n ======================================*/\nMQTTSnGwInfo::MQTTSnGwInfo(){\n  setMessageLength(3);\n  setType(MQTTSN_TYPE_GWINFO);\n  allocate();\n}\n\nMQTTSnGwInfo::~MQTTSnGwInfo(){\n\n}\n\nuint8_t MQTTSnGwInfo::getGwId(){\n    return getBodyPtr()[0];\n}\n\nvoid MQTTSnGwInfo::setGwId(uint8_t id){\n    getBodyPtr()[0] = id;\n}\n\n/*=====================================\n         Class MQTTSnConnect\n  ======================================*/\nMQTTSnConnect::MQTTSnConnect(){\n    setMessageLength(6);\n    allocate();\n    setType(MQTTSN_TYPE_CONNECT);\n    getBodyPtr()[1] = MQTTSN_PROTOCOL_ID;\n}\n\nMQTTSnConnect::MQTTSnConnect(string* id){\n    setMessageLength(id->size() + 6);\n    allocate();\n    setType(MQTTSN_TYPE_CONNECT);\n    getBodyPtr()[1] = MQTTSN_PROTOCOL_ID;\n    id->copy((char*)getBodyPtr() + 4,id->size(),0);\n}\n\nMQTTSnConnect::~MQTTSnConnect(){\n\n}\n\nvoid MQTTSnConnect::setFlags(uint8_t flg){\n    getBodyPtr()[0] = flg & 0x0c;\n}\n\nuint8_t MQTTSnConnect::getFlags(){\n    return getBodyPtr()[0];\n}\n\nbool MQTTSnConnect::isCleanSession(){\n\treturn getBodyPtr()[0] & MQTTSN_FLAG_CLEAN;\n}\n\nbool MQTTSnConnect::isWillRequired(){\n\treturn getBodyPtr()[0] & MQTTSN_FLAG_WILL;\n}\n\nvoid MQTTSnConnect::setDuration(uint16_t sec){\n    setUint16((uint8_t*)getBodyPtr() + 2, sec);\n}\n\nuint16_t MQTTSnConnect::getDuration(){\n    return getUint16((uint8_t*)getBodyPtr() + 2);\n}\n\nvoid MQTTSnConnect::setClientId(string id){\n\t_clientId = id;\n}\n\nstring* MQTTSnConnect::getClientId(){\n\t_clientId = string((char*)(getBodyPtr() + 4), getMessageLength() - 6 );\n    return &_clientId;\n}\n\nvoid MQTTSnConnect::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnConnect::absorb(MQTTSnMessage* src){\n\tsetMessageLength(src->getMessageLength());\n\tsetClientId(*getClientId());\n\tsetFlags(src->getBodyPtr()[0]);\n\tsetDuration(getUint16(src->getBodyPtr() + 2));\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n        Class MQTTSnConnack\n ======================================*/\nMQTTSnConnack::MQTTSnConnack(){\n    setMessageLength(3);\n    setType(MQTTSN_TYPE_CONNACK);\n    allocate();\n}\n\nMQTTSnConnack::~MQTTSnConnack(){\n\n}\n\nvoid MQTTSnConnack::setReturnCode(uint8_t rc){\n    getBodyPtr()[0] = rc;\n}\n\nuint8_t MQTTSnConnack::getReturnCode(){\n    return getBodyPtr()[0];\n}\n\n/*=====================================\n       Class MQTTSnWillTopicReq\n======================================*/\nMQTTSnWillTopicReq::MQTTSnWillTopicReq(){\n    setMessageLength(2);\n    setType(MQTTSN_TYPE_WILLTOPICREQ);\n    allocate();\n}\n\nMQTTSnWillTopicReq::~MQTTSnWillTopicReq(){\n\n}\n\n/*=====================================\n         Class MQTTSnWillTopic\n  ======================================*/\nMQTTSnWillTopic::MQTTSnWillTopic(){\n    setMessageLength(3);\n    setType(MQTTSN_TYPE_WILLTOPIC);\n    allocate();\n    _flags = 0;\n}\n\nMQTTSnWillTopic::~MQTTSnWillTopic(){\n\n}\n\nvoid MQTTSnWillTopic::setFlags(uint8_t flags){\n    flags &= 0x70;\n    if (_message){\n\t\tgetBodyPtr()[0] = flags;\n    }\n    _flags = flags;\n}\n\nvoid MQTTSnWillTopic::setWillTopic(string* topic){\n    setMessageLength(topic->size() + 3);\n    allocate();\n    topic->copy((char*)getBodyPtr() + 1,topic->size() ,0);\n    _message[2] = _flags;\n    _topicName = *topic;\n}\n\nstring* MQTTSnWillTopic::getWillTopic(){\n\tif (_message){\n\t\treturn &_topicName;\n\t}else{\n\t\treturn 0;\n\t}\n}\n\nbool MQTTSnWillTopic::isWillRequired(){\n    return getBodyPtr()[0] && MQTTSN_FLAG_WILL;\n}\n\nuint8_t MQTTSnWillTopic::getQos(){\n    return (_flags && (MQTTSN_FLAG_QOS_1 | MQTTSN_FLAG_QOS_2)) >> 5;\n}\n\nvoid MQTTSnWillTopic::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnWillTopic::absorb(MQTTSnMessage* src){\n\tsetFlags(src->getBodyPtr()[0]);\n\t_topicName = string((char*)src->getBodyPtr() + 1, src->getMessageLength() - 3);\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n         Class MQTTSnWillMsgReq\n  ======================================*/\nMQTTSnWillMsgReq::MQTTSnWillMsgReq(){\n    setMessageLength(2);\n    setType(MQTTSN_TYPE_WILLMSGREQ);\n    allocate();\n\n}\n\nMQTTSnWillMsgReq::~MQTTSnWillMsgReq(){\n\n}\n\n/*=====================================\n         Class MQTTSnWillMsg\n  ======================================*/\nMQTTSnWillMsg::MQTTSnWillMsg(){\n    setMessageLength(2);\n    setType(MQTTSN_TYPE_WILLMSG);\n    allocate();\n}\n\nMQTTSnWillMsg::~MQTTSnWillMsg(){\n\n}\n\nvoid MQTTSnWillMsg::setWillMsg(string* msg){\n    setMessageLength(2 + msg->size());\n    allocate();\n    msg->copy((char*)getBodyPtr(),msg->size(),0);\n    _willMsg = *msg;\n}\n\nstring* MQTTSnWillMsg::getWillMsg(){\n\treturn &_willMsg;\n}\n\nvoid MQTTSnWillMsg::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnWillMsg::absorb(MQTTSnMessage* src){\n\t_willMsg = string((char*)src->getBodyPtr(), src->getMessageLength() - 2);\n\tMQTTSnMessage::absorb(src);\n}\n/*=====================================\n         Class MQTTSnRegister\n  ======================================*/\nMQTTSnRegister::MQTTSnRegister(){\n    setMessageLength(6);\n    setType(MQTTSN_TYPE_REGISTER);\n    allocate();\n    _topicId = 0;\n    _msgId = 0;\n}\n\nMQTTSnRegister::~MQTTSnRegister(){\n\n}\n\nvoid MQTTSnRegister::setTopicId(uint16_t topicId){\n  if (_message){\n            setUint16(getBodyPtr(), topicId);\n    }\n    _topicId = topicId;\n}\nuint16_t MQTTSnRegister::getTopicId(){\n    return _topicId;\n}\nvoid MQTTSnRegister::setMsgId(uint16_t msgId){\n    if (_message){\n            setUint16(getBodyPtr() + 2, msgId);\n    }\n    _msgId = msgId;\n}\nuint16_t MQTTSnRegister::getMsgId(){\n    return _msgId;\n\n}\nvoid MQTTSnRegister::setTopicName(string* topicName){\n    setMessageLength(6 + topicName->size());\n    allocate();\n    topicName->copy((char*)getBodyPtr() + 4, topicName->size(),0);\n    setTopicId(_topicId);\n    setMsgId(_msgId);\n}\n/*\nvoid MQTTSnRegister::setFrame(uint8_t* data, uint8_t len){\n    //setMessageLength(len + MQTTSN_HEADER_SIZE);\n    //allocate();\n    //memcpy(getBodyPtr(), data, len);\n    _topicId = getUint16(data);\n    _msgId = getUint16(data + 2);\n    _topicName = string((char*)getBodyPtr() + 4, len - 4);\n}\n\nvoid MQTTSnRegister::setFrame(NWResponse* resp){\n    setFrame(resp->getPayloadPtr() + MQTTSN_HEADER_SIZE, resp->getPayloadPtr()[0] - MQTTSN_HEADER_SIZE);\n}\n*/\nstring* MQTTSnRegister::getTopicName(){\n    return &_topicName;\n}\n\nvoid MQTTSnRegister::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnRegister::absorb(MQTTSnMessage* src){\n\t_topicId = getUint16((uint8_t*)(src->getBodyPtr()));\n\t_msgId = getUint16((uint8_t*)(src->getBodyPtr() +2));\n\t_topicName = string((char*)src->getBodyPtr() + 4, src->getMessageLength() - 6);\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n         Class MQTTSnRegAck\n  ======================================*/\nMQTTSnRegAck::MQTTSnRegAck(){\n    setMessageLength(7);\n    setType(MQTTSN_TYPE_REGACK);\n    allocate();\n}\nMQTTSnRegAck::~MQTTSnRegAck(){\n\n}\nvoid MQTTSnRegAck::setTopicId(uint16_t topicId){\n    setUint16((uint8_t*)getBodyPtr(), topicId);\n}\nuint16_t MQTTSnRegAck::getTopicId(){\n    return getUint16((unsigned char*)getBodyPtr());\n}\nvoid MQTTSnRegAck::setMsgId(uint16_t msgId){\n    setUint16(getBodyPtr()+ 2,msgId);\n}\nuint16_t MQTTSnRegAck::getMsgId(){\n    return getUint16((unsigned char*)getBodyPtr()+ 2);\n}\nvoid MQTTSnRegAck::setReturnCode(uint8_t rc){\n    getBodyPtr()[4] = rc;\n}\nuint8_t MQTTSnRegAck::getReturnCode(){\n    return (uint8_t)getBodyPtr()[4];\n}\n\nvoid MQTTSnRegAck::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n         Class MQTTSnPublish\n  ======================================*/\nMQTTSnPublish::MQTTSnPublish(){\n    setMessageLength(7);\n    setType(MQTTSN_TYPE_PUBLISH);\n    allocate();\n    _topicId = 0;\n    _msgId = 0;\n    _flags = 0;\n}\n\nMQTTSnPublish::~MQTTSnPublish(){\n\n}\n\nvoid MQTTSnPublish::setFlags(uint8_t flags){\n    _flags = flags & 0xf3;\n    getBodyPtr()[0] = _flags ;\n}\n\nuint8_t MQTTSnPublish::getFlags(){\n    return _flags;\n}\n\nuint8_t MQTTSnPublish::getTopicType(){\n    return _flags & MQTTSN_TOPIC_TYPE;\n}\n\nuint8_t MQTTSnPublish::getQos(){\n    return ((_flags >> 5) & 0x03);\n}\n\nvoid MQTTSnPublish::setQos(uint8_t qos){\n\t_flags &= 0x9f;\n\tif( qos == 1){\n\t\t_flags |= MQTTSN_FLAG_QOS_1;\n\t}else if( qos == 2){\n\t\t_flags |= MQTTSN_FLAG_QOS_2;\n\t}\n\tsetFlags(_flags);\n}\n\nvoid MQTTSnPublish::setDup(){\n\t_flags |= 0x80;\n\tsetFlags(_flags);\n}\n\nvoid MQTTSnPublish::setRetain(){\n\t_flags |= 0x10;\n\tsetFlags(_flags);\n}\n\nvoid MQTTSnPublish::setTopicIdType(uint8_t type){\n\tswitch(type){\n\tcase 0:\n\t\t_flags &= 0x9f;\n\t\tbreak;\n\tcase 1:\n\t\t_flags &= 0x9f;\n\t\t_flags |= 0x01;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tsetFlags(_flags);\n}\n\nvoid MQTTSnPublish::setTopicId(uint16_t id){\n    setUint16((uint8_t*)(getBodyPtr() + 1), id);\n    _topicId = id;\n}\n\nvoid MQTTSnPublish::setTopic(string* topic){\n   topic->copy((char*)(getBodyPtr() + 1), 2);\n   _topicId = getUint16((uint8_t*)(getBodyPtr() + 1));\n}\n\nstring* MQTTSnPublish::getTopic(string* str){\n\tchar tp[3];\n\ttp[0] = (char)*(getBodyPtr() + 1);\n\ttp[1] = (char)*(getBodyPtr() + 2);\n\ttp[2] = 0;\n\tstr->copy(tp,2);\n\treturn str;\n}\n\nuint16_t MQTTSnPublish::getTopicId(){\n    return _topicId;\n}\n\nvoid MQTTSnPublish::setMsgId(uint16_t msgId){\n    setUint16((uint8_t*)(getBodyPtr() + 3), msgId);\n    _msgId = msgId;\n}\n\nuint16_t MQTTSnPublish::getMsgId(){\n    return _msgId;\n}\n\n\nvoid MQTTSnPublish::setData(uint8_t* data, uint8_t len){\n    setMessageLength(7 + len);\n    allocate();\n    memcpy(getBodyPtr() + 5, data, len);\n    setTopicId(_topicId);\n    setMsgId(_msgId);\n    setFlags(_flags);\n}\n\nuint8_t*  MQTTSnPublish::getData(){\n    return (uint8_t*)(getBodyPtr() + 5);\n}\n\nuint16_t  MQTTSnPublish::getDataLength(){\n\treturn getBodyLength() -5;\n}\n\n/*\nvoid MQTTSnPublish::setFrame(uint8_t* data, uint8_t len){\n    setMessageLength(len + MQTTSN_HEADER_SIZE);\n    allocate();\n    memcpy(getBodyPtr(), data, len);\n    _topicId = getUint16(data + 1);\n    _msgId = getUint16(data + 3);\n    _flags = *data;\n}\n\n\nvoid MQTTSnPublish::setFrame(NWResponse* resp){\n    setFrame(resp->getPayloadPtr() + MQTTSN_HEADER_SIZE, resp->getPayloadPtr()[0] - MQTTSN_HEADER_SIZE);\n}\n*/\nvoid MQTTSnPublish::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnPublish::absorb(MQTTSnMessage* src){\n\t_msgId = getUint16((uint8_t*)(src->getBodyPtr() + 3));\n\t_flags = src->getBodyPtr()[0];\n\t_topicId = getUint16((uint8_t*)(src->getBodyPtr() + 1));\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n         Class MQTTSnPubAck\n ======================================*/\nMQTTSnPubAck::MQTTSnPubAck(){\n\t_topicId = 0;\n\t_msgId = 0;\n\t_returnCode = 0;\n    setMessageLength(7);\n    setType(MQTTSN_TYPE_PUBACK);\n    allocate();\n}\nMQTTSnPubAck::~MQTTSnPubAck(){\n\n}\nvoid MQTTSnPubAck::setTopicId(uint16_t topicId){\n    setUint16((uint8_t*)getBodyPtr(), topicId);\n}\nuint16_t MQTTSnPubAck::getTopicId(){\n    return getUint16((unsigned char*)getBodyPtr());\n}\nvoid MQTTSnPubAck::setMsgId(uint16_t msgId){\n    setUint16(getBodyPtr()+ 2,msgId);\n}\nuint16_t MQTTSnPubAck::getMsgId(){\n    return getUint16((unsigned char*)getBodyPtr()+ 2);\n}\nvoid MQTTSnPubAck::setReturnCode(uint8_t rc){\n    getBodyPtr()[4] = rc;\n}\nuint8_t MQTTSnPubAck::getReturnCode(){\n    return (uint8_t)getBodyPtr()[4];\n}\n\nvoid MQTTSnPubAck::absorb(MQTTSnMessage* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnPubAck::absorb(NWResponse* resp){\n\tMQTTSnMessage::absorb(resp);\n}\n\n/*=====================================\n         Class MQTTSnPubRec\n ======================================*/\nMQTTSnPubRec::MQTTSnPubRec(){\n\t_msgId = 0;\n    setMessageLength(4);\n    setType(MQTTSN_TYPE_PUBREC);\n    allocate();\n}\n\nMQTTSnPubRec::~MQTTSnPubRec(){\n\n}\n\nvoid MQTTSnPubRec::setMsgId(uint16_t msgId){\n    setUint16(getBodyPtr(),msgId);\n}\n\nuint16_t MQTTSnPubRec::getMsgId(){\n    return getUint16((unsigned char*)getBodyPtr());\n}\n/*\nvoid MQTTSnPubRec::absorb(NWResponse* resp){\n\tMQTTSnMessage::absorb(resp);\n}*/\n\n/*=====================================\n         Class MQTTSnPubRel\n ======================================*/\nMQTTSnPubRel::MQTTSnPubRel(){\n\t_msgId = 0;\n    setMessageLength(4);\n    setType(MQTTSN_TYPE_PUBREL);\n    allocate();\n}\n\nMQTTSnPubRel::~MQTTSnPubRel(){\n\n}\n\n/*=====================================\n         Class MQTTSnPubComp\n ======================================*/\nMQTTSnPubComp::MQTTSnPubComp(){\n\t_msgId = 0;\n    setMessageLength(4);\n    setType(MQTTSN_TYPE_PUBCOMP);\n    allocate();\n}\n\nMQTTSnPubComp::~MQTTSnPubComp(){\n\n}\n\n /*=====================================\n         Class MQTTSnSubscribe\n  ======================================*/\nMQTTSnSubscribe::MQTTSnSubscribe(){\n    setMessageLength(5);\n    setType(MQTTSN_TYPE_SUBSCRIBE);\n    allocate();\n    _topicId = 0;\n    _msgId = 0;\n    _flags = 0;\n}\n\nMQTTSnSubscribe::~MQTTSnSubscribe(){\n\n}\n\nvoid MQTTSnSubscribe::setFlags(uint8_t flags){\n    _flags = flags & 0xe3;\n    if (_message){\n\t\t  getBodyPtr()[0] = _flags;\n    }\n}\n\nuint8_t MQTTSnSubscribe::getFlags(){\n    return _flags;\n}\n\nuint8_t MQTTSnSubscribe::getQos(){\n    return ((_flags >> 5) & 0x03);\n}\n\nvoid MQTTSnSubscribe::setQos(uint8_t qos){\n\t_flags &= 0x9f;\n\tif(qos == 1){\n\t\t_flags |= MQTTSN_FLAG_QOS_1;\n\t}\n\tsetFlags(_flags);\n}\n\nvoid MQTTSnSubscribe::setTopicId(uint16_t predefinedId){\n    setMessageLength(7);\n    allocate();\n    setMsgId(_msgId);\n    setUint16((uint8_t*)(getBodyPtr() + 3), predefinedId);\n    setFlags(_flags | MQTTSN_TOPIC_TYPE_PREDEFINED);\n    _topicId = predefinedId;\n}\n\nuint16_t MQTTSnSubscribe::getTopicId(){\n    if (_message){\n        _topicId = getUint16(getBodyPtr() +3);\n    }\n    return _topicId;\n}\nvoid MQTTSnSubscribe::setMsgId(uint16_t msgId){\n    _msgId = msgId;\n    if (_message){\n       setUint16((uint8_t*)(getBodyPtr() + 1), msgId);\n    }\n}\n\nuint16_t MQTTSnSubscribe::getMsgId(){\n    if (_message){\n        _msgId = getUint16(getBodyPtr() + 1);\n    }\n    return _msgId;\n}\nvoid MQTTSnSubscribe::setTopicName(string* data){\n    setMessageLength(5 + data->size());\n    allocate();\n    data->copy((char*)getBodyPtr() + 3, data->size(),0);\n    setMsgId(_msgId);\n    setFlags(_flags | MQTTSN_TOPIC_TYPE_NORMAL);\n    _topicName = *data;\n}\n\n\nstring*  MQTTSnSubscribe::getTopicName(){\n    return &_topicName;\n}\n\n/*\nvoid MQTTSnSubscribe::setFrame(uint8_t* data, uint8_t len){\n    setMessageLength(len + MQTTSN_HEADER_SIZE);\n    allocate();\n    memcpy(getBodyPtr(), data, len);\n    _msgId = getUint16(data + 1);\n    _flags = *data;\n    if ((_flags & MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_NORMAL){\n        _topicId = 0;\n        _topicName = string((char*)data + 3, len);\n    }else{\n        _topicId = getUint16(data + 3);\n    }\n}\n\nvoid MQTTSnSubscribe::setFrame(NWResponse* resp){\n    setFrame(resp->getPayloadPtr() + MQTTSN_HEADER_SIZE, resp->getPayloadPtr()[0] - MQTTSN_HEADER_SIZE);\n}\n*/\nvoid MQTTSnSubscribe::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnSubscribe::absorb(MQTTSnMessage* src){\n\t_msgId = getUint16((uint8_t*)(src->getBodyPtr() +1));\n\t_flags = src->getBodyPtr()[0];\n\tif((_flags & MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_SHORT ){\n\t\t_topicName = string((char*)src->getBodyPtr() + 3, src->getMessageLength() - 5);\n\t}else if((_flags & MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_NORMAL){\n\t\t_topicName = string((char*)src->getBodyPtr() + 3, src->getMessageLength() - 5);\n\t}else if((_flags & MQTTSN_TOPIC_TYPE) == MQTTSN_TOPIC_TYPE_PREDEFINED){\n\t\t _topicId = getUint16(getBodyPtr() +3);\n\t}\n\tMQTTSnMessage::absorb(src);\n}\n/*=====================================\n         Class MQTTSnSubAck\n  ======================================*/\nMQTTSnSubAck::MQTTSnSubAck(){\n    setMessageLength(8);\n    setType(MQTTSN_TYPE_SUBACK);\n    _flags = 0;\n    _topicId = 0;\n    _msgId = 0;\n    _returnCode = 0;\n    allocate();\n}\n\nMQTTSnSubAck::~MQTTSnSubAck(){\n\n}\n\nvoid MQTTSnSubAck::setFlags(uint8_t flags){\n    _flags = flags & 0x60;\n    getBodyPtr()[0] = _flags;\n}\n\nvoid MQTTSnSubAck::setQos(uint8_t qos){\n\t_flags &= 0x9f;\n\tif(qos == 1){\n\t\t_flags |= MQTTSN_FLAG_QOS_1;\n\t}\n\tsetFlags(_flags);\n}\n\nuint8_t MQTTSnSubAck::getFlags(){\n    return _flags;\n}\n\nuint8_t MQTTSnSubAck::getQos(){\n    return (_flags >> 5) & 0x03;\n}\n\nvoid MQTTSnSubAck::setTopicId(uint16_t id){\n    _topicId = id;\n    setUint16(getBodyPtr() + 1, id);\n}\n\nuint16_t MQTTSnSubAck::getTopicId(){\n    return _topicId;\n}\nvoid MQTTSnSubAck::setMsgId(uint16_t msgId){\n   _msgId = msgId;\n   setUint16(getBodyPtr() + 3, msgId);\n}\n\nuint16_t MQTTSnSubAck::getMsgId(){\n    return _msgId;\n}\nvoid MQTTSnSubAck::setReturnCode(uint8_t rc){\n    _returnCode = rc;\n    getBodyPtr()[5] = rc;\n}\nuint8_t  MQTTSnSubAck::getReturnCode(){\n    return _returnCode;\n}\n\n /*=====================================\n         Class MQTTSnUnsubscribe\n  ======================================*/\nMQTTSnUnsubscribe::MQTTSnUnsubscribe() : MQTTSnSubscribe(){\n    setType(MQTTSN_TYPE_UNSUBSCRIBE);\n}\n\nMQTTSnUnsubscribe::~MQTTSnUnsubscribe(){\n\n}\n\nvoid MQTTSnUnsubscribe::setFlags(uint8_t flags){\n    if (_message){\n\t\t  getBodyPtr()[0] = flags & 0x03;\n    }\n}\n\nstring* MQTTSnUnsubscribe::getTopicName(){\n\treturn &_topicName;\n}\n\nuint16_t MQTTSnUnsubscribe::getTopicId(){\n\treturn _topicId;\n}\n\nvoid MQTTSnUnsubscribe::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnUnsubscribe::absorb(MQTTSnMessage* src){\n\tMQTTSnSubscribe::absorb(src);\n}\n\n/*=====================================\n         Class MQTTSnUnSubAck\n  ======================================*/\nMQTTSnUnsubAck::MQTTSnUnsubAck(){\n\t_msgId = 0;\n    setMessageLength(4);\n    setType(MQTTSN_TYPE_UNSUBACK);\n    allocate();\n}\n\nMQTTSnUnsubAck::~MQTTSnUnsubAck(){\n\n}\n\nvoid MQTTSnUnsubAck::setMsgId(uint16_t msgId){\n    setUint16((uint8_t*)getBodyPtr(), msgId);\n}\n\nuint16_t MQTTSnUnsubAck::getMsgId(){\n    return getUint16(getBodyPtr());\n}\n\n/*=====================================\n        Class MQTTSnPingReq\n ======================================*/\nMQTTSnPingReq::MQTTSnPingReq(){\n\tsetMessageLength(2);\n\tsetType(MQTTSN_TYPE_PINGREQ);\n\tallocate();\n}\n\nMQTTSnPingReq::MQTTSnPingReq(string* id){\n  setMessageLength(id->size() + 2);\n  setType(MQTTSN_TYPE_PINGREQ);\n  allocate();\n  id->copy((char*)getBodyPtr(),id->size(),0);\n\n}\nMQTTSnPingReq::~MQTTSnPingReq(){\n\n}\n\nchar* MQTTSnPingReq::getClientId(){\n    return (char*)getBodyPtr();\n}\n\nvoid MQTTSnPingReq::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n        Class MQTTSnPingResp\n ======================================*/\nMQTTSnPingResp::MQTTSnPingResp(){\n    setMessageLength(2);\n    setType(MQTTSN_TYPE_PINGRESP);\n    allocate();\n}\nMQTTSnPingResp::~MQTTSnPingResp(){\n\n}\n\n /*=====================================\n         Class MQTTSnDisconnect\n  ======================================*/\nMQTTSnDisconnect::MQTTSnDisconnect(){\n    setMessageLength(4);\n    setType(MQTTSN_TYPE_DISCONNECT);\n    allocate();\n\n}\nMQTTSnDisconnect::~MQTTSnDisconnect(){\n\n}\nvoid MQTTSnDisconnect::setDuration(uint16_t duration){\n    setUint16((uint8_t*)getBodyPtr(), duration);\n}\nuint16_t MQTTSnDisconnect::getDuration(){\n    return getUint16((uint8_t*)getBodyPtr());\n}\n\nvoid MQTTSnDisconnect::absorb(NWResponse* src){\n\tMQTTSnMessage::absorb(src);\n}\n\nvoid MQTTSnDisconnect::absorb(MQTTSnMessage* src){\n\tMQTTSnMessage::absorb(src);\n}\n\n/*=====================================\n        Class RemaingLength\n ======================================*/\nRemainingLength::RemainingLength(){\n\t_size = _digit[0] = _digit[1] = _digit[2] = _digit[3] = 0;\n}\n\nRemainingLength::~RemainingLength(){\n\n}\n\nvoid RemainingLength::encode(uint16_t len){\n\t_size = 0;\n\tdo{\n\t\tuint8_t digit = len % 128;\n\t\tlen = len / 128;\n\t\tif(len > 0){\n\t\t\tdigit |= 0x80;\n\t\t}\n\t\t_digit[_size++] = digit;\n\t}while(len > 0);\n}\n\nuint16_t RemainingLength::decode(){\n\tuint16_t multiplier = 1;\n\tuint16_t value = 0;\n\tuint8_t digit;\n\tuint8_t pos = 0;\n\tdo{\n\t\tdigit = _digit[pos++];\n\t\tvalue += (digit & 0x7f) * multiplier;\n\t\tmultiplier *= 128;\n\t}while((digit & 0x80) != 0);\n\treturn value;\n}\n\nuint16_t RemainingLength::serialize(uint8_t* pos){\n\tmemcpy(pos, _digit, _size);\n\treturn decode();\n}\n\nvoid RemainingLength::deserialize(uint8_t* pos){\n\tuint8_t i = 0;\n\t_size = 0;\n\tdo{\n\t\t_digit[i++] = *pos;\n\t\t_size++;\n\t}while((*pos++ & 0x80) != 0 );\n}\n\nuint8_t RemainingLength::getSize(){\n\treturn _size;\n}\n\n/*=====================================\n         Class MQTTMessage\n  ======================================*/\nMQTTMessage::MQTTMessage(){\n\t_type = 0;\n\t_flags = 0;\n\t_messageId = 0;\n\t_remainLength = 0;\n\t_payload = 0;\n\t_userName = string(\"\");\n\t_password = string(\"\");\n\t_willTopic = string(\"\");\n\t_willMessage = string(\"\");\n\t_clientId = string(\"\");\n\t_topic = string(\"\");\n}\n\nMQTTMessage::~MQTTMessage(){\n\tif(_payload){\n\t\tfree(_payload);\n\t}\n}\n\nuint8_t MQTTMessage::getType(){\n\treturn _type;\n}\n\nuint8_t MQTTMessage::getQos(){\n\treturn (_flags & 0x06) >> 1;\n}\n\nuint16_t MQTTMessage::getRemainLength(){\n\treturn _remainLength;\n}\n\nuint8_t MQTTMessage::getRemainLengthSize(){\n\tRemainingLength remLen;\n\tremLen.encode(_remainLength);\n\treturn remLen.getSize();\n}\n\nbool MQTTMessage::isDup(){\n\treturn _flags & 0x80;\n}\n\nbool MQTTMessage::isRetain(){\n\treturn _flags & 0x01;\n}\n\nuint16_t MQTTMessage::serialize(uint8_t* buf){\n\tRemainingLength remLen;\n\tremLen.encode(_remainLength);\n\n\t*buf++ = _type | _flags;\n\tremLen.serialize(buf);\n\tbuf += remLen.getSize();\n\n\tif(remLen.decode() > 0){\n\t\tsetUint16(buf, _messageId);\n\t}\n\treturn 1 + remLen.getSize() + remLen.decode();\n}\n\nbool MQTTMessage::deserialize(uint8_t* buf){\n\tRemainingLength remLen;\n\n\t_type = *buf & 0xf0;\n\t_flags = *buf & 0x0f;\n\tremLen.deserialize(buf + 1);\n\t_remainLength = remLen.decode();\n\n\tswitch(_type){\n\t\tcase MQTT_TYPE_PINGRESP:\n\t\t\treturn true;\n\t\t\tbreak;\n\t\tcase MQTT_TYPE_UNSUBACK:\n\t\tcase MQTT_TYPE_PUBACK:\n\t\tcase MQTT_TYPE_PUBREC:\n\t\tcase MQTT_TYPE_PUBREL:\n\t\tcase MQTT_TYPE_PUBCOMP:\n\t\t\t_messageId = getUint16(buf + 2);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid MQTTMessage::absorb(MQTTMessage* msg){\n\t_type = msg->_type;\n\t_flags = msg->_flags;\n\t_messageId = msg->_messageId;\n\t_remainLength = msg->_remainLength;\n}\n\nvoid MQTTMessage::setType(uint8_t type){\n\t_type = type;\n}\nvoid MQTTMessage::setQos(uint8_t qos){\n\t_flags &= 0xf9;\n\tif(qos == 1){\n\t\t_flags |= 0x02;\n\t}else if(qos == 2){\n\t\t_flags |= 0x04;\n\t}\n}\n\nvoid MQTTMessage::setDup(){\n\t_flags |= 0x08;\n}\n\nvoid MQTTMessage::setRetain(){\n\t_flags |= 0x01;\n}\n\n/*=====================================\n         Class MQTTDisconnect\n  ======================================*/\nMQTTDisconnect::MQTTDisconnect(){\n\t_type = MQTT_TYPE_DISCONNECT;\n}\n\nMQTTDisconnect::~MQTTDisconnect(){\n\n}\n\n/*=====================================\n         Class MQTTPingReq\n  ======================================*/\nMQTTPingReq::MQTTPingReq(){\n\t_type = MQTT_TYPE_PINGREQ;\n}\n\nMQTTPingReq::~MQTTPingReq(){\n\n}\n\n/*=====================================\n         Class MQTTPingResp\n  ======================================*/\nMQTTPingResp::MQTTPingResp(){\n\t_type = MQTT_TYPE_PINGRESP;\n}\n\nMQTTPingResp::~MQTTPingResp(){\n\n}\n\n/*=====================================\n         Class MQTTConnAck\n  ======================================*/\nMQTTConnAck::MQTTConnAck(){\n\t_type = MQTT_TYPE_CONNACK;\n\t_remainLength = 2;\n\t_returnCd = 0;\n}\n\nMQTTConnAck::~MQTTConnAck(){\n\n}\n\n\nuint8_t MQTTConnAck::getReturnCd(){\n\treturn _returnCd;\n}\n\nbool MQTTConnAck::deserialize(uint8_t* buf){\n\tMQTTMessage::deserialize(buf);\n\n\tif(_type != MQTT_TYPE_CONNACK){\n\t\treturn false;\n\t}\n\tbuf += 3;\n\t_returnCd = *buf;\n\treturn true;\n}\n\n/*=====================================\n         Class MQTTUnsubAck\n  ======================================*/\nMQTTUnsubAck::MQTTUnsubAck(){\n\t_type = MQTT_TYPE_CONNACK;\n\t_remainLength = 2;\n}\n\nMQTTUnsubAck::~MQTTUnsubAck(){\n\n}\n\nvoid MQTTUnsubAck::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTUnsubAck::getMessageId(){\n\treturn _messageId;\n}\n\n/*=====================================\n         Class MQTTPubAck\n  ======================================*/\nMQTTPubAck::MQTTPubAck(){\n\t_type = MQTT_TYPE_PUBACK;\n\t_remainLength = 2;\n}\n\nMQTTPubAck::~MQTTPubAck(){\n\n}\n\nvoid MQTTPubAck::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTPubAck::getMessageId(){\n\treturn _messageId;\n}\n\n/*=====================================\n         Class MQTTPubRec\n  ======================================*/\nMQTTPubRec::MQTTPubRec(){\n\t_type = MQTT_TYPE_PUBREC;\n\t_remainLength = 2;\n}\n\nMQTTPubRec::~MQTTPubRec(){\n\n}\nvoid MQTTPubRec::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTPubRec::getMessageId(){\n\treturn _messageId;\n}\n\n/*=====================================\n         Class MQTTPubRel\n  ======================================*/\nMQTTPubRel::MQTTPubRel(){\n\t_type = MQTT_TYPE_PUBREL;\n\t_remainLength = 2;\n}\n\nMQTTPubRel::~MQTTPubRel(){\n\n}\n\n/*=====================================\n         Class MQTTPubComp\n  ======================================*/\nMQTTPubComp::MQTTPubComp(){\n\t_type = MQTT_TYPE_PUBCOMP;\n\t_remainLength = 2;\n}\n\nMQTTPubComp::~MQTTPubComp(){\n\n}\n\n/*=====================================\n         Class MQTTSubAck\n  ======================================*/\nMQTTSubAck::MQTTSubAck(){\n\t_type = MQTT_TYPE_SUBACK;\n\t_remainLength = 3;\n\t_qos = 0;\n}\n\nMQTTSubAck::~MQTTSubAck(){\n\n}\n\nvoid MQTTSubAck::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTSubAck::getMessageId(){\n\treturn _messageId;\n}\n\nuint8_t MQTTSubAck::getGrantedQos(){\n\treturn _qos;\n}\n\nvoid MQTTSubAck::setGrantedQos0(){\n\t_qos = 0;\n}\n\nvoid MQTTSubAck::setGrantedQos1(){\n\t_qos = 1;\n}\n\nbool MQTTSubAck::deserialize(uint8_t* buf){\n\tRemainingLength remLen;\n\tremLen.encode(_remainLength);\n\n\t_type = *buf & 0xf0;\n\tif(_type != MQTT_TYPE_SUBACK){\n\t\treturn false;\n\t}\n\t_flags = *buf++ & 0x0f;\n\tremLen.deserialize(buf);\n\t_messageId = getUint16(buf + remLen.getSize());\n\t_qos = *(buf + remLen.getSize() + 2);\n\treturn true;\n}\n\n/*=====================================\n         Class MQTTUnsubscribe\n  ======================================*/\nMQTTUnsubscribe::MQTTUnsubscribe(){\n\t_type = MQTT_TYPE_UNSUBSCRIBE;\n\t_remainLength = 0;\n}\n\nMQTTUnsubscribe::~MQTTUnsubscribe(){\n\n}\n\nvoid MQTTUnsubscribe::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTUnsubscribe::getMessageId(){\n\treturn _messageId;\n}\n\nvoid MQTTUnsubscribe::setTopicName(string* topic){\n\t_topic = *topic;\n}\n\nuint16_t MQTTUnsubscribe::serialize(uint8_t* buf){\n\tRemainingLength remLen;\n\t_remainLength = _topic.size() + 4;\n\tremLen.encode(_remainLength);\n\n\t*buf++ = _type | 0x02;\n\tremLen.serialize(buf);\n\tbuf += remLen.getSize();\n\tsetUint16(buf, _messageId);\n\tbuf += 2;\n\tutfSerialize(buf,_topic);\n\treturn 1 + remLen.getSize() + remLen.decode();\n}\n\n\n/*=====================================\n         Class MQTTSubscribe\n  ======================================*/\nMQTTSubscribe::MQTTSubscribe(){\n\t_type = MQTT_TYPE_SUBSCRIBE;\n\t_remainLength = 2;\n\t_qos = 0;\n\tsetQos(1);\n}\n\nMQTTSubscribe::~MQTTSubscribe(){\n\n}\n\nvoid MQTTSubscribe::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTSubscribe::getMessageId(){\n\treturn _messageId;\n}\n\nvoid MQTTSubscribe::setTopic(string* topic, uint8_t qos){\n\t_topic = *topic;\n\t_qos = qos;\n}\n\nuint16_t MQTTSubscribe::serialize(uint8_t* buf){\n\tRemainingLength remLen;\n\t_remainLength = _topic.size() + 5; //length:2, Topic:n, QoS:1\n\tremLen.encode(_remainLength);\n\n\t*buf++ = _type | 0x02;   //SUBSCRIBE QoS1\n\tremLen.serialize(buf);\n\tbuf += remLen.getSize();\n\tsetUint16(buf, _messageId);\n\tbuf += 2;\n\tutfSerialize(buf,_topic);\n\tbuf += 2 + _topic.size();\n\t*buf = _qos;\n\treturn 1 + remLen.getSize() + remLen.decode();\n}\n/*=====================================\n         Class MQTTConnect\n  ======================================*/\nMQTTConnect::MQTTConnect() : MQTTMessage(){\n\t_type = MQTT_TYPE_CONNECT;\n\t_connectFlags = 0;;\n\t_keepAliveTime = 0;\n\t_userName = string(\"\");\n\t_password = string(\"\");\n\t_willTopic = string(\"\");\n\t_willMessage = string(\"\");\n\t_clientId = string(\"\");\n\t_protocol = 0;\n}\n\n\nMQTTConnect::~MQTTConnect(){\n\n}\n\nvoid MQTTConnect::setKeepAliveTime(uint16_t sec){\n\t_keepAliveTime = sec;\n}\n\nvoid MQTTConnect::setUserName(string* userName){\n\t_userName = *userName;\n\t_connectFlags &= 0x7e;\n\t_connectFlags |= 0x80;\n}\n\nvoid MQTTConnect::setPassword(string* pw){\n\t_password = *pw;\n\t_connectFlags &= 0xbe;\n\t_connectFlags |= 0x40;\n}\n\nvoid MQTTConnect::setWillMessage(string* wm){\n\t_willMessage = *wm;\n\t_connectFlags &= 0xfa;\n\t_connectFlags |= 0x04;\n}\n\nvoid MQTTConnect::setWillTopic(string* tp){\n\t_willTopic = *tp;\n\t_connectFlags &= 0xfa;\n\t_connectFlags |= 0x04;\n}\n\nvoid MQTTConnect::setWillQos(uint8_t qos){\n\t_connectFlags &= 0xe6;\n\t_connectFlags |= (qos << 3);\n}\n\nvoid MQTTConnect::setProtocol(uint8_t protocol){\n\t_protocol = protocol;\n}\n\nvoid MQTTConnect::setClientId(string* cid){\n\t_clientId = *cid;\n}\n\nvoid MQTTConnect::setCleanSessionFlg(){\n\t_connectFlags &= 0xfc;\n\t_connectFlags |= 0x02;\n}\n\n\nuint16_t MQTTConnect::serialize(uint8_t* buf){\n\tuint16_t len;\n\tstring protocol;\n\tif(_protocol == MQTT_PROTOCOL_VER4){\n\t\tprotocol = MQTT_PROTOCOL_NAME4;\n\t\tlen = 10;\n\t}else{\n\t\tprotocol = MQTT_PROTOCOL_NAME3;\n\t\tlen = 12;\n\t}\n\n\tlen += _clientId.size() + 2;\n\n\tif(_connectFlags & 0x0c){  // Will Topic & Message\n\t\tlen += _willTopic.size() + 2;\n\t\tlen += _willMessage.size() + 2;\n\t}\n\tif(_connectFlags & 0x80){  // User Name\n\t\tlen += _userName.size() + 2;\n\t}\n\tif(_connectFlags & 0x40){  // Password\n\t\tlen += _password.size() + 2;\n\t}\n\tRemainingLength remLen;\n\tremLen.encode(len);\n\t_remainLength = len;\n\n\t*buf++ = _type | _flags;\n\tremLen.serialize(buf);\n\tbuf += remLen.getSize();\n\n\tutfSerialize(buf, protocol);\n\tbuf += protocol.size() + 2;\n\t*buf++ = _protocol;\n\t*buf++ = _connectFlags;\n\tsetUint16(buf++, _keepAliveTime);\n\n\tutfSerialize(++buf,_clientId); // copy clienId\n\tbuf += _clientId.size() + 2;\n\n\tif(_connectFlags & 0x0c){  // Will Topic & Message\n\t\tutfSerialize(buf,_willTopic);\n\t\tbuf += _willTopic.size() + 2;\n\t\tutfSerialize(buf,_willMessage);\n\t\tbuf += _willMessage.size() + 2;\n\t}\n\tif(_connectFlags & 0x80){  // User Name\n\t\tutfSerialize(buf,_userName);\n\t\tbuf += _userName.size() + 2;\n\t}\n\tif(_connectFlags & 0x40){  // Password\n\t\tutfSerialize(buf,_password);\n\t}\n\n\treturn 1 + remLen.getSize() + remLen.decode();\n\n}\n\n/*=====================================\n         Class MQTTPublish\n  ======================================*/\nMQTTPublish::MQTTPublish(){\n\t_type = MQTT_TYPE_PUBLISH;\n\t//_topic = string(\"\");\n\t//_payload = 0;\n\t_len = 0;\n\t_messageId = 0;\n}\n\nMQTTPublish::~MQTTPublish(){\n\n}\n\nvoid MQTTPublish::setMessageId(uint16_t id){\n\t_messageId = id;\n}\n\nuint16_t MQTTPublish::getMessageId(){\n\treturn _messageId;\n}\n\nstring* MQTTPublish::getTopic(){\n\treturn &_topic;\n}\n\nuint8_t* MQTTPublish::getPayload(){\n\treturn _payload;\n}\n\n\nuint8_t  MQTTPublish::getPayloadLength(){\n\treturn _len;\n}\n\nvoid MQTTPublish::setTopic(string* topic){\n\t_topic = *topic;\n}\n\nvoid MQTTPublish::setPayload(uint8_t* payload, uint8_t length){\n\tif(_payload){\n\t\t_remainLength -= _len;\n\t\tfree(_payload);\n\t}\n\t_payload = mqcalloc(length);\n\tmemcpy(_payload, payload, length);\n\t_len = length;\n\t_remainLength += length;\n}\n\nuint16_t MQTTPublish::serialize(uint8_t* buf){\n\tRemainingLength remLen;\n\t_remainLength = _topic.size() + 2 + _len;\n\tif(getQos()){\n\t\t_remainLength += 2;\n\t}\n\tremLen.encode(_remainLength);\n\n\t*buf++ = (_type & 0xf0) | (_flags & 0x0f);\n\tremLen.serialize(buf);\n\tbuf += remLen.getSize();\n\tutfSerialize(buf, _topic);\n\tbuf += _topic.size() + 2;\n\tif(getQos()){\n\t\tsetUint16(buf, _messageId);\n\t\tbuf += 2;\n\t}\n\tmemcpy(buf, _payload, _len);\n\n\treturn 1 + remLen.getSize() + remLen.decode();\n}\n\nbool MQTTPublish::deserialize(uint8_t* buf){\n\tuint8_t pos = 2;\n\n\t_type = *buf & 0xf0;\n\tif(_type != MQTT_TYPE_PUBLISH){\n\t\treturn false;\n\t}\n\tRemainingLength remLen;\n\n\t_flags = *buf & 0x0f;\n\tremLen.deserialize(buf + 1);\n\t_remainLength = remLen.decode();\n\n\tbuf += 1 + remLen.getSize();\n\t_topic = string((char*)buf + 2, getUint16(buf));\n\tif(!isUtf8Valid(_topic)){\n\t\treturn false;\n\t}\n\n\tbuf += _topic.size() + 2;\n\tif(getQos()){\n\t\t_messageId = getUint16(buf);\n\t\tbuf += 2;\n\t\tpos += 2;\n\t}\n\t_len = _remainLength - _topic.size() - pos;\n\t_payload = mqcalloc(_len);\n\tmemcpy(_payload, buf, _len);\n\treturn true;\n}\n\n"
  },
  {
    "path": "Gateway/src/lib/Messages.h",
    "content": "/*\n * Messages.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef MESSAGES_H_\n#define MESSAGES_H_\n\n\n/*\n *     MQTT-SN Message Type\n */\n#define MQTTSN_TYPE_ADVERTISE     0x00\n#define MQTTSN_TYPE_SEARCHGW      0x01\n#define MQTTSN_TYPE_GWINFO        0x02\n#define MQTTSN_TYPE_CONNECT       0x04\n#define MQTTSN_TYPE_CONNACK       0x05\n#define MQTTSN_TYPE_WILLTOPICREQ  0x06\n#define MQTTSN_TYPE_WILLTOPIC     0x07\n#define MQTTSN_TYPE_WILLMSGREQ    0x08\n#define MQTTSN_TYPE_WILLMSG       0x09\n#define MQTTSN_TYPE_REGISTER      0x0A\n#define MQTTSN_TYPE_REGACK        0x0B\n#define MQTTSN_TYPE_PUBLISH       0x0C\n#define MQTTSN_TYPE_PUBACK        0x0D\n#define MQTTSN_TYPE_PUBCOMP       0x0E\n#define MQTTSN_TYPE_PUBREC        0x0F\n#define MQTTSN_TYPE_PUBREL        0x10\n#define MQTTSN_TYPE_SUBSCRIBE     0x12\n#define MQTTSN_TYPE_SUBACK        0x13\n#define MQTTSN_TYPE_UNSUBSCRIBE   0x14\n#define MQTTSN_TYPE_UNSUBACK      0x15\n#define MQTTSN_TYPE_PINGREQ       0x16\n#define MQTTSN_TYPE_PINGRESP      0x17\n#define MQTTSN_TYPE_DISCONNECT    0x18\n#define MQTTSN_TYPE_WILLTOPICUPD  0x1A\n#define MQTTSN_TYPE_WILLTOPICRESP 0x1B\n#define MQTTSN_TYPE_WILLMSGUPD    0x1C\n#define MQTTSN_TYPE_WILLMSGRESP   0x1D\n\n/*\n *     MQTT Message types\n */\n#define MQTT_PROTOCOL_NAME3      \"MQIsdp\"\n#define MQTT_PROTOCOL_NAME4      \"MQTT\"\n#define MQTT_PROTOCOL_VER4        4\n#define MQTT_PROTOCOL_VER3        3\n\n\n#define MQTT_TYPE_CONNECT         0x10\n#define MQTT_TYPE_CONNACK         0x20\n#define MQTT_TYPE_PUBLISH         0x30\n#define MQTT_TYPE_PUBACK          0x40\n#define MQTT_TYPE_PUBREC          0x50\n#define MQTT_TYPE_PUBREL          0x60\n#define MQTT_TYPE_PUBCOMP         0x70\n#define MQTT_TYPE_SUBSCRIBE       0x80\n#define MQTT_TYPE_SUBACK          0x90\n#define MQTT_TYPE_UNSUBSCRIBE     0xA0\n#define MQTT_TYPE_UNSUBACK        0xB0\n#define MQTT_TYPE_PINGREQ         0xC0\n#define MQTT_TYPE_PINGRESP        0xD0\n#define MQTT_TYPE_DISCONNECT      0xE0\n\n#define MQTT_RC_ACCEPTED                      0\n#define MQTT_RC_REFUSED_PROTOCOL_VERSION      1\n#define MQTT_RC_REFUSED_IDENTIFIER_REJECTED   2\n#define MQTT_RC_REFUSED_SERVER_UNAVAILABLE    3\n#define MQTT_RC_REFUSED_BAD_USERNAME_PASSWORD 4\n#define MQTT_RC_REFUSED_NOT_AUTHORIZED        5\n\n/*\n *    Flags\n */\n#define MQTTSN_FLAG_DUP                     0x80\n#define MQTTSN_FLAG_QOS_0                   0x0\n#define MQTTSN_FLAG_QOS_1                   0x20\n#define MQTTSN_FLAG_QOS_2                   0x40\n#define MQTTSN_FLAG_QOS_N1                  0xc0\n#define MQTTSN_FLAG_RETAIN                  0x10\n#define MQTTSN_FLAG_WILL                    0x08\n#define MQTTSN_FLAG_CLEAN                   0x04\n#define MQTTSN_FLAG_TOPICID_TYPE_NORMAL     0x00\n#define MQTTSN_FLAG_TOPICID_TYPE_PREDEFINED 0x01\n#define MQTTSN_FLAG_TOPICID_TYPE_SHORT      0x02\n#define MQTTSN_FLAG_TOPICID_TYPE_RESV       0x03\n\n#define MQTTSN_TOPIC_TYPE_NORMAL            0x00\n#define MQTTSN_TOPIC_TYPE_PREDEFINED        0x01\n#define MQTTSN_TOPIC_TYPE_SHORT             0x02\n#define MQTTSN_TOPIC_TYPE                   0x03\n\n#define MQTTSN_PROTOCOL_ID  0x01\n#define MQTTSN_HEADER_SIZE  2\n\n/*\n *     Return Code\n */\n#define MQTTSN_RC_ACCEPTED                  0x00\n#define MQTTSN_RC_REJECTED_CONGESTION       0x01\n#define MQTTSN_RC_REJECTED_INVALID_TOPIC_ID 0x02\n#define MQTTSN_RC_REJECTED_NOT_SUPPORTED    0x03\n\n#define MQTTSN_MSG_REQUEST     1\n#define MQTTSN_MSG_RESEND_REQ  2\n#define MQTTSN_MSG_WAIT_ACK    3\n#define MQTTSN_MSG_COMPLETE    4\n#define MQTTSN_MSG_REJECTED    5\n\n\n#define MQTTSN_GW_INIT         0\n#define MQTTSN_GW_SEARCHING    1\n#define MQTTSN_GW_FOUND        2\n#define MQTTSN_GW_CONNECTED    3\n#define MQTTSN_GW_DISCONNECTED 4\n#define MQTTSN_GW_LOST         5\n\n#define MQTTSN_ERR_NO_ERROR            0\n#define MQTTSN_ERR_NOT_CONNECTED      -1\n#define MQTTSN_ERR_RETRY_OVER         -2\n#define MQTTSN_ERR_GATEWAY_LOST       -3\n#define MQTTSN_ERR_CANNOT_ADD_REQUEST -4\n#define MQTTSN_ERR_NO_TOPICID         -5\n#define MQTTSN_ERR_REJECTED           -6\n#define MQTTSN_ERR_WAIT_GWINFO        -7\n#define MQTTSN_ERR_OUT_OF_MEMORY      -8\n#define MQTTSN_ERR_PING_REQUIRED      -9\n#define MQTTSN_ERR_ACK_TIMEOUT       -10\n#define MQTTSN_ERR_PINGRESP_TIMEOUT  -11\n\n\n#include \"ZBStack.h\"\n#include \"UDPStack.h\"\n#include \"ProcessFramework.h\"\n#include <string>\n\nusing namespace std;\nusing namespace tomyGateway;\n\n/*=====================================\n        Class MQTTSnMessage\n  =====================================*/\nclass MQTTSnMessage{\npublic:\n\tMQTTSnMessage();\n    ~MQTTSnMessage();\n    void setMessageLength(uint16_t length);\n    void setType(uint8_t type);\n    void setBody(uint8_t* body, uint16_t bodyLength);\n    void setMessage(uint8_t* msg);\n\n    uint8_t  getType();\n    uint16_t getBodyLength();\n    uint16_t getMessageLength();\n    uint8_t* getMessagePtr();\n    uint8_t* getBodyPtr();\n    bool    getMessage(uint16_t pos, uint8_t& val);\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\nprotected:\n    void allocate();\n    uint8_t* _message;\nprivate:\n    uint16_t  _length;\n\tuint8_t   _type;\n};\n\n/*=====================================\n        Class MQTTSnAdvertize\n ======================================*/\nclass MQTTSnAdvertise : public MQTTSnMessage {\npublic:\n\tMQTTSnAdvertise();\n\t~MQTTSnAdvertise();\n\tvoid setGwId(uint8_t id);\n\tvoid setDuration(uint16_t duration);\n\tuint8_t getGwId();\n\tuint16_t getDuration();\nprivate:\n};\n\n/*=====================================\n        Class MQTTSnSearchGw\n ======================================*/\nclass MQTTSnSearchGw : public MQTTSnMessage {\npublic:\n\tMQTTSnSearchGw();\n\t~MQTTSnSearchGw();\n\tvoid setRadius(uint8_t radius);\n\tuint8_t getRadius();\n\tvoid absorb(NWResponse* src);\nprivate:\n};\n\n/*=====================================\n        Class MQTTSnGwinfo\n ======================================*/\nclass MQTTSnGwInfo : public MQTTSnMessage {\npublic:\n  MQTTSnGwInfo();\n  ~MQTTSnGwInfo();\n  void setGwId(uint8_t id);\n  uint8_t getGwId();\n\nprivate:\n};\n\n/*=====================================\n         Class MQTTSnConnect\n  ======================================*/\nclass MQTTSnConnect : public MQTTSnMessage {\npublic:\n\tMQTTSnConnect();\n    MQTTSnConnect(string* id);\n    ~MQTTSnConnect();\n\n    void setFlags(uint8_t flg);\n    void setDuration(uint16_t msec);\n    void setClientId(string id);\n\n    uint8_t getFlags();\n    uint16_t getDuration();\n    string* getClientId();\n    bool isCleanSession();\n    bool isWillRequired();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprivate:\n    string _clientId;\n };\n\n/*=====================================\n        Class MQTTSnConnack\n ======================================*/\nclass MQTTSnConnack : public MQTTSnMessage  {\npublic:\n    MQTTSnConnack();\n    ~MQTTSnConnack();\n    void setReturnCode(uint8_t rc);\n    uint8_t getReturnCode();\n\nprivate:\n\n};\n\n/*=====================================\n         Class MQTTSnWillTopicReq\n  ======================================*/\nclass MQTTSnWillTopicReq : public MQTTSnMessage  {\npublic:\n    MQTTSnWillTopicReq();\n    ~MQTTSnWillTopicReq();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MQTTSnWillTopic\n  ======================================*/\nclass MQTTSnWillTopic : public MQTTSnMessage  {\npublic:\n    MQTTSnWillTopic();\n    ~MQTTSnWillTopic();\n    void setFlags(uint8_t flags);\n    void setWillTopic(string* topic);\n    string* getWillTopic();\n    uint8_t getQos();\n    bool isWillRequired();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprivate:\n    uint8_t _flags;\n    string _topicName;\n };\n\n/*=====================================\n         Class MQTTSnWillMsgReq\n  ======================================*/\nclass MQTTSnWillMsgReq : public MQTTSnMessage  {\npublic:\n    MQTTSnWillMsgReq();\n    ~MQTTSnWillMsgReq();\n\nprivate:\n\n };\n\n/*=====================================\n         Class MQTTSnWillMsg\n  ======================================*/\nclass MQTTSnWillMsg : public MQTTSnMessage  {\npublic:\n    MQTTSnWillMsg();\n    ~MQTTSnWillMsg();\n    void setWillMsg(string* msg);\n    string* getWillMsg();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprivate:\n    string _willMsg;\n };\n\n/*=====================================\n         Class MQTTSnRegister\n  ======================================*/\nclass MQTTSnRegister : public MQTTSnMessage  {\npublic:\n    MQTTSnRegister();\n    ~MQTTSnRegister();\n    void setTopicId(uint16_t topicId);\n    void setMsgId(uint16_t msgId);\n    void setTopicName(string* topicName);\n    //void setFrame(uint8_t* data, uint8_t len);\n    //void setFrame(NWResponse* resp);\n    uint16_t getMsgId();\n    uint16_t getTopicId();\n    string*  getTopicName();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\nprivate:\n    uint16_t _topicId;\n    uint16_t _msgId;\n    string _topicName;\n\n };\n\n/*=====================================\n         Class MQTTSnRegAck\n  ======================================*/\nclass MQTTSnRegAck : public MQTTSnMessage  {\npublic:\n    MQTTSnRegAck();\n    ~MQTTSnRegAck();\n    void setTopicId(uint16_t topicId);\n    void setMsgId(uint16_t msgId);\n    void setReturnCode(uint8_t rc);\n    uint16_t getMsgId();\n    uint16_t getTopicId();\n    uint8_t  getReturnCode();\n\n    void absorb(NWResponse* src);\nprivate:\n\n };\n\n /*=====================================\n         Class MQTTSnPublish\n  ======================================*/\nclass MQTTSnPublish : public MQTTSnMessage  {\npublic:\n    MQTTSnPublish();\n    ~MQTTSnPublish();\n    void setFlags(uint8_t flags);\n\n    void setTopicId(uint16_t id);\n    void setTopic(string* topic);\n    void setMsgId(uint16_t msgId);\n    void setData(uint8_t* data, uint8_t len);\n    //void setFrame(uint8_t* data, uint8_t len);\n    //void setFrame(NWResponse* resp);\n\tvoid setQos(uint8_t);\n\tvoid setDup();\n\tvoid setRetain();\n\tvoid setTopicIdType(uint8_t);\n\n    uint16_t getTopicId();\n    string*  getTopic(string* str);\n    uint8_t  getTopicType();\n    uint8_t  getQos();\n    uint8_t  getFlags();\n    uint8_t* getData();\n    uint16_t getDataLength();\n    uint16_t getMsgId();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprivate:\n    uint8_t _flags;\n    uint16_t _topicId;\n    uint16_t _msgId;\n };\n\n/*=====================================\n         Class MQTTSnPubAck\n  ======================================*/\nclass MQTTSnPubAck : public MQTTSnMessage  {\npublic:\n    MQTTSnPubAck();\n    ~MQTTSnPubAck();\n    void setTopicId(uint16_t id);\n    void setMsgId(uint16_t msgId);\n    void setReturnCode(uint8_t rc);\n\n    uint8_t  getReturnCode();\n    uint16_t getTopicId();\n    uint16_t getMsgId();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprivate:\n    uint16_t _topicId;\n\tuint16_t _msgId;\n\tuint8_t  _returnCode;\n };\n\n/*=====================================\n         Class MQTTSnPubRec\n  ======================================*/\nclass MQTTSnPubRec : public MQTTSnMessage  {\npublic:\n\tMQTTSnPubRec();\n    ~MQTTSnPubRec();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n\n    //void absorb(MQTTSnMessage* src);\n    //void absorb(NWResponse* src);\nprotected:\n\tuint16_t _msgId;\n };\n\n/*=====================================\n         Class MQTTSnPubRel\n  ======================================*/\nclass MQTTSnPubRel : public MQTTSnPubRec  {\npublic:\n\tMQTTSnPubRel();\n    ~MQTTSnPubRel();\n };\n\n/*=====================================\n         Class MQTTSnPubRel\n  ======================================*/\nclass MQTTSnPubComp : public MQTTSnPubRec  {\npublic:\n\tMQTTSnPubComp();\n    ~MQTTSnPubComp();\nprivate:\n\n };\n\n /*=====================================\n         Class MQTTSnSubscribe\n  ======================================*/\nclass MQTTSnSubscribe : public MQTTSnMessage  {\npublic:\n    MQTTSnSubscribe();\n    ~MQTTSnSubscribe();\n    void setFlags(uint8_t flags);\n    void setMsgId(uint16_t msgId);\n\tvoid setQos(uint8_t);\n    void setTopicName(string* topicName);\n    void setTopicId(uint16_t predefinedId);\n\t//void setFrame(uint8_t* data, uint8_t len);\n\t//void setFrame(NWResponse* resp);uint16_t getMsgId();\n    uint8_t  getQos();\n    uint8_t  getFlags();\n    uint16_t getTopicId();\n    uint16_t getMsgId();\n    string*  getTopicName();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\n\nprotected:\n    uint16_t _topicId;\n    uint16_t _msgId;\n    uint8_t  _flags;\n    string _topicName;\n };\n\n/*=====================================\n         Class MQTTSnSubAck\n  ======================================*/\nclass MQTTSnSubAck : public MQTTSnMessage  {\npublic:\n    MQTTSnSubAck();\n    ~MQTTSnSubAck();\n    void setFlags(uint8_t flags);\n    void setQos(uint8_t qos);\n    void setMsgId(uint16_t msgId);\n    void setTopicId(uint16_t topicId);\n    void setReturnCode(uint8_t rc);\n\n    uint8_t  getFlags();\n    uint8_t  getQos();\n    uint8_t  getReturnCode();\n    uint16_t getMsgId();\n    uint16_t getTopicId();\n\nprivate:\n    uint16_t _topicId;\n\tuint16_t _msgId;\n\tuint8_t  _flags;\n\tuint8_t  _returnCode;\n\tstring   _topicName;\n };\n\n /*=====================================\n         Class MQTTSnUnsubscribe\n  ======================================*/\nclass MQTTSnUnsubscribe : public MQTTSnSubscribe  {\npublic:\n    MQTTSnUnsubscribe();\n    ~MQTTSnUnsubscribe();\n    void setFlags(uint8_t flags);\n\n    string* getTopicName();\n    uint16_t  getTopicId();\n\n    void absorb(NWResponse* src);\n    void absorb(MQTTSnMessage* src);\nprivate:\n\n };\n\n/*=====================================\n         Class MQTTSnUnSubAck\n  ======================================*/\nclass MQTTSnUnsubAck : public MQTTSnMessage  {\npublic:\n    MQTTSnUnsubAck();\n    ~MQTTSnUnsubAck();\n    void setMsgId(uint16_t msgId);\n    uint16_t getMsgId();\n\nprivate:\n    uint16_t _msgId;\n };\n\n/*=====================================\n        Class MQTTSnPingReq\n ======================================*/\nclass MQTTSnPingReq : public MQTTSnMessage  {\npublic:\n\tMQTTSnPingReq();\n    MQTTSnPingReq(string* id);\n    ~MQTTSnPingReq();\n    void setClientId(string* id);\n    char* getClientId();\n\n    void absorb(NWResponse* src);\nprivate:\n\n};\n\n/*=====================================\n        Class MQTTSnPingResp\n ======================================*/\nclass MQTTSnPingResp : public MQTTSnMessage  {\npublic:\n    MQTTSnPingResp();\n    ~MQTTSnPingResp();\nprivate:\n\n};\n\n /*=====================================\n         Class MQTTSnDisconnect\n  ======================================*/\nclass MQTTSnDisconnect : public MQTTSnMessage  {\npublic:\n    MQTTSnDisconnect();\n    ~MQTTSnDisconnect();\n    void setDuration(uint16_t duration);\n    uint16_t getDuration();\n\n    void absorb(MQTTSnMessage* src);\n    void absorb(NWResponse* src);\nprivate:\n\n };\n\n\n\n\n\n/*=====================================\n        Class RemaingLength\n =====================================*/\nclass RemainingLength{\npublic:\n\tRemainingLength();\n\t~RemainingLength();\n\tvoid encode(uint16_t);\n\tuint16_t decode();\n\tuint16_t serialize(uint8_t* pos);\n\tvoid deserialize(uint8_t* pos);\n\tuint8_t getSize();\n\nprivate:\n\tuint8_t _digit[4];\n\tuint8_t _size;\n};\n\n/*=====================================\n         Class MQTTMessage\n  ======================================*/\nclass MQTTMessage{\npublic:\n\tMQTTMessage();\n\t~MQTTMessage();\n\tuint8_t getType();\n\tuint8_t getQos();   // QOS0 = 0, QOS1 = 1\n\tuint16_t getRemainLength();\n\tuint8_t getRemainLengthSize();\n\tbool isDup();\n\tbool isRetain();\n\tuint16_t serialize(uint8_t* buf);\n\tbool deserialize(uint8_t* buf);\n\n\tvoid setType(uint8_t);\n\tvoid setQos(uint8_t);\n\tvoid setDup();\n\tvoid setRetain();\n\tvoid absorb(MQTTMessage* msg);\n\nprotected:\n\tuint8_t _type;\n\tuint8_t _flags;\n\tuint16_t _remainLength;\n\tuint16_t _messageId;\n\n\tuint8_t* _payload;\n\n\tstring _userName;\n\tstring _password;\n\tstring _willTopic;\n\tstring _willMessage;\n\tstring _clientId;\n\n\tstring _topic;\n\n\n};\n\n\n/*=====================================\n         Class MQTTPingReq\n  ======================================*/\nclass MQTTPingReq : public MQTTMessage{\npublic:\n\tMQTTPingReq();\n\t~MQTTPingReq();\n};\n\n/*=====================================\n         Class MQTTPingResp\n  ======================================*/\nclass MQTTPingResp : public MQTTMessage{\npublic:\n\tMQTTPingResp();\n\t~MQTTPingResp();\n};\n\n/*=====================================\n         Class MQTTDisconnect\n  ======================================*/\nclass MQTTDisconnect : public MQTTMessage{\npublic:\n\tMQTTDisconnect();\n\t~MQTTDisconnect();\n};\n\n/*=====================================\n         Class MQTTPubAck\n  ======================================*/\nclass MQTTPubAck : public MQTTMessage{\npublic:\n\tMQTTPubAck();\n\t~MQTTPubAck();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n\n};\n\n/*=====================================\n         Class MQTTPubRec\n  ======================================*/\nclass MQTTPubRec : public MQTTMessage{\npublic:\n\tMQTTPubRec();\n\t~MQTTPubRec();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n\n};\n\n/*=====================================\n         Class MQTTPubRel\n  ======================================*/\nclass MQTTPubRel : public MQTTPubRec{\npublic:\n\tMQTTPubRel();\n\t~MQTTPubRel();\n\t//void setMessageId(uint16_t);\n\t//uint16_t getMessageId();\n};\n\n/*=====================================\n         Class MQTTPubComp\n  ======================================*/\nclass MQTTPubComp : public MQTTPubRec{\npublic:\n\tMQTTPubComp();\n\t~MQTTPubComp();\n\t//void setMessageId(uint16_t);\n\t//uint16_t getMessageId();\n};\n/*=====================================\n         Class MQTTConnAck\n  ======================================*/\nclass MQTTConnAck : public MQTTMessage{\npublic:\n\tMQTTConnAck();\n\t~MQTTConnAck();\n\tuint8_t getReturnCd();\n\tbool deserialize(uint8_t* buf);\nprivate:\n\tuint8_t _returnCd;\n};\n\n/*=====================================\n         Class MQTTUnsubAck\n  ======================================*/\nclass MQTTUnsubAck : public MQTTMessage{\npublic:\n\tMQTTUnsubAck();\n\t~MQTTUnsubAck();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n};\n\n/*=====================================\n         Class MQTTSubAck\n  ======================================*/\nclass MQTTSubAck : public MQTTMessage{\npublic:\n\tMQTTSubAck();\n\t~MQTTSubAck();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n\tuint8_t getGrantedQos();\n\tvoid setGrantedQos0();\n\tvoid setGrantedQos1();\n\tbool deserialize(uint8_t* buf);\nprivate:\n\tuint8_t _qos;\n};\n\n/*=====================================\n         Class MQTTUnSubscribe\n  ======================================*/\nclass MQTTUnsubscribe : public MQTTMessage{\npublic:\n\tMQTTUnsubscribe();\n\t~MQTTUnsubscribe();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n\tuint16_t serialize(uint8_t* buf);\n\tvoid setTopicName(string*);\nprivate:\n\t//string _topic;\n};\n\n/*=====================================\n         Class MQTTSubscribe\n  ======================================*/\nclass MQTTSubscribe : public MQTTMessage{\npublic:\n\tMQTTSubscribe();\n\t~MQTTSubscribe();\n\tvoid setMessageId(uint16_t);\n\tuint16_t getMessageId();\n\tuint16_t serialize(uint8_t* buf);\n\tvoid setTopic(string* topic, uint8_t qos);\nprivate:\n\t//string _topic;\n\tuint8_t _qos;\n};\n\n/*=====================================\n         Class MQTTConnect\n  ======================================*/\nclass MQTTConnect : public MQTTMessage{\npublic:\n\tMQTTConnect();\n\t~MQTTConnect();\n\tvoid setProtocol(uint8_t);\n\tvoid setUserName(string*);\n\tvoid setPassword(string*);\n\tvoid setKeepAliveTime(uint16_t);\n\tvoid setWillMessage(string*);\n\tvoid setWillTopic(string*);\n\tvoid setWillQos(uint8_t);\n\tvoid setClientId(string*);\n\tvoid setCleanSessionFlg();\n\tuint16_t serialize(uint8_t* buf);\nprivate:\n\tuint8_t _connectFlags;\n\tuint16_t _keepAliveTime;\n\tstring _userName;\n\tstring _password;\n\tstring _willTopic;\n\tstring _willMessage;\n\tstring _clientId;\n\tuint8_t _protocol;\n};\n\n/*=====================================\n         Class MQTTPublish\n  ======================================*/\nclass MQTTPublish : public MQTTMessage{\npublic:\n\tMQTTPublish();\n\t~MQTTPublish();\n\tvoid setMessageId(uint16_t);\n\tvoid setPayload(uint8_t*, uint8_t);\n\tvoid setTopic(string*);\n\tstring* getTopic();\n\tuint16_t getMessageId();\n\tuint8_t* getPayload();\n\tuint8_t  getPayloadLength();\n\n\tuint16_t serialize(uint8_t* buf);\n\tbool deserialize(uint8_t* buf);\n\nprivate:\n\t//string _topic;\n\tuint16_t _len;\n};\n\n#endif /* MESSAGES_H_ */\n"
  },
  {
    "path": "Gateway/src/lib/ProcessFramework.cpp",
    "content": "/*\n * ProcessFramework.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"ProcessFramework.h\"\n#include \"Defines.h\"\n#include <string.h>\n#include <exception>\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <iostream>\n#include <sys/time.h>\n#include <time.h>\n#include <unistd.h>\n#include <sys/ipc.h>\n#include <sys/sem.h>\n#include <sys/shm.h>\n#include <sys/types.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <signal.h>\n\nusing namespace std;\nextern const char* theCmdlineParameter;\nextern int optind;\n\n/*=====================================\n        Global functions & variables\n ======================================*/\nProcess* theProcess = 0;\nMultiTaskProcess* theMultiTask = 0;\nstatic volatile int theSignaled = 0;\n\nstatic void signalHandler(int sig){\n\ttheSignaled = sig;\n}\n\nint main(int argc, char** argv){\n\ttry{\n\t\tsignal(SIGINT, signalHandler);\n\n\t\ttheProcess->initialize(argc, argv);\n\t\ttheProcess->run();\n\t}catch(Exception& ex){\n\t\tex.writeMessage();\n\t}\n\treturn 0;\n}\n\nuint8_t* mqcalloc(uint8_t len){\n\tuint8_t* pos = (uint8_t*)calloc(len, sizeof(uint8_t));\n\tif( pos == 0){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't allocate memory.\");\n\t}\n\treturn pos;\n}\n\n#ifdef CPU_LITTLEENDIANN\n\n/*--- For Little endianness ---*/\n\nuint16_t getUint16(uint8_t* pos){\n\tuint16_t val = ((uint16_t)*pos++ << 8);\n\treturn val += *pos;\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n    *pos++ = (val >> 8) & 0xff;\n\t*pos   = val & 0xff;\n}\n\nuint32_t getUint32(uint8_t* pos){\n    uint32_t val = (uint32_t(*pos++ <<  24));\n\tval += (uint32_t(*pos++ << 16));\n\tval += (uint32_t(*pos++ <<  8));\n\treturn val += *pos++;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n\t*pos++ = (val >> 24) & 0xff;\n\t*pos++ = (val >> 16) & 0xff;\n\t*pos++ = (val >>  8) & 0xff;\n\t*pos   =  val & 0xff;\n}\n\n#endif\n#ifdef CPU_BIGENDIANN\n/*--- For Big endianness ---*/\n\nuint16_t getUint16(uint8_t* pos){\n  uint16_t val = *pos++;\n  return val += ((uint16_t)*pos++ << 8);\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n\t*pos++ =  val & 0xff;\n\t*pos   = (val >>  8) & 0xff;\n}\n\nlong getUint32(uint8_t* pos){\n    long val = (uint32_t(*(pos + 3)) << 24) +\n        (uint32_t(*(pos + 2)) << 16) +\n        (uint32_t(*(pos + 1)) <<  8);\n        return val += *pos;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n    *pos++ =  val & 0xff;\n    *pos++ = (val >>  8) & 0xff;\n    *pos++ = (val >> 16) & 0xff;\n    *pos   = (val >> 24) & 0xff;\n}\n\n\n#endif\n\n\nvoid utfSerialize(uint8_t* pos, string str){\n\tsetUint16(pos, (uint16_t)str.size());\n\tstr.copy((char*)pos + 2, str.size(), 0);\n}\n\nchar theCurrentTime[32];\n\nchar* currentDateTime() {\n    time_t     now = time(0);\n    struct tm  tstruct;\n    tstruct = *localtime(&now);\n    strftime(theCurrentTime, sizeof(theCurrentTime), \"%Y%m%d %H%M%S\", &tstruct);\n    return theCurrentTime;\n}\n\n/*=====================================\n         Class Process\n  ======================================*/\nProcess::Process(){\n\t_argc = 0;\n\t_argv = 0;\n\t_rb = new RingBuffer();\n\t_rbsem = new Semaphore(TOMYFRAME_RB_SEMAPHOR_NAME, 0);\n}\n\nProcess::~Process(){\n\tdelete(_rb);\n\tdelete(_rbsem);\n}\n\nvoid Process::run(){\n\n}\n\nvoid Process::initialize(int argc, char** argv){\n\t_argc = argc;\n\t_argv = argv;\n}\n\nint Process::getArgc(){\n\treturn _argc;\n}\n\nchar** Process::getArgv(){\n\treturn _argv;\n}\n\nchar* Process::getArgv(char option){\n\tchar arg;\n\toptind = 1;\n\twhile((arg = getopt(_argc, _argv, theCmdlineParameter))!= -1 && (arg != 255)){\n\t\tif(arg == option){\n\t\t\treturn optarg;\n\t\t}\n\t}\n\treturn 0;\n}\n\nint Process::getParam(const char* parameter, char* value){\n\tchar str[TOMYFRAME_PARAM_MAX], param[TOMYFRAME_PARAM_MAX];\n\tFILE *fp;\n\tint i = 0, j = 0;\n\n\tif ((fp = fopen(TOMYFRAME_CONFIG_FILE, \"r\")) == NULL) {\n\t\tLOGWRITE(\"No config file:[%s]\\n\", TOMYFRAME_CONFIG_FILE);\n\t\treturn -1;\n\t}\n\n\twhile(true) {\n\t\tif (fgets(str, TOMYFRAME_PARAM_MAX - 1, fp) == NULL) {\n\t\t\tfclose(fp);\n\t\t\treturn -3;\n\t\t}\n\t\tif (!strncmp(str, parameter,strlen(parameter))) {\n\t\t\twhile (str[i++] != '=') {\n\t\t\t\t;\n\t\t\t}\n\t\t\twhile (str[i] != '\\n') {\n\t\t\t\tparam[j++] = str[i++];\n\t\t\t}\n\t\t\tparam[j] = '\\0';\n\n\t\t    for( i = strlen(param)-1; i >= 0 && isspace( param[i] ); i-- ) ;\n\t\t    param[i+1] = '\\0';\n\t\t    for( i = 0; isspace( param[i] ); i++ ) ;\n\t\t    if( i > 0 ) {\n\t\t        j = 0;\n\t\t        while( param[i] ) param[j++] = param[i++];\n\t\t        param[j] = '\\0';\n\t\t    }\n\t\t\tstrcpy(value,param);\n\t\t\tfclose(fp);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tfclose(fp);\n\treturn -2;\n}\n\n\nvoid Process::putLog(const char* format, ...){\n\t_mt.lock();\n\tva_list arg;\n\tva_start(arg, format);\n\tvsprintf(_rbdata, format, arg);\n\tva_end(arg);\n\tif(strlen(_rbdata)){\n\t\t_rb->put(_rbdata);\n\t\t_rbsem->post();\n\t}\n\t_mt.unlock();\n}\n\nconst char* Process::getLog(){\n\tint len = 0;\n\t_mt.lock();\n\twhile((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0){\n\t\t_rbsem->wait();\n\t}\n\t*(_rbdata + len) = 0;\n\t_mt.unlock();\n\treturn _rbdata;\n}\n\nvoid Process::resetRingBuffer(){\n\t_rb->reset();\n}\n\nint Process::checkSignal(){\n\treturn theSignaled;\n}\n/*=====================================\n         Class MultiTaskProcess\n  ======================================*/\nMultiTaskProcess::MultiTaskProcess(){\n\ttheMultiTask = this;\n}\n\nMultiTaskProcess::~MultiTaskProcess(){\n\n}\n\nvoid MultiTaskProcess::initialize(int argc, char** argv){\n\tProcess::initialize(argc, argv);\n\tlist<Thread*>::iterator thread = _threadList.begin();\n\twhile( thread != _threadList.end()){\n\t\t(*thread)->initialize(argc, argv);\n\t\t++thread;\n\t}\n}\n\nvoid MultiTaskProcess::run(){\n\tlist<Thread*>::iterator thread = _threadList.begin();\n\twhile(thread != _threadList.end()){\n\t\t(*thread)->start();\n\t\tthread++;\n\t}\n\n\t_stopProcessEvent.wait();\n\n\tthread = _threadList.begin();\n\twhile(thread != _threadList.end()){\n\t\t(*thread)->cancel();\n\t\t(*thread)->join();\n\t\tthread++;\n\t}\n}\n\nSemaphore* MultiTaskProcess::getStopProcessEvent(){\n\treturn &_stopProcessEvent;\n}\n\nvoid MultiTaskProcess::attach(Thread* thread){\n\t_threadList.push_back(thread);\n}\n\nchar* MultiTaskProcess::getArgv(char option){\n\t_mutex.lock();\n\tchar* arg = Process::getArgv(option);\n\t_mutex.unlock();\n\treturn arg;\n}\n\nint MultiTaskProcess::getParam(const char* parameter, char* value){\n\t_mutex.lock();\n\tint rc = Process::getParam(parameter, value);\n\t_mutex.unlock();\n\tif(rc == -1){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"No config file.\");\n\t}\n\treturn rc;\n}\n/*=====================================\n        Class Thread\n =====================================*/\nThread::Thread(){\n\t_stopProcessEvent = theMultiTask->getStopProcessEvent();\n\t_threadID = 0;\n}\n\nThread::~Thread(){\n\n}\n\nvoid* Thread::_run(void* runnable){\n\tstatic_cast<Runnable*>(runnable)->EXECRUN();\n\treturn 0;\n}\n\nvoid Thread::initialize(int argc, char** argv){\n\n}\n\npthread_t Thread::getID(){\n\treturn pthread_self();\n}\n\nbool Thread::equals(pthread_t *t1, pthread_t *t2){\n\t\treturn (pthread_equal(*t1, *t2) ? false : true);\n}\n\nint Thread::start(void){\n\tRunnable *runnable = this;\n\treturn pthread_create(&_threadID, 0, _run, runnable);\n}\n\nint Thread::join(void){\n\treturn pthread_join(_threadID, 0);\n}\n\nint Thread::cancel(void){\n\treturn pthread_cancel(_threadID);\n}\n\n\nvoid Thread::stopProcess(void){\n\t_stopProcessEvent->post();\n}\n\n/*=====================================\n        Class Mutex\n =====================================*/\n\nMutex::Mutex(void){\n\tpthread_mutexattr_t  attr;\n\tpthread_mutexattr_init(&attr);\n\tpthread_mutex_init(&_mutex, &attr);\n\tpthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);\n\t_shmid = 0;\n\t_pmutex = 0;\n}\n\nMutex::Mutex(const char* fileName){\n\tpthread_mutexattr_t  attr;\n\n\tkey_t key = ftok(fileName, 1);\n\n\tif((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0){\n\t\t//perror(\"Mutex\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t}\n\t_pmutex = (pthread_mutex_t*)shmat(_shmid, NULL, 0);\n\tif(_pmutex  < 0 ){\n\t\t//perror(\"Mutex\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't attach shared memory for Mutex.\");\n\t}\n\n\tpthread_mutexattr_init(&attr);\n\n\tif(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0) {\n\t\t//perror(\"Mutex pthread_mutexattr_setpshared\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Mutex.\");\n\t}\n\tif(pthread_mutex_init(_pmutex, &attr) != 0) {\n\t\t//perror(\"Mutex pthread_mutexattr_setpshared\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Mutex.\");\n\t}\n}\n\nMutex::~Mutex(void){\n\tif(_pmutex){\n\t\tpthread_mutex_lock(_pmutex);\n\t\tpthread_mutex_unlock(_pmutex);\n\t\tpthread_mutex_destroy(_pmutex);\n\t}else{\n\t\tpthread_mutex_lock(&_mutex);\n\t\tpthread_mutex_unlock(&_mutex);\n\t\tpthread_mutex_destroy(&_mutex);\n\t}\n\tif(_shmid){\n\t\tshmctl(_shmid, IPC_RMID, NULL);\n\t}\n}\n\nvoid Mutex::lock(void){\n\tif(_pmutex){\n\t\tpthread_mutex_lock(_pmutex);\n\t}else{\n\t\ttry{\n\t\t\tif(pthread_mutex_lock(&_mutex)){\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}catch(char* errmsg){\n\t\t\t//perror(\"Mutex\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"The same thread can't aquire a mutex twice.\");\n\t\t}\n\t}\n}\n\nvoid Mutex::unlock(void){\n\n\tif(_pmutex){\n\t\tpthread_mutex_unlock(_pmutex);\n\t}else{\n\t\ttry {\n\t\t\tif(pthread_mutex_unlock(&_mutex)){\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}catch(char* errmsg){\n\t\t\t//perror(\"Mutex\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't release a mutex.\");\n\t\t}\n\t}\n}\n\n/*=====================================\n        Class Semaphore\n =====================================*/\n\nSemaphore::Semaphore(){\n\tSemaphore(0);\n}\n\nSemaphore::Semaphore(unsigned int val){\n\tsem_init(&_sem, 0, val);\n\t_name = 0;\n\t_psem = 0;\n}\n\nSemaphore::Semaphore(const char* name,unsigned int val){\n\t_psem = sem_open(name, O_CREAT, 0666, val);\n\tif(_psem == SEM_FAILED ){\n\t\t//perror(\"Semaphore\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Semaphore.\");\n\t}\n\t_name = (char*)mqcalloc(strlen(name + 1));\n\tstrcpy(_name, name);\n}\n\nSemaphore::~Semaphore(){\n\tif(_name){\n\t\tsem_close(_psem);\n\t\tsem_unlink(_name);\n\t\tfree((void*)_name);\n\t}else{\n\t\tsem_destroy(&_sem);\n\t}\n}\n\nvoid Semaphore::post(void){\n\tint val = 0;\n\tif(_psem){\n\t\tsem_getvalue(_psem,&val);\n\t\tif(val <= 0){\n\t\t\tsem_post(_psem);\n\t\t}\n\t}else{\n\t\tsem_getvalue(&_sem,&val);\n\t\tif(val <= 0){\n\t\t\tsem_post(&_sem);\n\t\t}\n\t}\n}\n\nvoid Semaphore::wait(void){\n\tif(_psem){\n\t\tsem_wait(_psem);\n\t}else{\n\t\tsem_wait(&_sem);\n\t}\n}\n\nvoid Semaphore::timedwait(uint16_t millsec){\n\tstruct timespec ts;\n\tclock_gettime(CLOCK_REALTIME, &ts);\n\tts.tv_sec += millsec / 1000;\n\tts.tv_nsec = (millsec % 1000) * 1000000;\n\tif(_psem){\n\t\tsem_timedwait(_psem, &ts);\n\t}else{\n\t\tsem_timedwait(&_sem, &ts);\n\t}\n}\n\n/*=========================================\n             Class RingBuffer\n =========================================*/\nRingBuffer::RingBuffer(){\n\tkey_t key = ftok(TOMYFRAME_RINGBUFFER_KEY, 1);\n\n\tif((_shmid = shmget(key, RINGBUFFER_SIZE, IPC_CREAT | IPC_EXCL | 0666)) >= 0){\n\t\tif((_shmaddr = (uint16_t*)shmat(_shmid, NULL, 0)) > 0 ){\n\t\t\t_length = (uint16_t*)_shmaddr;\n\t\t\t_start = (uint16_t*)_length + sizeof(uint16_t*);\n\t\t\t_end = (uint16_t*)_start + sizeof(uint16_t*);\n\t\t\t_buffer = (char*)_end + sizeof(uint16_t*);\n\t\t\t_createFlg = true;\n\n\t\t\t*_length = RINGBUFFER_SIZE - sizeof(uint16_t*) * 3 - 16;\n\t\t\t*_start = *_end = 0;\n\t\t}else{\n\t\t\t//perror(\"RingBuffer\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't attach shared memory.\");\n\t\t}\n\t}else if((_shmid = shmget(key, RINGBUFFER_SIZE, IPC_CREAT | 0666)) >= 0){\n\t\tif((_shmaddr = (uint16_t*)shmat(_shmid, NULL, 0)) > 0 ){\n\t\t\t_length = (uint16_t*)_shmaddr;\n\t\t\t_start = (uint16_t*)_length + sizeof(uint16_t*);\n\t\t\t_end = (uint16_t*)_start + sizeof(uint16_t*);\n\t\t\t_buffer = (char*)_end + sizeof(uint16_t*);\n\t\t\t_createFlg = false;\n\t\t}else{\n\t\t\t//perror(\"RingBuffer\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t\t}\n\t}else{\n\t\t//perror(\"RingBuffer\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t}\n\n\t_pmx = new Mutex(TOMYFRAME_RB_MUTEX_KEY);\n}\n\nRingBuffer::~RingBuffer(){\n\tif(_createFlg){\n\t\tif(_shmid > 0){\n\t\t\tshmctl(_shmid, IPC_RMID, NULL);\n\t\t}\n\t\tif(_pmx > 0){\n\t\t\tdelete _pmx;\n\t\t}\n\t}else{\n\t\tif(_shmid > 0){\n\t\t\tshmdt(_shmaddr);\n\t\t}\n\t}\n}\n\nvoid RingBuffer::put(char* data){\n\t_pmx->lock();\n\n\tuint16_t dlen = strlen(data);\n\tuint16_t blen = *_length - *_end;\n\n\tif(*_end > *_start){\n\t\tif(dlen < blen){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\tif(*_end - *_start == 1){ // Buffer is empty.\n\t\t\t\t*_start = *_end;\n\t\t\t}\n\t\t\t*_end += dlen;\n\t\t}else{\n\t\t\tstrncpy(_buffer + *_end, data, blen);\n\t\t\tstrncpy(_buffer, data + blen, dlen - blen);\n\t\t\tif(*_end - *_start == 1){ // Buffer is empty.\n\t\t\t\t*_start = *_end;\n\t\t\t\t*_end = dlen - blen;\n\t\t\t}else{\n\t\t\t\t*_end = dlen - blen;\n\t\t\t\t*_start = *_end + 1;\n\t\t\t}\n\t\t}\n\t}else if(*_end == *_start){\n\t\tif(dlen < blen){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t*_end += dlen;\n\t\t}else{\n\t\t\tconst char* errmsg = \"RingBuffer Error: data is too long\";\n\t\t\tstrcpy(_buffer + *_end, errmsg);\n\t\t\t*_end += strlen(errmsg);\n\t\t}\n\t}else{    // *_end < *_start\n\t\tif(dlen < *_start - *_end){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t*_end += dlen;\n\t\t\t*_start = *_end + 1;\n\t\t}else {\n\t\t\tif( dlen < blen){\n\t\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t\t*_end += dlen;\n\t\t\t\t*_start = *_end + 1;\n\t\t\t}else {\n\t\t\t\tstrncpy(_buffer + *_end, data, blen);\n\t\t\t\tstrncpy(_buffer, data + blen, dlen - blen);\n\t\t\t\t*_start = *_end;\n\t\t\t\t*_end = dlen - blen;\n\t\t\t}\n\t\t}\n\t}\n\t_pmx->unlock();\n}\n\nint RingBuffer::get(char* buf, int length){\n\tint len = 0;\n\t_pmx->lock();\n\n\tif(*_end > *_start){\n\t\tif(length > *_end - *_start){\n\t\t\tlen = *_end - *_start;\n\t\t\tif (len == 1){\n\t\t\t\tlen = 0;\n\t\t\t}\n\t\t\tstrncpy(buf, _buffer + *_start, len);\n\t\t\t*_start = *_end - 1;\n\t\t}else{\n\t\t\tlen = length;\n\t\t\tstrncpy(buf, _buffer + *_start, len);\n\t\t\t*_start = *_start + len;\n\t\t}\n\t}else if(*_end < *_start){\n\t\tint blen = *_length - *_start;\n\t\tif(length > blen ){\n\t\t\tstrncpy(buf, _buffer + *_start, blen);\n\t\t\t*_start = 0;\n\t\t\tif(length - (blen + *_end) > 0){\n\t\t\t\tstrncpy(buf + blen , _buffer, *_end);\n\t\t\t\tlen = blen + *_end;\n\t\t\t\tif(*_end > 0){\n\t\t\t\t\t*_start = *_end - 1;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tstrncpy(buf + blen, _buffer, length - blen);\n\t\t\t\tlen = length;\n\t\t\t\t*_start = length - blen;\n\t\t\t}\n\t\t}else{\n\t\t\tstrncpy(buf, _buffer + *_start, length);\n\t\t\t*_start += length;\n\t\t\tlen = length;\n\t\t}\n\t}\n\t_pmx->unlock();\n\treturn len;\n}\n\nvoid RingBuffer::reset(){\n\t_pmx->lock();\n\t*_start = *_end = 0;\n\t_pmx->unlock();\n}\n\n/*=====================================\n        Class Exception\n ======================================*/\nException::Exception(const ExceptionType type, const int exNo, const string& message){\n\t_message = message;\n\t_type = type;\n\t_exNo = exNo;\n\t_fileName = 0;\n\t_functionName = 0;\n\t_line = 0;\n}\n\nException::Exception(const ExceptionType type, const int exNo, const string& message,\n\t\t                const char* file, const char* function, const int line){\n\t_message = message;\n\t_type = type;\n\t_exNo = exNo;\n\t_fileName = file;\n\t_functionName = function;\n\t_line = line;\n}\n\nException::~Exception() throw(){\n\n}\n\nconst char* Exception::what() const throw() {\n    return _message.c_str();\n}\n\nconst char* Exception::getFileName(){\n        return _fileName;\n}\n\nconst char* Exception::getFunctionName(){\n        return _functionName;\n}\n\nconst int Exception::getLineNo(){\n        return _line;\n}\n\nconst int Exception::getExceptionNo(){\n        return _exNo;\n}\n\nbool Exception::isFatal(){\n\treturn _type == ExFatal;\n}\n\nconst char* Exception::strType(){\n\tswitch(_type){\n\tcase ExInfo:\n\t\treturn \"Info\";\n\t\tbreak;\n\tcase ExWarn:\n\t\treturn \"Warn\";\n\t\tbreak;\n\tcase ExError:\n\t\treturn \"Error\";\n\t\tbreak;\n\tcase ExFatal:\n\t\treturn \"Fatal\";\n\t\tbreak;\n\tcase ExDebug:\n\t\treturn \"Debug\";\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn \"\";\n}\n\nvoid Exception::writeMessage(){\n\n\tfprintf(stdout, \"%s %5s:%-6d   %s  line %-4d %s() : %s\\n\",\n\t\t\tcurrentDateTime(), strType(), getExceptionNo(), getFileName(), getLineNo(), getFunctionName(), what());\n}\n\n/*=========================================\n             Class Timer\n =========================================*/\n\nTimer::Timer(){\n  stop();\n}\n\nvoid Timer::start(uint32_t msec){\n  gettimeofday(&_startTime, 0);\n  _millis = msec;\n}\n\nbool Timer::isTimeup(){\n  return isTimeup(_millis);\n}\n\nbool Timer::isTimeup(uint32_t msec){\n    struct timeval curTime;\n    long secs, usecs;\n    if (_startTime.tv_sec == 0){\n        return false;\n    }else{\n        gettimeofday(&curTime, 0);\n        secs  = (curTime.tv_sec  - _startTime.tv_sec) * 1000;\n        usecs = (curTime.tv_usec - _startTime.tv_usec) / 1000.0;\n        return ((secs + usecs) > (long)msec);\n    }\n}\n\nvoid Timer::stop(){\n  _startTime.tv_sec = 0;\n  _millis = 0;\n}\n\n"
  },
  {
    "path": "Gateway/src/lib/ProcessFramework.h",
    "content": "/*\n * ProcessFramework.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef PROCESSFRAMEWORK_H_\n#define PROCESSFRAMEWORK_H_\n\n#include <stdlib.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <semaphore.h>\n#include <list>\n#include <queue>\n#include <exception>\n#include <string>\n#include <iostream>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netdb.h>\n#include <unistd.h>\n#include <string>\n#include <arpa/inet.h>\n#include \"Defines.h\"\n#include <sys/ipc.h>\n#include <sys/sem.h>\n#include <sys/shm.h>\n\n#define TOMYFRAME_PARAM_MAX     128\n#define TOMYFRAME_CONFIG_FILE      \"/usr/local/etc/tomygateway/config/param.conf\"\n\n#define TOMYFRAME_RINGBUFFER_KEY   \"/usr/local/etc/tomygateway/config/ringbuffer.key\"\n#define TOMYFRAME_RB_MUTEX_KEY     \"/usr/local/etc/tomygateway/config/rbmutex.key\"\n#define TOMYFRAME_RB_SEMAPHOR_NAME \"/rbsemaphor\"\n\n#define LOGWRITE theProcess->putLog\n//#define LOGWRITE printf\n#define RINGBUFFER_SIZE 16384\n#define PROCESS_LOG_BUFFER_SIZE  2048\n\n#define ERRNO_SYS_01  1   // Application Frame Error\n\nusing namespace std;\n\n/*=================================\n *    Data Type\n ==================================*/\ntypedef unsigned char  uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int   uint32_t;\n\n/*=====================================\n         Class Mutex\n  ====================================*/\nclass Mutex{\npublic:\n\tMutex();\n\tMutex(const char* name);\n\t~Mutex();\n\tvoid lock(void);\n\tvoid unlock(void);\n\nprivate:\n\tpthread_mutex_t _mutex;\n\tpthread_mutex_t* _pmutex;\n\tint   _shmid;\n};\n\n/*=====================================\n         Class Semaphore\n  ====================================*/\nclass Semaphore{\npublic:\n\tSemaphore();\n\tSemaphore(unsigned int val);\n\tSemaphore(const char* name, unsigned int val);\n\t~Semaphore();\n\tvoid post(void);\n\tvoid wait(void);\n\tvoid timedwait(uint16_t millsec);\n\nprivate:\n\tsem_t* _psem;\n\tsem_t  _sem;\n\tchar*  _name;\n};\n\n/*=====================================\n         Class EventQue\n  ====================================*/\ntemplate <class T>\nclass EventQue{\npublic:\n\tEventQue();\n\t~EventQue();\n\tT*  wait(void);\n\tT*  timedwait(uint16_t millsec);\n    int post(T*);\n    int size();\n\nprivate:\n    queue<T*> _que;\n    Mutex         _mutex;\n    Semaphore     _sem;\n};\n\n/*=====================================\n        Class RingBuffer\n =====================================*/\nclass RingBuffer{\npublic:\n\tRingBuffer();\n\t~RingBuffer();\n\tvoid put(char* buffer);\n\tint get(char* buffer, int bufferLength);\n\tvoid reset();\nprivate:\n\tvoid* _shmaddr;\n\tuint16_t* _length;\n\tuint16_t* _start;\n\tuint16_t* _end;\n\tchar* _buffer;\n\tint _shmid;\n\tMutex* _pmx;\n\tbool _createFlg;\n};\n\n/*=====================================\n         Class Thread\n  ====================================*/\n#define MAGIC_WORD_FOR_TASK \\\n\tpublic: void EXECRUN(){try{run();}catch(Exception& ex){ex.writeMessage();\\\n    if(ex.isFatal()){stopProcess();}}catch(...){throw;}}\n\nclass Runnable{\npublic:\n\tRunnable(){}\n\tvirtual ~Runnable(){}\n\tvirtual void initialized(int argc, char** argv){}\n\tvirtual void EXECRUN(){}\n};\n\nclass Thread : virtual public Runnable{\npublic:\n\tThread();\n    ~Thread();\n\tint start(void);\n\tint join(void);\n\tint cancel(void);\n\tstatic pthread_t getID();\n\tstatic bool equals(pthread_t*, pthread_t*);\n\tvoid initialize(int argc, char** argv);\n\tvoid stopProcess(void);\nprivate:\n\tpthread_t _threadID;\n\tSemaphore* _stopProcessEvent;\n\tvoid (*_initializePtr)(int argc, char** argv);\n\n\tstatic void* _run(void*);\n\n};\n\n/*=====================================\n         Class Process\n  ====================================*/\nclass Process{\npublic:\n\tProcess();\n\tvirtual ~Process();\n\tvoid initialize(int argc, char** argv);\n\tvirtual void run();\n\tint getArgc();\n\tchar** getArgv();\n\tchar*  getArgv(char option);\n\tint    getParam(const char* param, char* value);\n\tvoid   putLog(const char* format, ...);\n\tvoid   resetRingBuffer();\n\tint    checkSignal();\n\tconst char*  getLog(void);\nprivate:\n\tint _argc;\n\tchar** _argv;\n\tRingBuffer* _rb;\n\tMutex _mt;\n\tSemaphore* _rbsem;\n\tchar _rbdata[PROCESS_LOG_BUFFER_SIZE + 1];\n\n};\n\nextern Process* theProcess;\n\n/*=====================================\n         Class MultiTaskProcess\n  ====================================*/\nclass MultiTaskProcess: public Process{\n\tfriend int main(int, char**);\n\tfriend class Thread;\npublic:\n\tMultiTaskProcess();\n\tvirtual ~MultiTaskProcess();\n\tvoid attach(Thread* thread);\n\tint getArgc();\n\tchar** getArgv();\n\tchar*  getArgv(char option);\n\tint    getParam(const char* param, char* value);\nprotected:\n\tvoid initialize(int argc, char** argv);\n\tvoid run();\n\tSemaphore* getStopProcessEvent();\n\nprivate:\n\tlist<Thread*> _threadList;\n\tSemaphore _stopProcessEvent;\n\tMutex  _mutex;\n};\n\nextern MultiTaskProcess* theMultiTask;\n\n\n/*=====================================\n        Class Exception\n =====================================*/\nenum ExceptionType {\n\tExInfo = 0,\n\tExWarn,\n\tExError,\n\tExFatal,\n\tExDebug\n};\n\n#define THROW_EXCEPTION(type, exceptionNo, message) \\\n\tthrow Exception(type, exceptionNo, message, __FILE__, __func__, __LINE__)\n\n\nclass Exception : public exception {\npublic:\n    Exception(const ExceptionType type, const int exNo, const string& message);\n    Exception(const ExceptionType type, const int exNo, const string& message,\n    \t\t   const char*, const char*, const int);\n    virtual ~Exception() throw();\n    const char* getFileName();\n    const char* getFunctionName();\n    const int getLineNo();\n    const int getExceptionNo();\n    virtual const char* what() const throw();\n    void writeMessage();\n    bool isFatal();\n\nprivate:\n    const char* strType();\n    ExceptionType _type;\n    int _exNo;\n    string _message;\n    const char* _fileName;\n    const char* _functionName;\n    int _line;\n};\n\n\n/*============================================\n                Timer\n ============================================*/\nclass Timer {\npublic:\n    Timer();\n    void start(uint32_t msec = 0);\n    bool isTimeup(uint32_t msec);\n    bool isTimeup(void);\n    void stop();\nprivate:\n    struct timeval _startTime;\n    uint32_t _millis;\n};\n\n/*=====================================\n        Class EventQue\n =====================================*/\ntemplate<class T> EventQue<T>::EventQue(){\n\n}\n\ntemplate<class T> EventQue<T>::~EventQue(){\n\t_mutex.lock();\n\twhile(!_que.empty()){\n\t\tdelete _que.front();\n\t\t_que.pop();\n\t}\n\t_mutex.unlock();\n}\n\ntemplate<class T> T* EventQue<T>::wait(void){\n\tT* ev;\n\t_sem.wait();\n\t_mutex.lock();\n\tev = _que.front();\n\t_que.pop();\n\t_mutex.unlock();\n\treturn ev;\n}\n\ntemplate<class T> T* EventQue<T>::timedwait(uint16_t millsec){\n\tT* ev;\n\t_sem.timedwait(millsec);\n\t_mutex.lock();\n\n\tif(_que.empty()){\n\t\tev = new T();\n\t\tev->setTimeout();\n\t}else{\n\t\tev = _que.front();\n\t\t_que.pop();\n\t}\n\t_mutex.unlock();\n\treturn ev;\n}\n\ntemplate<class T> int EventQue<T>::post(T* ev){\n\t_mutex.lock();\n\t_que.push(ev);\n\t_mutex.unlock();\n\t_sem.post();\n\treturn 0;\n}\n\ntemplate<class T> int EventQue<T>::size(){\n\t_mutex.lock();\n\tint sz = _que.size();\n\t_mutex.unlock();\n\treturn sz;\n}\n\n\n#endif /* PROCESSFRAMEWORK_H_ */\n"
  },
  {
    "path": "Gateway/src/lib/TCPStack.cpp",
    "content": "/*\n * Socket.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n#include \"TCPStack.h\"\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <iostream>\n#include <sys/socket.h>\n#include <netdb.h>\n#include <errno.h>\n\nusing namespace std;\nextern char* currentDateTime();\n\n/*========================================\n       Class TCPStack\n =======================================*/\nTCPStack::TCPStack(){\n    _addrinfo = 0;\n    _disconReq = false;\n    _sockfd = -1;\n}\n\nTCPStack::~TCPStack(){\n    if(_addrinfo){\n\t\tfreeaddrinfo(_addrinfo);\n\t}\n}\n\nbool TCPStack::isValid(){\n\tif(_sockfd > 0){\n\t\tif(_disconReq){\n\t\t\tclose();\n\t\t\t_sem.post();\n\t\t}else{\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nvoid TCPStack::disconnect(){\n    if ( _sockfd > 0 ){\n    \t_disconReq = true;\n    \t_sem.wait();\n    }\n}\n\nvoid TCPStack::close(){\n\tif(_sockfd > 0){\n\t\t::close(_sockfd);\n\t\t_sockfd = -1;\n\t\t_disconReq = false;\n\t\tif(_addrinfo){\n\t\t\tfreeaddrinfo(_addrinfo);\n\t\t\t_addrinfo = 0;\n\t\t}\n\t}\n}\n\nbool TCPStack::bind ( const char* service ){\n\tif(isValid()){\n\t\treturn false;\n\t}\n\taddrinfo hints;\n\tmemset(&hints, 0, sizeof(addrinfo));\n\thints.ai_family = AF_INET;\n\thints.ai_socktype = SOCK_STREAM;\n    hints.ai_flags = AI_PASSIVE;\n\n\tif (_addrinfo){\n\t\tfreeaddrinfo(_addrinfo);\n\t}\n\tint err = getaddrinfo(0, service, &hints, &_addrinfo);\n    if (err) {\n    \tLOGWRITE(\"\\n%s   \\x1b[0m\\x1b[31merror:\\x1b[0m\\x1b[37mgetaddrinfo(): %s\\n\", currentDateTime(),gai_strerror(err));\n        return false;\n    }\n\n\t_sockfd = socket(_addrinfo->ai_family, _addrinfo->ai_socktype, _addrinfo->ai_protocol);\n    if (_sockfd < 0){\n    \treturn false;\n\t}\n\tint on = 1;\n\tif ( setsockopt ( _sockfd, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ){\n\t\treturn false;\n\t}\n\n\tif( ::bind ( _sockfd, _addrinfo->ai_addr,  _addrinfo->ai_addrlen ) <0){\n\t    return false;\n\t}\n\treturn true;\n}\n\nbool TCPStack::listen() {\n\tif ( !isValid() ){\n\t    return false;\n\t}\n\tint listen_return = ::listen ( _sockfd, SOCKET_MAXCONNECTIONS );\n\tif ( listen_return == -1 ){\n\t    return false;\n\t}\n\treturn true;\n}\n\n\nbool TCPStack::accept ( TCPStack& new_socket ){\n\tsockaddr_storage sa;\n\tsocklen_t len = sizeof ( sa );\n\tnew_socket._sockfd = ::accept ( _sockfd, (struct sockaddr*) &sa,  &len );\n\tif ( new_socket._sockfd <= 0 ){\n\t\treturn false;\n\t}else{\n\t\treturn true;\n\t}\n}\n\nint TCPStack::send (const uint8_t* buf, uint16_t length  ){\n\treturn ::send ( _sockfd, buf, length, MSG_NOSIGNAL );\n}\n\nint TCPStack::recv ( uint8_t* buf, uint16_t len ){\n\treturn ::recv ( _sockfd, buf, len, 0 );\n}\n\n\nbool TCPStack::connect ( const char* host, const char* service ){\n\tif(isValid()){\n\t\treturn false;\n\t}\n\taddrinfo hints;\n\tmemset(&hints, 0, sizeof(addrinfo));\n\thints.ai_family = AF_INET;\n\thints.ai_socktype = SOCK_STREAM;\n\tif (_addrinfo){\n\t\tfreeaddrinfo(_addrinfo);\n\t}\n\n\tint err = getaddrinfo(host, service, &hints, &_addrinfo);\n    if (err) {\n    \tLOGWRITE(\"\\n%s   \\x1b[0m\\x1b[31merror:\\x1b[0m\\x1b[37mgetaddrinfo(): %s\\n\", currentDateTime(),gai_strerror(err));\n        return false;\n    }\n\n\tint sockfd = socket(_addrinfo->ai_family, _addrinfo->ai_socktype, _addrinfo->ai_protocol);\n\n    if (sockfd < 0){\n    \treturn false;\n\t}\n\tint on = 1;\n\n\tif ( setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ){\n\t\treturn false;\n\t}\n\n\tif( ::connect (sockfd, _addrinfo->ai_addr,  _addrinfo->ai_addrlen ) <0){\n\t\t//perror(\"TCPStack connect\");\n\t\t::close(sockfd);\n\t    return false;\n\t}\n\n\t_sockfd = sockfd;\n\treturn true;\n}\n\nvoid TCPStack::setNonBlocking ( const bool b ){\n\tint opts;\n\n\topts = fcntl ( _sockfd, F_GETFL );\n\n\tif ( opts < 0 ){\n\t    return;\n\t}\n\n\tif ( b ){\n\t    opts = ( opts | O_NONBLOCK );\n\t}else{\n\t    opts = ( opts & ~O_NONBLOCK );\n\t}\n\tfcntl ( _sockfd,  F_SETFL,opts );\n}\n"
  },
  {
    "path": "Gateway/src/lib/TCPStack.h",
    "content": "/*\n * TCPStack.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef TCPSTACK_H\n#define TCPSTACK_H\n\n\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netdb.h>\n#include <unistd.h>\n#include <string>\n#include <arpa/inet.h>\n#include \"Defines.h\"\n#include \"Messages.h\"\n\n#define SOCKET_MAXCONNECTIONS  5\n#define SOCKET_MAXBUFFER_LENGTH 1280 // buffer size\n\nusing namespace std;\n\n/*========================================\n       Class TCPStack\n =======================================*/\nclass TCPStack{\npublic:\n\tTCPStack();\n\tvirtual ~TCPStack();\n\tvoid disconnect();\n\n\t// Server initialization\n\tbool bind( const char* service );\n\tbool listen();\n\tbool accept( TCPStack& );\n\n\t// Client initialization\n\tbool connect( const char* host, const char* service );\n\n\tint send( const uint8_t* buf, uint16_t length );\n\tint  recv ( uint8_t* buf, uint16_t len );\n\tvoid close();\n\n\tvoid setNonBlocking( const bool );\n\n\tbool isValid();\n\tint getSock(){return _sockfd;}\nprivate:\n\tint _sockfd;\n\taddrinfo* _addrinfo;\n\tSemaphore _sem;\n\tbool   _disconReq;\n\n};\n\n\n\n#endif /* TCPSTACK_H */\n"
  },
  {
    "path": "Gateway/src/lib/TLSStack.cpp",
    "content": "/*\n * TLSStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n#include \"TLSStack.h\"\n#include <string.h>\n#include <openssl/ssl.h>\n#include <openssl/err.h>\n#include <openssl/rand.h>\n\nusing namespace std;\n\nint TLSStack::_numOfInstance = 0;\nSSL_CTX* TLSStack::_ctx = 0;\nSSL_SESSION* TLSStack::_session = 0;\n\n/*========================================\n       Class TLSStack\n =======================================*/\nTLSStack::TLSStack(){\n    TLSStack(true);\n}\n\nTLSStack::TLSStack(bool secure):TCPStack(){\n\tchar error[256];\n\tif(secure){\n\t    _numOfInstance++;\n\t\tif(_ctx == 0){\n\t\t\tSSL_load_error_strings();\n\t\t\tSSL_library_init();\n\t\t\t_ctx = SSL_CTX_new(TLSv1_2_client_method());\n\t\t\tif(_ctx == 0){\n\t\t\t\tERR_error_string_n(ERR_get_error(), error, sizeof(error));\n\t\t\t\tLOGWRITE(\"SSL_CTX_new() %s\\n\",error);\n\t\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't create SSL context.\");\n\t\t\t}\n\t\t\tif(!SSL_CTX_load_verify_locations(_ctx, 0,TLS_CA_DIR)){\n\t\t\t\tERR_error_string_n(ERR_get_error(), error, sizeof(error));\n\t\t\t\tLOGWRITE(\"SSL_CTX_load_verify_locations() %s\\n\",error);\n\t\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't load CA_LIST.\");\n\t\t\t}\n\t\t}\n\t}\n    _ssl = 0;\n    _disconReq = false;\n    _secureFlg = secure;\n    _busy = false;\n}\n\nTLSStack::~TLSStack(){\n\tif(_secureFlg){\n\t\t_numOfInstance--;\n\t}\n    if(_ssl){\n\t\tSSL_free(_ssl);\n\t}\n    if(_session && _numOfInstance == 0){\n    \tSSL_SESSION_free(_session);\n    \t_session = 0;\n    }\n    if(_ctx && _numOfInstance == 0){\n    \tSSL_CTX_free(_ctx);\n    \t_ctx = 0;\n        ERR_free_strings();\n    }\n}\n\nbool TLSStack::connect ( const char* host, const char* service ){\n\tchar errmsg[256];\n\tint rc = 0;\n\tchar peer_CN[256];\n\tSSL_SESSION* sess = 0;\n\tX509* peer;\n\n\tif(isValid()){\n\t\treturn false;\n\t}\n\tif(!TCPStack::connect(host, service)){\n\t\treturn false;\n\t}\n\tif(!_secureFlg){\n\t\treturn true;\n\t}\n\n\tSSL* ssl = SSL_new(_ctx);\n\tif(ssl == 0){\n\t\tERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));\n\t\tLOGWRITE(\"SSL_new()  %s\\n\",errmsg);\n\t\treturn false;\n\t}\n\n\trc = SSL_set_fd(ssl, TCPStack::getSock());\n\tif(rc == 0){\n\t\tSSL_free(ssl);\n\t\treturn false;\n\t}\n\n\tif(_session){\n\t\trc = SSL_set_session(ssl, sess);\n\t}else{\n\t\trc = SSL_connect(ssl);\n\t}\n\tif(rc != 1){\n\t\tERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));\n\t\tLOGWRITE(\"SSL_connect() %s\\n\",errmsg);\n\t\tSSL_free(ssl);\n\t\treturn false;\n\t}\n\n\tif(SSL_get_verify_result(ssl) != X509_V_OK){\n\t\tLOGWRITE(\"SSL_get_verify_result() error: Certificate doesn't verify.\\n\");\n\t\tSSL_free(ssl);\n\t\treturn false;\n\t}\n\n\tpeer = SSL_get_peer_certificate(ssl);\n\tX509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);\n\tif(strcasecmp(peer_CN, host)){\n\t\tLOGWRITE(\"SSL_get_peer_certificate() error: Broker dosen't much host name.\\n\");\n\t\tSSL_free(ssl);\n\t\treturn false;\n\t}\n\tif(_session == 0){\n\t\t_session = sess;\n\t}\n\t_ssl = ssl;\n\treturn true;\n}\n\n\nint TLSStack::send (const uint8_t* buf, uint16_t length  ){\n\tchar errmsg[256];\n\tfd_set rset;\n\tfd_set wset;\n\tbool writeBlockedOnRead = false;\n\tint bpos = 0;\n\n\tif(_secureFlg){\n\t\t_mutex.lock();\n\t\t_busy = true;\n\n\t\twhile(true){\n\t\t\tFD_ZERO(&rset);\n\t\t\tFD_ZERO(&wset);\n\t\t\tFD_SET(getSock(), &rset);\n\t\t\tFD_SET(getSock(), &wset);\n\n\t\t\tint activity =  select( getSock() + 1 , &rset , &wset , 0 , 0);\n\t\t\tif (activity > 0){\n\t\t\t\tif(FD_ISSET(getSock(),&wset) ||\n\t\t\t\t\t(writeBlockedOnRead && FD_ISSET(getSock(),&rset))){\n\n\t\t\t\t\twriteBlockedOnRead = false;\n\t\t\t\t\tint r = SSL_write(_ssl, buf + bpos, length);\n\n\t\t\t\t\tswitch(SSL_get_error(_ssl, r)){\n\t\t\t\t\tcase SSL_ERROR_NONE:\n\t\t\t\t\t\tlength -= r;\n\t\t\t\t\t\tbpos += r;\n\t\t\t\t\t\tif( length == 0){\n\t\t\t\t\t\t\t_busy = false;\n\t\t\t\t\t\t\t_mutex.unlock();\n\t\t\t\t\t\t\treturn bpos;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SSL_ERROR_WANT_WRITE:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SSL_ERROR_WANT_READ:\n\t\t\t\t\t\twriteBlockedOnRead = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));\n\t\t\t\t\t\tLOGWRITE(\"TLSStack::send() default %s\\n\",errmsg);\n\t\t\t\t\t\t_busy = false;\n\t\t\t\t\t\t_mutex.unlock();\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}else{\n\t\treturn TCPStack::send (buf, length);\n\t}\n}\n\n\nint TLSStack::recv ( uint8_t* buf, uint16_t len ){\n\tchar errmsg[256];\n\tbool writeBlockedOnRead = false;\n\tbool readBlockedOnWrite = false;\n\tbool readBlocked = false;\n\tint rlen = 0;\n\tint bpos = 0;\n\tfd_set rset;\n\tfd_set wset;\n\n\n\tif(_secureFlg){\n\t\tif(_busy){\n\t\t\treturn 0;\n\t\t}\n\t\t_mutex.lock();\n\t\t_busy = true;\n\n\tloop:\n\t\tdo{\n\t\t\treadBlockedOnWrite = false;\n\t\t\treadBlocked = false;\n\n\t\t\trlen = SSL_read(_ssl, buf + bpos, len - bpos);\n\n\t\t\tswitch (SSL_get_error(_ssl, rlen)){\n\t\t\t\tcase SSL_ERROR_NONE:\n\t\t\t\t\t_busy = false;\n\t\t\t\t\t_mutex.unlock();\n\t\t\t\t\treturn rlen + bpos;\n\t\t\t\t\tbreak;\n\t\t\t\tcase SSL_ERROR_ZERO_RETURN:\n\t\t\t\t\tSSL_shutdown(_ssl);\n\t\t\t\t\t_ssl = 0;\n\t\t\t\t\tTCPStack::close();\n\t\t\t\t\t_busy = false;\n\t\t\t\t\t_mutex.unlock();\n\t\t\t\t\treturn -1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase SSL_ERROR_WANT_READ:\n\t\t\t\t\treadBlocked = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase SSL_ERROR_WANT_WRITE:\n\t\t\t\t\treadBlockedOnWrite = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));\n\t\t\t\t\tLOGWRITE(\"TLSStack::recv() default %s\\n\", errmsg);\n\t\t\t\t\t_busy = false;\n\t\t\t\t\t_mutex.unlock();\n\t\t\t\t\treturn -1;\n\t\t\t}\n\t\t}while(SSL_pending(_ssl) && !readBlocked);\n\n\t\tbpos += rlen;\n\t\twhile(true){\n\t\t\tFD_ZERO(&rset);\n\t\t\tFD_ZERO(&wset);\n\t\t\tFD_SET(getSock(), &rset);\n\t\t\tFD_SET(getSock(), &wset);\n\n\t\t\tint activity =  select( getSock() + 1 , &rset , &wset , 0 , 0);\n\t\t\tif (activity > 0){\n\t\t\t\tif((FD_ISSET(getSock(),&rset) && !writeBlockedOnRead) ||\n\t\t\t\t\t(readBlockedOnWrite && FD_ISSET(getSock(),&wset))){\n\t\t\t\t\tgoto loop;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));\n\t\t\t\tLOGWRITE(\"TLSStack::recv() select %s\\n\",errmsg);\n\t\t\t\t_busy = false;\n\t\t\t\t_mutex.unlock();\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\treturn TCPStack::recv (buf, len);\n}\n\n\nbool TLSStack::isValid(){\n\tif(!_secureFlg){\n\t\treturn TCPStack::isValid();\n\t}\n\tif(_ssl){\n\t\tif(_disconReq){\n\t\t\tSSL_shutdown(_ssl);\n\t\t\t_ssl = 0;\n\t\t\tTCPStack::close();\n\t\t\t_disconReq = false;\n\t\t}else{\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nvoid TLSStack::disconnect(){\n    if (_ssl){\n    \t_disconReq = true;\n    \tTCPStack::disconnect();\n    }else{\n    \tTCPStack::disconnect();\n    }\n}\n\n\nint TLSStack::getSock(){\n\treturn TCPStack::getSock();\n}\n\nSSL* TLSStack::getSSL(){\n\tif(_secureFlg){\n\t\treturn _ssl;\n\t}else{\n\t\treturn 0;\n\t}\n}\n\nbool TLSStack::isSecure(){\n\treturn _secureFlg;\n}\n"
  },
  {
    "path": "Gateway/src/lib/TLSStack.h",
    "content": "/*\n * TLSStack.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef TLSSTACK_H\n#define TLSSTACK_H\n\n#include <sys/types.h>\n#include <openssl/ssl.h>\n#include <openssl/err.h>\n#include <string>\n#include \"Defines.h\"\n#include \"Messages.h\"\n#include \"TCPStack.h\"\n\n#define TLS_CA_DIR      \"/etc/ssl/certs\"\n\nusing namespace std;\n\n/*========================================\n       Class TLSStack\n =======================================*/\nclass TLSStack:public TCPStack{\npublic:\n\tTLSStack();\n\tTLSStack(bool secure);\n\tvirtual ~TLSStack();\n\n\tbool connect( const char* host, const char* service );\n\tvoid disconnect();\n\tint send( const uint8_t* buf, uint16_t length );\n\tint  recv ( uint8_t* buf, uint16_t len );\n\n\tbool isValid();\n\tbool isSecure();\n\tint  getSock();\n\tSSL* getSSL();\nprivate:\n\tstatic SSL_CTX* _ctx;\n\tstatic int  _numOfInstance;\n\tstatic SSL_SESSION* _session;\n\n\tSSL*     _ssl;\n\tbool   _secureFlg;\n\tbool   _disconReq;\n\tMutex _mutex;\n\tbool  _busy;\n};\n\n\n\n#endif /* TLSSTACK_H */\n"
  },
  {
    "path": "Gateway/src/lib/Topics.cpp",
    "content": "/*\n * Topics.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Topics.h\"\n#include \"Messages.h\"\n#include <string>\n\nextern uint16_t getUint16(uint8_t* pos);\n\n/*=====================================\n        Class Topic\n ======================================*/\nTopic::Topic(){\n    _topicId = 0;\n}\n\n\nTopic::Topic(string topic){\n\t_topicId = 0;\n\t_topicStr = topic;\n}\n\n\nTopic::~Topic(){\n\n}\n\nuint16_t Topic::getTopicId(){\n    return _topicId;\n}\n\nstring* Topic::getTopicName(){\n    return &_topicStr;\n}\n\nuint8_t Topic::getTopicLength(){\n    return (uint8_t)_topicStr.size();\n}\n\nvoid Topic::setTopicId(uint16_t id){\n    _topicId = id;\n}\n\n\nvoid Topic::setTopicName(string topic){\n    _topicStr = topic;\n}\n\n\nuint8_t Topic::isWildCard(uint8_t* pos){\n\tunsigned int p = _topicStr.find(\"MQTTSN_TOPIC_SINGLE_WILDCARD\", 0);\n\tif( p != string::npos){\n\t\t*pos = p;\n\t\treturn MQTTSN_TOPIC_SINGLE_WILDCARD;\n\t}else{\n\t\tp = _topicStr.find(\"MQTTSN_TOPIC_MULTI_WILDCARD\", 0);\n\t\tif( p != string::npos){\n\t\t\t*pos = p;\n\t\t\treturn MQTTSN_TOPIC_MULTI_WILDCARD;\n\t\t}\n\t}\n\t*pos = 0;\n    return 0;\n}\n\nbool Topic::isMatch(Topic* topic){\n    uint8_t pos;\n    uint8_t pos1;\n\n    if (topic->isWildCard(&pos) == MQTTSN_TOPIC_SINGLE_WILDCARD &&\n        (_topicStr.compare(0, (unsigned int)pos, (const string)*(topic->getTopicName()), 0, (unsigned int)pos) == 0 )){\n    \t\tpos1 = pos + 2;\n    \t\tpos = _topicStr.find(\"/\", ++pos);\n\n    \tif(pos == string::npos ){\n    \t\treturn true;\n    \t}else{\n    \t\tif(_topicStr.substr(pos) == topic->getTopicName()->substr(pos1)){\n    \t\t\treturn true;\n    \t\t}else{\n    \t\t\treturn false;\n    \t\t}\n    \t}\n\n    }else if(topic->isWildCard(&pos) == MQTTSN_TOPIC_MULTI_WILDCARD &&\n    \t\t(_topicStr.compare(0, (unsigned int)pos, (const string)*(topic->getTopicName()), 0, (unsigned int)pos) == 0 )){\n        return true;\n    }\n    return false;\n}\n\n/*=====================================\n        Class Topics\n ======================================*/\nTopics::Topics(){\n\tTopic* tp = new Topic(string(MQTTSN_TOPIC_PREDEFINED_TIME));\n\ttp->setTopicId(MQTTSN_TOPICID_PREDEFINED_TIME);\n\t_topics.push_back(tp);\n\t_cnt = 1;\n\t_nextTopicId = MQTTSN_TOPICID_NORMAL;\n}\n\nTopics::~Topics() {\n\tfor (uint8_t i = 0; i < _topics.size(); i++) {\n\t    if(_topics[i]){\n\t    \tdelete _topics[i];\n\t    }\n\t}\n}\n\n\nuint16_t Topics::getTopicId(string* topic){\n    Topic *p = getTopic(topic);\n    if ( p != 0) {\n        return p->getTopicId();\n    }\n    return 0;\n}\n\n\nTopic* Topics::getTopic(string* topic) {\n    for (uint8_t i = 0; i < _cnt; i++) {\n    \tif(_topics[i]){\n\t\t\tif( *topic == *(_topics[i]->getTopicName())){\n\t\t\t\treturn _topics[i];\n\t\t\t}\n    \t}\n    }\n    return 0;\n}\n\nTopic* Topics::getTopic(uint16_t id) {\n    for (uint8_t i = 0; i < _cnt; i++) {\n    \tif(_topics[i]){\n\t\t\tif ( _topics[i]->getTopicId() == id) {\n\t\t\t\treturn _topics[i];\n\t\t\t}\n    \t}\n    }\n    return 0;\n}\n\n\nuint16_t Topics::createTopic(string* topic){\n    if (!getTopic(topic)){\n        if ( _cnt < MAX_TOPIC_COUNT){\n        \tTopic* tp = new Topic();\n        \ttp->setTopicName(*topic);\n        \tif(tp->getTopicLength() == 2){\n        \t\tuint16_t id = getUint16((uint8_t*)tp->getTopicName());\n        \t\ttp->setTopicId(id);\n        \t}else{\n        \t\ttp->setTopicId(getNextTopicId());\n        \t}\n        \t_topics.push_back(tp);\n        \t_cnt++;\n        \treturn _nextTopicId;\n        }else{\n        \treturn 0;\n        }\n    }else{\n    \treturn getTopicId(topic);\n    }\n}\n\nuint16_t Topics::getNextTopicId(){\n\tif(++_nextTopicId <  MQTTSN_TOPICID_NORMAL){\n\t\t_nextTopicId = MQTTSN_TOPICID_NORMAL;\n\t}\n\treturn _nextTopicId;\n}\n\nTopic* Topics::match(string* topic){\n\tuint8_t pos;\n\n    for ( uint8_t i = 0; i< _cnt; i++){\n    \tif(_topics[i]){\n\t\t\tif ( _topics[i]->isWildCard(&pos)){\n\t\t\t\tif (getTopic(topic)->isMatch(_topics[i])){\n\t\t\t\t\treturn _topics[i];\n\t\t\t\t}\n\t\t\t}\n    \t}\n    }\n    return 0;\n}\n\n\n"
  },
  {
    "path": "Gateway/src/lib/Topics.h",
    "content": "/*\n * Topics.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef TOPICS_H_\n#define TOPICS_H_\n\n#include \"ProcessFramework.h\"\n#include \"Messages.h\"\n#include <stdlib.h>\n\n#define MQTTSN_TOPIC_MULTI_WILDCARD   '#'\n#define MQTTSN_TOPIC_SINGLE_WILDCARD  '+'\n\n#define MQTTSN_TOPICID_NORMAL 256\n#define MQTTSN_TOPICID_PREDEFINED_TIME   0x0001\n#define MQTTSN_TOPIC_PREDEFINED_TIME     (\"$GW/01\")\n\n#define MAX_TOPIC_COUNT   50        // Number of Topic Par ClientNode\n\n/*=====================================\n        Class Topic\n======================================*/\n\nclass Topic {\npublic:\n    Topic();\n    Topic(string topic);\n    ~Topic();\n    uint16_t  getTopicId();\n    uint8_t   getTopicLength();\n    string*  getTopicName();\n    void     setTopicId(uint16_t id);\n    void     setTopicName(string topic);\n\n    uint8_t isWildCard(uint8_t* pos);\n    bool    isMatch(Topic* wildCard);\nprivate:\n    uint16_t  _topicId;\n    string _topicStr;\n};\n\n/*=====================================\n        Class Topics\n ======================================*/\nclass Topics {\npublic:\n      Topics();\n      ~Topics();\n      uint16_t  createTopic(string* topic);\n      uint16_t  getTopicId(string* topic);\n      uint16_t  getNextTopicId();\n      Topic*    getTopic(string* topic);\n      Topic*    getTopic(uint16_t topicId);\n      Topic*    match(string* topic);\n      bool     deleteTopic(string* topic);\n\nprivate:\n    uint16_t _nextTopicId;\n    uint8_t  _cnt;\n    vector<Topic*>  _topics;\n\n};\n\n#endif /* TOPICS_H_ */\n"
  },
  {
    "path": "Gateway/src/lib/UDPStack.cpp",
    "content": "/*\n * UDPStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n\n#ifdef NETWORK_UDP\n\n#include <stdio.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <netinet/ip.h>\n#include <netdb.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <termios.h>\n#include \"ProcessFramework.h\"\n#include \"UDPStack.h\"\n\nusing namespace std;\nusing namespace tomyGateway;\n\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=========================================\n       Class Network\n =========================================*/\nNetwork::Network(){\n}\n\nNetwork::~Network(){\n\n}\n\nvoid Network::unicast(NWAddress64* addr64, uint16_t addr16, uint8_t* payload, uint16_t payloadLength){\n\tUDPPort::unicast(payload, payloadLength, addr64->getLsb(), addr16);\n}\n\nvoid Network::broadcast(uint8_t* payload, uint16_t payloadLength){\n\tUDPPort::multicast(payload, payloadLength);\n}\n\nbool Network::getResponse(NWResponse* response){\n\tuint32_t ipAddress = 0;\n\tuint16_t portNo = 0;\n\tuint16_t msgLen;\n\tuint8_t  msgType;\n\n\tuint8_t* buf = response->getPayloadPtr();\n\tuint16_t recvLen = UDPPort::recv(buf, MQTTSN_MAX_FRAME_SIZE, &ipAddress, &portNo);\n\tif(recvLen < 0){\n\t\treturn false;\n\t}else{\n\t\tif(buf[0] == 0x01){\n\t\t\tmsgLen = getUint16(buf + 1);\n\t\t\tmsgType = *(buf + 3);\n\t\t}else{\n\t\t\tmsgLen = (uint16_t)*(buf);\n\t\t\tmsgType = *(buf + 1);\n\t\t}\n\t\tif(msgLen != recvLen){\n\t\t\treturn false;\n\t\t}\n\t\tresponse->setLength(msgLen);\n\t\tresponse->setMsgType(msgType);\n\t\tresponse->setClientAddress16(portNo);\n\t\tresponse->setClientAddress64(0, ipAddress);\n\t\treturn true;\n\t}\n}\n\nint Network::initialize(UdpConfig  config){\n\treturn UDPPort::open(config);\n}\n\n\n/*=========================================\n       Class udpStack\n =========================================*/\n\nUDPPort::UDPPort(){\n    _disconReq = false;\n    _sockfdUnicast = -1;\n    _sockfdMulticast = -1;\n\t_gPortNo = 0;\n\t_gIpAddr = 0;\n\n}\n\nUDPPort::~UDPPort(){\n    close();\n}\n\nvoid UDPPort::close(){\n\tif(_sockfdUnicast > 0){\n\t\t::close( _sockfdUnicast);\n\t\t_sockfdUnicast = -1;\n\t}\n\tif(_sockfdMulticast > 0){\n\t\t::close( _sockfdMulticast);\n\t\t_sockfdMulticast = -1;\n\t}\n}\n\nint UDPPort::open(UdpConfig config){\n\tchar loopch = 0;\n\tconst int reuse = 1;\n\n\tif(config.uPortNo == 0 || config.gPortNo == 0){\n\t\treturn -1;\n\t}\n\t_gPortNo = htons(config.gPortNo);\n\t_gIpAddr = inet_addr(config.ipAddress);\n\n\t/*------ Create unicast socket --------*/\n\t_sockfdUnicast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n\tif (_sockfdUnicast < 0){\n\t\treturn -1;\n\t}\n\n\tsetsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));\n\n\tsockaddr_in addru;\n\taddru.sin_family = AF_INET;\n\taddru.sin_port = htons(config.uPortNo);\n\taddru.sin_addr.s_addr = INADDR_ANY;\n\n\tif( ::bind ( _sockfdUnicast, (sockaddr*)&addru,  sizeof(addru)) <0){\n\t\treturn -1;\n\t}\n\tif(setsockopt(_sockfdUnicast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){\n\t\tD_NWSTACK(\"error IP_MULTICAST_LOOP in UDPPort::open\\n\");\n\t\tclose();\n\t\treturn -1;\n\t}\n\n\t/*------ Create Multicast socket --------*/\n\t_sockfdMulticast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n\tif (_sockfdMulticast < 0){\n\t\tclose();\n\t\treturn -1;\n\t}\n\n\tsetsockopt(_sockfdMulticast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));\n\n\tsockaddr_in addrm;\n\taddrm.sin_family = AF_INET;\n\taddrm.sin_port = _gPortNo;\n\taddrm.sin_addr.s_addr = INADDR_ANY;\n\n\tif( ::bind ( _sockfdMulticast, (sockaddr*)&addrm,  sizeof(addrm)) <0){\n\t\treturn -1;\n\t}\n\tif(setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){\n\t\tD_NWSTACK(\"error IP_MULTICAST_LOOP in UDPPort::open\\n\");\n\t\tclose();\n\t\treturn -1;\n\t}\n\n\tip_mreq mreq;\n\tmreq.imr_interface.s_addr = INADDR_ANY;\n\tmreq.imr_multiaddr.s_addr = _gIpAddr;\n\n\tif( setsockopt(_sockfdMulticast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))< 0){\n\t\tD_NWSTACK(\"error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\\n\");\n\t\tperror(\"multicast\");\n\t\tclose();\n\t\treturn -1;\n\t}\n\n\tif( setsockopt(_sockfdUnicast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))< 0){\n\t\tD_NWSTACK(\"error Unicast IP_ADD_MEMBERSHIP in UDPPort::open\\n\");\n\t\tclose();\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n\nint UDPPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port  ){\n\tsockaddr_in dest;\n\tdest.sin_family = AF_INET;\n\tdest.sin_port = port;\n\tdest.sin_addr.s_addr = ipAddress;\n\n\tint status = ::sendto( _sockfdUnicast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );\n\tif( status < 0){\n\t\tD_NWSTACK(\"errno == %d in UDPPort::sendto\\n\", errno);\n\t}\n\tD_NWSTACK(\"sendto %s:%u length = %d\\n\",inet_ntoa(dest.sin_addr), htons(port), status);\n\treturn status;\n}\n\nint UDPPort::multicast( const uint8_t* buf, uint32_t length ){\n\treturn unicast(buf, length,_gIpAddr, _gPortNo);\n}\n\nint UDPPort::recv(uint8_t* buf, uint16_t len, uint32_t* ipAddressPtr, uint16_t* portPtr){\n\tfd_set recvfds;\n\tint maxSock = 0;\n\n\tFD_ZERO(&recvfds);\n\tFD_SET(_sockfdUnicast, &recvfds);\n\tFD_SET(_sockfdMulticast, &recvfds);\n\n\tif(_sockfdMulticast > _sockfdUnicast){\n\t\tmaxSock = _sockfdMulticast;\n\t}else{\n\t\tmaxSock = _sockfdUnicast;\n\t}\n\n\tselect(maxSock + 1, &recvfds, 0, 0, 0);\n\n\tif(FD_ISSET(_sockfdUnicast, &recvfds)){\n\t\treturn recvfrom (_sockfdUnicast,buf, len, 0,ipAddressPtr, portPtr );\n\t}else if(FD_ISSET(_sockfdMulticast, &recvfds)){\n\t\treturn recvfrom (_sockfdMulticast,buf, len, 0,ipAddressPtr, portPtr );\n\t}\n\treturn 0;\n}\n\nint UDPPort::recvfrom (int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){\n\tsockaddr_in sender;\n\tsocklen_t addrlen = sizeof(sender);\n\tmemset(&sender, 0, addrlen);\n\n\tint status = ::recvfrom( sockfd, buf, len, flags, (sockaddr*)&sender, &addrlen );\n\n\tif ( status < 0 && errno != EAGAIN )\t{\n\t\tD_NWSTACK(\"errno == %d in UDPPort::recvfrom\\n\", errno);\n\t\treturn -1;\n\t}\n\t*ipAddressPtr = (uint32_t)sender.sin_addr.s_addr;\n\t*portPtr = (uint16_t)sender.sin_port;\n\tD_NWSTACK(\"recved from %s:%d length = %d\\n\",inet_ntoa(sender.sin_addr),htons(*portPtr),status);\n\treturn status;\n}\n\n\n/*=========================================\n             Class NLLongAddress\n =========================================*/\nNWAddress64::NWAddress64(){\n    _msb = _lsb = 0;\n}\n\nNWAddress64::NWAddress64(uint32_t msb, uint32_t lsb){\n    _msb = msb;\n    _lsb = lsb;\n}\n\nuint32_t NWAddress64::getMsb(){\n    return _msb;\n}\n\nuint32_t NWAddress64::getLsb(){\n    return _lsb;\n}\n\nvoid NWAddress64::setMsb(uint32_t msb){\n    _msb = msb;\n}\n\nvoid NWAddress64::setLsb(uint32_t lsb){\n    _lsb = lsb;\n}\n\nbool NWAddress64::operator==(NWAddress64& addr){\n\tif(_msb == addr.getMsb() && _lsb == addr.getLsb()){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\n/*=========================================\n             Class ZBResponse\n =========================================*/\nNWResponse::NWResponse(){\n    _addr16 = 0;\n    memset( _frameDataPtr, 0, MQTTSN_MAX_FRAME_SIZE);\n}\n\nuint8_t  NWResponse::getFrameLength(){\n\treturn _len;\n}\n\nvoid NWResponse::setLength(uint16_t len){\n\t_len = len;\n}\n\nNWAddress64*  NWResponse::getClientAddress64(){\n    return &_addr64;\n}\n\nuint16_t NWResponse::getClientAddress16(){\n  return _addr16;\n}\n\nvoid  NWResponse::setClientAddress64(uint32_t msb, uint32_t lsb){\n    _addr64.setMsb(msb);\n    _addr64.setLsb(lsb);\n}\n\nvoid  NWResponse::setClientAddress16(uint16_t addr16){\n\t_addr16 = addr16;\n}\n\nvoid NWResponse::setMsgType(uint8_t type){\n\t_type = type;\n}\n\n\nuint8_t NWResponse::getMsgType(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr[3];\n\t}else{\n\t\treturn _frameDataPtr[1];\n\t}\n}\n\nuint8_t* NWResponse::getBody(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr + 4;\n\t}else{\n\t\treturn _frameDataPtr + 2;\n\t}\n}\n\nuint16_t NWResponse::getBodyLength(){\n\tif(_len > 255){\n\t\treturn getPayloadLength() - 4;\n\t}else{\n\t\treturn getPayloadLength() - 2;\n\t}\n}\n\nuint8_t NWResponse::getPayload(uint8_t index){\n\t\treturn _frameDataPtr[index + 2];\n\n}\n\nuint8_t* NWResponse::getPayloadPtr(){\n\n\t\treturn _frameDataPtr;\n\n}\n\nuint8_t NWResponse::getPayloadLength(){\n\n\treturn _len;\n}\n\n#endif /* NETWORK_UDP */\n"
  },
  {
    "path": "Gateway/src/lib/UDPStack.h",
    "content": "/*\r\n * UDPStack.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified:\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 0.0.0\r\n */\r\n\r\n#ifndef UDPSTACK_H_\r\n#define UDPSTACK_H_\r\n\r\n#include \"Defines.h\"\r\n#ifdef NETWORK_UDP\r\n\r\n#include \"ProcessFramework.h\"\r\n#include <sys/time.h>\r\n#include <iostream>\r\n#include <sys/types.h>\r\n#include <sys/socket.h>\r\n#include <netinet/in.h>\r\n#include <netdb.h>\r\n#include <unistd.h>\r\n#include <string>\r\n#include <arpa/inet.h>\r\n\r\n/*\r\n *   MQTTS  Client's state\r\n */\r\n#define MQTTS_DEVICE_DISCONNECTED     0\r\n#define MQTTS_DEVICE_ACTIVE           1\r\n#define MQTTS_DEVICE_ASLEEP           2\r\n#define MQTTS_DEVICE_AWAKE            3\r\n#define MQTTS_DEVICE_LOST             4\r\n\r\n#define MQTTSN_MAX_FRAME_SIZE      1024\r\n\r\nusing namespace std;\r\n\r\nnamespace tomyGateway{\r\n/*============================================\r\n              NWAddress64\r\n =============================================*/\r\nclass NWAddress64 {\r\npublic:\r\n\tNWAddress64(uint32_t msb, uint32_t lsb);\r\n\tNWAddress64(void);\r\n\tuint32_t getMsb();\r\n\tuint32_t getLsb();\r\n\tvoid setMsb(uint32_t msb);\r\n\tvoid setLsb(uint32_t lsb);\r\n\tbool operator==(NWAddress64&);\r\nprivate:\r\n\tuint32_t _msb;\r\n\tuint32_t _lsb;\r\n};\r\n\r\n/*============================================\r\n               NWResponse\r\n =============================================*/\r\n\r\nclass NWResponse {\r\npublic:\r\n\tNWResponse();\r\n\tuint8_t  getMsgType();\r\n\tuint8_t  getFrameLength();\r\n\tuint8_t  getPayload(uint8_t index);\r\n\tuint8_t* getPayloadPtr();\r\n\tuint8_t* getBody();\r\n\tuint16_t getBodyLength();\r\n\tuint8_t  getPayloadLength();\r\n\tuint16_t getClientAddress16();\r\n\tNWAddress64* getClientAddress64();\r\n\r\n\tvoid setLength(uint16_t len);\r\n  \tvoid setMsgType(uint8_t type);\r\n\tvoid setClientAddress64(uint32_t msb, uint32_t ipAddress);\r\n\tvoid setClientAddress16(uint16_t portNo);\r\nprivate:\r\n\tNWAddress64 _addr64;\r\n\tuint16_t _addr16;\r\n\tuint16_t _len;\r\n\tuint8_t  _type;\r\n\tuint8_t _frameDataPtr[MQTTSN_MAX_FRAME_SIZE];\r\n};\r\n\r\n\r\n/*========================================\r\n       Class UpdPort\r\n =======================================*/\r\nclass UDPPort{\r\npublic:\r\n\tUDPPort();\r\n\tvirtual ~UDPPort();\r\n\r\n\tint open(UdpConfig config);\r\n\r\n\tint unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port  );\r\n\tint multicast( const uint8_t* buf, uint32_t length );\r\n\tint recv(uint8_t* buf, uint16_t len, uint32_t* ipaddress, uint16_t* port );\r\n\r\nprivate:\r\n\tvoid close();\r\n\tvoid setNonBlocking( const bool );\r\n\tint recvfrom (int sockfd, uint8_t* buf, uint16_t len, uint8_t flags, uint32_t* ipaddress, uint16_t* port );\r\n\r\n\tint _sockfdUnicast;\r\n\tint _sockfdMulticast;\r\n\r\n\tuint16_t _gPortNo;\r\n\tuint32_t _gIpAddr;\r\n\tbool    _disconReq;\r\n\r\n};\r\n\r\n/*===========================================\r\n               Class  Network\r\n ============================================*/\r\nclass Network:public UDPPort{\r\npublic:\r\n    Network();\r\n    ~Network();\r\n\r\n    void unicast(NWAddress64* addr64, uint16_t addr16,\tuint8_t* payload, uint16_t payloadLength);\r\n\tvoid broadcast(uint8_t* payload, uint16_t payloadLength);\r\n\tbool getResponse(NWResponse* response);\r\n    int  initialize(UdpConfig  config);\r\n\r\nprivate:\r\n\r\n};\r\n\r\n\r\n}    /* end of namespace */\r\n\r\n#endif /* NETWORK_UDP */\r\n#endif  /* UDPSTACK_H_ */\r\n"
  },
  {
    "path": "Gateway/src/lib/XXXXXStack.cpp",
    "content": "/*\n * XXXXXStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n\n#ifdef NETWORK_XXXXX\n\n#include <stdio.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <sys/socket.h>\n#include <netdb.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <termios.h>\n#include \"ProcessFramework.h\"\n#include \"XXXXXStack.h\"\n\nusing namespace std;\nusing namespace tomyGateway;\n\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=========================================\n       Class Network\n =========================================*/\nNetwork::Network(){\n}\n\nNetwork::~Network(){\n\n}\n\nvoid Network::unicast(NWAddress64* addr64, uint16_t addr16, uint8_t* payload, uint16_t payloadLength){\n\tXXXXXPort::unicast( );\n}\n\nvoid Network::broadcast(uint8_t* payload, uint16_t payloadLength){\n\tXXXXXPort::multicast( );\n}\n\nbool Network::getResponse(NWResponse* response){\n\n}\n\nint Network::initialize(XXXXXConfig  config){\n\treturn XXXXXPort::initialize(config);\n}\n\n\n/*=========================================\n       Class XXXXXPort\n =========================================*/\n\nXXXXXPort::XXXXXPort(){\n\n\n}\n\nXXXXXPort::~XXXXXPort(){\n    close();\n}\n\nvoid XXXXXPort::close(){\n\n}\n\nint XXXXXPort::initialize(){\n\treturn initialize(_config);\n}\n\nint XXXXXPort::initialize(UdpConfig config){\n\n\t_config.param1 = config.param1;\n\t_config.param2 = config.param2;\n\t_config.param3 = config.param3;\n\n\n}\n\n\nint XXXXXPort::unicast( ){\n\n}\n\nint XXXXXPort::multicast(){\n\n}\n\nint XXXXXPort::recv(){\n\n}\n\n\n/*=========================================\n             Class NLLongAddress\n =========================================*/\nNWAddress64::NWAddress64(){\n    _msb = _lsb = 0;\n}\n\nNWAddress64::NWAddress64(uint32_t msb, uint32_t lsb){\n    _msb = msb;\n    _lsb = lsb;\n}\n\nuint32_t NWAddress64::getMsb(){\n    return _msb;\n}\n\nuint32_t NWAddress64::getLsb(){\n    return _lsb;\n}\n\nvoid NWAddress64::setMsb(uint32_t msb){\n    _msb = msb;\n}\n\nvoid NWAddress64::setLsb(uint32_t lsb){\n    _lsb = lsb;\n}\n\nbool NWAddress64::operator==(NWAddress64& addr){\n\tif(_msb == addr.getMsb() && _lsb == addr.getLsb()){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n\n/*=========================================\n             Class ZBResponse\n =========================================*/\nNWResponse::NWResponse(){\n    _addr16 = 0;\n    memset( _frameDataPtr, 0, MQTTSN_MAX_FRAME_SIZE);\n}\n\nuint8_t  NWResponse::getFrameLength(){\n\treturn _len;\n}\n\nvoid NWResponse::setLength(uint16_t len){\n\t_len = len;\n}\n\nNWAddress64*  NWResponse::getClientAddress64(){\n    return &_addr64;\n}\n\nuint16_t NWResponse::getClientAddress16(){\n  return _addr16;\n}\n\nvoid  NWResponse::setClientAddress64(uint32_t msb, uint32_t lsb){\n    _addr64.setMsb(msb);\n    _addr64.setLsb(lsb);\n}\n\nvoid  NWResponse::setClientAddress16(uint16_t addr16){\n\t_addr16 = addr16;\n}\n\nvoid NWResponse::setMsgType(uint8_t type){\n\t_type = type;\n}\n\n\nuint8_t NWResponse::getMsgType(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr[3];\n\t}else{\n\t\treturn _frameDataPtr[1];\n\t}\n}\n\nuint8_t* NWResponse::getBody(){\n\tif(_len > 255){\n\t\treturn _frameDataPtr + 4;\n\t}else{\n\t\treturn _frameDataPtr + 2;\n\t}\n}\n\nuint16_t NWResponse::getBodyLength(){\n\tif(_len > 255){\n\t\treturn getPayloadLength() - 4;\n\t}else{\n\t\treturn getPayloadLength() - 2;\n\t}\n}\n\nuint8_t NWResponse::getPayload(uint8_t index){\n\t\treturn _frameDataPtr[index + 2];\n\n}\n\nuint8_t* NWResponse::getPayloadPtr(){\n\n\t\treturn _frameDataPtr;\n\n}\n\nuint8_t NWResponse::getPayloadLength(){\n\n\treturn _len;\n}\n\n#endif /* NETWORK_XXXXX */\n"
  },
  {
    "path": "Gateway/src/lib/XXXXXStack.h",
    "content": "/*\r\n * UDPStack.h\r\n *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified:\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 0.0.0\r\n */\r\n\r\n#ifndef XXXXXSTACK_H_\r\n#define XXXXXSTACK_H_\r\n\r\n#include \"Defines.h\"\r\n#ifdef NETWORK_XXXXX\r\n\r\n#include \"ProcessFramework.h\"\r\n#include <sys/time.h>\r\n#include <iostream>\r\n#include <sys/types.h>\r\n#include <sys/socket.h>\r\n#include <netinet/in.h>\r\n#include <netdb.h>\r\n#include <unistd.h>\r\n#include <string>\r\n#include <arpa/inet.h>\r\n\r\n/*\r\n *   MQTTS  Client's state\r\n */\r\n#define MQTTS_DEVICE_DISCONNECTED     0\r\n#define MQTTS_DEVICE_ACTIVE           1\r\n#define MQTTS_DEVICE_ASLEEP           2\r\n#define MQTTS_DEVICE_AWAKE            3\r\n#define MQTTS_DEVICE_LOST             4\r\n\r\n#define MQTTSN_MAX_FRAME_SIZE      1024\r\n\r\nusing namespace std;\r\n\r\nnamespace tomyGateway{\r\n/*============================================\r\n              NWAddress64\r\n =============================================*/\r\nclass NWAddress64 {\r\npublic:\r\n\tNWAddress64(uint32_t msb, uint32_t lsb);\r\n\tNWAddress64(void);\r\n\tuint32_t getMsb();\r\n\tuint32_t getLsb();\r\n\tvoid setMsb(uint32_t msb);\r\n\tvoid setLsb(uint32_t lsb);\r\n\tbool operator==(NWAddress64&);\r\nprivate:\r\n\tuint32_t _msb;\r\n\tuint32_t _lsb;\r\n};\r\n\r\n/*============================================\r\n               NWResponse\r\n =============================================*/\r\n\r\nclass NWResponse {\r\npublic:\r\n\tNWResponse();\r\n\tuint8_t  getMsgType();\r\n\tuint8_t  getFrameLength();\r\n\tuint8_t  getPayload(uint8_t index);\r\n\tuint8_t* getPayloadPtr();\r\n\tuint8_t* getBody();\r\n\tuint16_t getBodyLength();\r\n\tuint8_t  getPayloadLength();\r\n\tuint16_t getClientAddress16();\r\n\tNWAddress64* getClientAddress64();\r\n\r\n\tvoid setLength(uint16_t len);\r\n  \tvoid setMsgType(uint8_t type);\r\n\tvoid setClientAddress64(uint32_t msb, uint32_t ipAddress);\r\n\tvoid setClientAddress16(uint16_t portNo);\r\nprivate:\r\n\tNWAddress64 _addr64;\r\n\tuint16_t _addr16;\r\n\tuint16_t _len;\r\n\tuint8_t  _type;\r\n\tuint8_t _frameDataPtr[MQTTSN_MAX_FRAME_SIZE];\r\n};\r\n\r\n\r\n/*========================================\r\n       Class XXXXXPort\r\n =======================================*/\r\nclass XXXXXPort{\r\npublic:\r\n\tXXXXXPort();\r\n\tvirtual ~XXXXXPort();\r\n\r\n\tint initialize(XXXXXConfig config);\r\n    int initialize();\r\n\r\n\tint unicast(  );\r\n\tint multicast(  );\r\n\tint recv( );\r\n\r\nprivate:\r\n\tvoid close();\r\n\r\n\tXXXXXConfig _config;\r\n\r\n};\r\n\r\n/*===========================================\r\n               Class  Network\r\n ============================================*/\r\nclass Network:public XXXXXPort{\r\npublic:\r\n    Network();\r\n    ~Network();\r\n\r\n    void unicast(NWAddress64* addr64, uint16_t addr16,\tuint8_t* payload, uint16_t payloadLength);\r\n\tvoid broadcast(uint8_t* payload, uint16_t payloadLength);\r\n\tbool getResponse(NWResponse* response);\r\n    int  initialize(XXXXXConfig  config);\r\n\r\nprivate:\r\n\r\n};\r\n\r\n\r\n}    /* end of namespace */\r\n\r\n#endif /* NETWORK_UDP */\r\n#endif  /* UDPSTACK_H_ */\r\n"
  },
  {
    "path": "Gateway/src/lib/ZBStack.cpp",
    "content": "/*\n * ZBeeStack.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"Defines.h\"\n#ifdef  NETWORK_XBEE\n\n#include \"Messages.h\"\n#include \"ZBStack.h\"\n#include \"ProcessFramework.h\"\n#include <stdio.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <termios.h>\n\nusing namespace std;\n\nextern uint8_t* mqcalloc(uint8_t length);\nextern uint16_t getUint16(uint8_t* pos);\nextern uint32_t getUint32(uint8_t* pos);\nextern void setUint16(uint8_t* pos, uint16_t val);\nextern void setUint32(uint8_t* pos, uint32_t val);\n\n/*=========================================\n             Class NWAddress64\n =========================================*/\nNWAddress64::NWAddress64(){\n  _msb = _lsb = 0;\n}\n\nNWAddress64::NWAddress64(uint32_t msb, uint32_t lsb){\n  _msb = msb;\n  _lsb = lsb;\n}\n\nuint32_t NWAddress64::getMsb(){\n  return _msb;\n}\n\nuint32_t NWAddress64::getLsb(){\n  return _lsb;\n}\n\nvoid NWAddress64::setMsb(uint32_t msb){\n  _msb = msb;\n}\n\nvoid NWAddress64::setLsb(uint32_t lsb){\n  _lsb = lsb;\n}\n\nbool NWAddress64::operator==(NWAddress64& addr){\n\tif(_msb == addr.getMsb() && _lsb == addr.getLsb()){\n\t\treturn true;\n\t}else{\n\t\treturn false;\n\t}\n}\n/*=========================================\n             Class NWBResponse\n =========================================*/\nNWResponse::NWResponse(){\n\t_frameDataPtr = 0;\n\t_msbLength = 0;\n\t_lsbLength = 0;\n\t_checksum = 0;\n\t_frameLength = 0;\n\t_errorCode = NO_ERROR;\n\t_complete = false;\n\t_apiId = 0;\n}\n\nNWResponse::~NWResponse(){\n  if(_frameDataPtr){\n\t  free(_frameDataPtr);\n  }\n}\n\nuint8_t NWResponse::getMsbLength(){\n  return _msbLength;\n}\n\nuint8_t NWResponse::getLsbLength(){\n  return _lsbLength;\n}\n\nuint8_t NWResponse::getChecksum(){\n  return _checksum;\n}\n\nuint8_t NWResponse::getFrameDataLength(){\n  return _frameLength;\n}\n\nuint8_t* NWResponse::getFrameData(){\n  return _frameDataPtr;\n}\n\nuint16_t NWResponse::getPacketLength() {\n        return ((_msbLength << 8) & 0xff) + (_lsbLength & 0xff);\n}\n\nvoid NWResponse::setMsbLength(uint8_t msbLength){\n  _msbLength = msbLength;\n}\n\nvoid NWResponse::setLsbLength(uint8_t lsbLength){\n  _lsbLength = lsbLength;\n}\n\nvoid NWResponse::setChecksum(uint8_t checksum){\n  _checksum = checksum;\n}\n\nvoid NWResponse::setFrameDataLength(uint8_t frameLength){\n  _frameLength = frameLength;\n}\nvoid NWResponse::setFrameData(uint8_t *frameDataPtr){\n  _frameDataPtr = frameDataPtr;\n}\n\nbool NWResponse::isAvailable(){\n  return _complete;\n}\n\nvoid NWResponse::setAvailable(bool complete){\n  _complete = complete;\n}\n\nbool NWResponse::isError(){\n  return _errorCode > 0;\n}\n\nuint8_t NWResponse::getErrorCode(){\n  return _errorCode;\n}\n\nvoid NWResponse::setErrorCode(uint8_t errorCode){\n  _errorCode = errorCode;\n}\n\nvoid NWResponse::setApiId(uint8_t apiId){\n  _apiId = apiId;\n}\n\nvoid NWResponse::reset(){\n\tif(_frameDataPtr){\n\t\t  free(_frameDataPtr);\n\t}\n\t_msbLength = 0;\n\t_lsbLength = 0;\n\t_checksum = 0;\n\t_frameLength = 0;\n\t_errorCode = NO_ERROR;\n_complete = false;\n}\n\nuint8_t NWResponse::getPayload(int index){\n  return getFrameData()[ZB_PAYLOAD_OFFSET + index];\n}\n\nuint8_t* NWResponse::getPayloadPtr(){\n  return getFrameData() + ZB_PAYLOAD_OFFSET;\n}\n\nuint8_t NWResponse::getPayloadLength(){\n  return getFrameDataLength() - ZB_PAYLOAD_OFFSET;\n}\n\nuint16_t NWResponse::getClientAddress16(){\n\treturn getUint16(getFrameData() + 8);\n}\n\n\nuint32_t NWResponse::getRemoteAddressMsb(){\n\treturn getUint32(getFrameData());\n}\n\nuint32_t NWResponse::getRemoteAddressLsb(){\n\treturn getUint32(getFrameData() + 4);\n}\n\nNWAddress64* NWResponse::getClientAddress64(){\n\treturn &_addr64;\n}\n\nuint8_t NWResponse::getOption(){\n  return getFrameData()[10];\n}\n\nuint8_t NWResponse::getType(){\n\tif(_frameLength > 255){\n\t\treturn getPayload(3);\n\t}else{\n\t\treturn getPayload(1);\n\t}\n}\nuint8_t NWResponse::getApiId(){\n  return _apiId;\n}\n\nuint8_t NWResponse::getMsgType(){\n  return getPayloadPtr()[1];\n}\n\nbool NWResponse::isBroadcast(){\n  return ( getOption() && 0x02);\n}\n\nvoid NWResponse::absorb(NWResponse* resp){\n\tif(_frameDataPtr){\n\t\tfree(_frameDataPtr);\n\t}\n\t_apiId = resp->getApiId();\n\t_msbLength = resp->getMsbLength();\n\t_lsbLength = resp->getLsbLength();\n\t_checksum = resp->getChecksum();\n\t_frameLength = resp->getFrameDataLength();\n\t_errorCode = resp->getErrorCode();\n\t_complete = resp->isAvailable();\n\t_addr64.setMsb(resp->getRemoteAddressMsb());\n\t_addr64.setLsb(resp->getRemoteAddressLsb());\n\t_frameDataPtr = mqcalloc(resp->getFrameDataLength());\n\tmemcpy(_frameDataPtr, resp->getFrameData(), resp->getFrameDataLength());\n}\n\n/*=========================================\n             Class NWRequest\n =========================================*/\n\nNWRequest::NWRequest(){\n\t_apiId = 0x10;\n\t_addr16 = 0;\n\t_broadcastRadius = 0;\n\t_option = 0;\n\t_payloadPtr = 0;\n\t_payloadLength = 0;\n}\n\n\nNWRequest::~NWRequest(){\n\n}\n\nNWAddress64& NWRequest::getAddress64(){\n    return _addr64;\n}\n\nuint16_t NWRequest::getAddress16(){\n    return _addr16;\n}\n\nuint8_t NWRequest::getApiId(){\n    return _apiId;\n}\n\nuint8_t NWRequest::getBroadcastRadius(){\n    return _broadcastRadius;\n}\n\nuint8_t  NWRequest::getOption(){\n    return _option;\n}\n\nuint8_t*  NWRequest::getPayloadPtr(){\n    return _payloadPtr;\n}\n\nuint8_t  NWRequest::getPayloadLength(){\n  return _payloadLength;\n}\n\nvoid NWRequest::setClientAddress64(NWAddress64* addr64){\n\t_addr64.setMsb(addr64->getMsb());\n\t_addr64.setLsb(addr64->getLsb());\n}\n\nvoid NWRequest::setClientAddress16(uint16_t addr16){\n    _addr16 = addr16;\n}\n\nvoid NWRequest::setBroadcastRadius(uint8_t broadcastRadius){\n    _broadcastRadius = broadcastRadius;\n}\n\nvoid NWRequest::setOption(uint8_t option){\n    _option = option;\n}\n\nvoid NWRequest::setApiId(uint8_t apiId){\n    _apiId = apiId;\n}\n\nvoid NWRequest::setPayload(uint8_t* payload){\n    _payloadPtr = payload;\n}\n\nvoid NWRequest::setPayloadLength(uint8_t payloadLength){\n    _payloadLength = payloadLength;\n}\n\n\nuint8_t NWRequest::getFrameData(uint8_t pos){\n\tuint8_t buf[4];\n\n\tif (pos == 0){\n\t\treturn 0;    // Frame ID\n\t}else if (pos == 1){\n\t\tsetUint32(buf, _addr64.getMsb());\n\t\treturn buf[0];\n\t}else if (pos == 2){\n\t\tsetUint32(buf, _addr64.getMsb());\n\t\treturn buf[1];\n\t}else if (pos == 3){\n\t\tsetUint32(buf, _addr64.getMsb());\n\t\treturn buf[2];\n\t}else if (pos == 4){\n\t\tsetUint32(buf, _addr64.getMsb());\n\t\treturn buf[3];\n\t}else if (pos == 5){\n\t\tsetUint32(buf, _addr64.getLsb());\n\t\treturn buf[0];\n\t}else if (pos == 6){\n\t\tsetUint32(buf, _addr64.getLsb());\n\t\treturn buf[1];\n\t}else if (pos == 7){\n\t\tsetUint32(buf, _addr64.getLsb());\n\t\treturn buf[2];\n\t}else if (pos == 8){\n\t\tsetUint32(buf, _addr64.getLsb());\n\t\treturn buf[3];\n\t}else if (pos == 9){\n\t\tsetUint16(buf,_addr16);\n\t\treturn buf[0];\n\t}else if (pos == 10){\n\t\tsetUint16(buf,_addr16);\n\t\treturn buf[1];\n\t}else if (pos == 11){\n\t\treturn _broadcastRadius;\n\t}else if (pos == 12){\n\t\treturn _option;\n\t}\n\treturn getPayloadPtr()[pos - ZB_TX_API_LENGTH -1 ];\n}\n\nuint8_t NWRequest::getFrameDataLength(){\n    return ZB_TX_API_LENGTH + 1 + getPayloadLength();\n}\n\n\n/*=========================================\n             Class XBee\n =========================================*/\n\nXBee::XBee(){\n\t_pos = 0;\n\t_escape = false;\n\t_checksumTotal = 0;\n\t_response.setFrameData(mqcalloc(MAX_FRAME_DATA_SIZE));\n\t_serialPort = new SerialPort();\n\t_bd = 0;\n}\n\nXBee::~XBee(){\n\n}\n\nint XBee::initialize(XBeeConfig  config){\n\treturn _serialPort->open(config);\n}\n\nvoid XBee::readPacket(){\n\n\twhile(read(&_bd)){\n\t  // Check Start Byte\n\t  if( _pos > 0 && _bd == START_BYTE){\n\t\t  _pos = 0;\n\t  }\n\t  // Check ESC\n\t  if(_pos > 0 && _bd == ESCAPE){\n\t\t  if(read(&_bd )){\n\t\t\t  _bd = 0x20^_bd;  // decode\n\t\t  }else{\n\t\t\t  _escape = true;\n\t\t\t  continue;\n\t\t  }\n\t  }\n\n\t  if(_escape){\n\t\t  _bd = 0x20 ^ _bd;\n\t\t  _escape = false;\n\t  }\n\n\t  if(_pos >= API_ID_INDEX){\n\t\t  _checksumTotal+= _bd;\n\t  }\n\t  switch(_pos){\n\t\tcase 0:\n\t\t  if(_bd == START_BYTE){\n\t\t\t  _pos++;\n\t\t  }\n\t\t  break;\n\t\tcase 1:\n\t\t  _response.setMsbLength(_bd);\n\t\t  _pos++;\n\t\t  break;\n\t\tcase 2:\n\t\t  _response.setLsbLength(_bd);\n\t\t  _pos++;\n\t\t  D_NWSTACK(\"\\r\\n===> Recv start: \");\n\t\t  break;\n\t\tcase 3:\n\t\t  _response.setApiId(_bd);\n\t\t  _pos++;\n\t\t  break;\n\t\tdefault:\n\t\t  if(_pos > MAX_FRAME_DATA_SIZE){\n\t\t\t  _response.setErrorCode(PACKET_EXCEEDS_BYTE_ARRAY_LENGTH);\n\t\t\t  return;\n\t\t  }else if(_pos == (_response.getPacketLength() + 3)){  // 3 = 2(packet len) + 1(checksum)\n\t\t\t  if((_checksumTotal & 0xff) == 0xff){\n\t\t\t\t  _response.setChecksum(_bd);\n\t\t\t\t  _response.setAvailable(true);\n\t\t\t\t  _response.setErrorCode(NO_ERROR);\n\t\t\t  }else{\n\t\t\t\t  _response.setErrorCode(CHECKSUM_FAILURE);\n\t\t\t  }\n\t\t\t  _response.setFrameDataLength(_pos - 4);    // 4 = 2(packet len) + 1(Api) + 1(checksum)\n\t\t\t  _pos = 0;\n\t\t\t  _checksumTotal = 0;\n\t\t\t  return;\n\t\t  }else{\n\t\t\t  uint8_t* buf = _response.getFrameData();\n\t\t\t  buf[_pos - 4] = _bd;\n\t\t\t  _pos++;\n\t\t\t  if (_response.getApiId() == XB_RX_RESPONSE && _pos == 15){\n\t\t\t\t  D_NWSTACK( \"\\r\\n     Payload: \");\n\t\t\t  }\n\t\t  }\n\t\t  break;\n\t  }\n\t}\n}\n\nbool XBee::receiveResponse(NWResponse* response){\n\n    while(true){\n    \treadPacket();\n\n        if(_response.isAvailable()){\n        \tD_NWSTACK(\"\\r\\n<=== CheckSum OK\\r\\n\\n\");\n\t\t\tresponse->absorb(&_response);\n            return true;\n\n        }else if(_response.isError()){\n        \tD_NWSTACK(\"\\r\\n<=== Packet Error Code = %d\\r\\n\\n\",_response.getErrorCode());\n\t\t\t_response.reset();\n\t\t\tresponse->reset();\n            return false;\n        }\n    }\n    return false;\n}\n\n\nvoid XBee::sendRequest(NWRequest &request){\n\tD_NWSTACK(\"\\r\\n===> Send start: \");\n\n\tsendByte(START_BYTE, false);\n\n\tuint8_t msbLen = ((request.getFrameDataLength() + 1) >> 8) & 0xff; // 1 = 1B(Api)  except Checksum\n\tuint8_t lsbLen = (request.getFrameDataLength() + 1) & 0xff;\n\tsendByte(msbLen, true);\n\tsendByte(lsbLen, true);\n\n\tsendByte(request.getApiId(), true);\n\n\tuint8_t checksum = 0;\n\tchecksum+= request.getApiId();\n\n\tfor( int i = 0; i < request.getFrameDataLength(); i++ ){\n\t  if (request.getApiId() == XB_TX_REQUEST && i == 13){\n\t\t  D_NWSTACK(\"\\r\\n     Payload:    \");\n\t  }\n\t  sendByte(request.getFrameData(i), true);\n\t  checksum+= request.getFrameData(i);\n\t}\n\tchecksum = 0xff - checksum;\n\tsendByte(checksum, true);\n\n\t//flush();  // clear receive buffer\n\n\tD_NWSTACK(\"\\r\\n<=== Send completed\\r\\n\\n\" );\n}\n\nvoid XBee::sendByte(uint8_t b, bool escape){\n\tif(escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)){\n\t  write(ESCAPE);\n\t  write(b ^ 0x20);\n\t}else{\n\t  write(b);\n\t}\n}\n\nvoid XBee::resetResponse(){\n\t_pos = 0;\n\t_escape = 0;\n\t_response.reset();\n}\n\nvoid XBee::flush(){\n\t_serialPort->flush();\n}\n\nbool XBee::write(uint8_t val){\n\treturn (_serialPort->send(val) ? true : false );\n}\n\nbool XBee::read(uint8_t *buff){\n\treturn  _serialPort->recv(buff);\n}\n\n/*===========================================\n              Class  Network\n ============================================*/\nNetwork::Network(){\n\n}\n\nNetwork::~Network(){\n\n}\n\nvoid Network::unicast(NWAddress64* addr64, uint16_t addr16,\n\t\tuint8_t* payload, uint16_t payloadLength ){\n\n\t_txRequest.setClientAddress64(addr64);\n\t_txRequest.setClientAddress16(addr16);\n\t_txRequest.setOption(0);\n\t_txRequest.setPayload(payload);\n\t_txRequest.setPayloadLength(payloadLength);\n\tsendRequest(_txRequest);\n}\n\nvoid Network::broadcast(uint8_t* payload, uint16_t payloadLength){\n\tNWAddress64 addr;\n\taddr.setMsb(0);\n\taddr.setLsb(XB_BROADCAST_ADDRESS32);\n\tunicast(&addr, XB_BROADCAST_ADDRESS16, payload, payloadLength);\n}\n\nbool Network::getResponse(NWResponse* response){\n\treturn receiveResponse(response);\n}\n\nint Network::initialize(NETWORK_CONFIG config){\n\treturn XBee::initialize(config);\n}\n\n/*=========================================\n       Class SerialPort\n =========================================*/\nSerialPort::SerialPort(){\n    _tio.c_iflag = IGNBRK | IGNPAR;\n    _tio.c_cflag = CS8 | CLOCAL | CREAD | CRTSCTS;\n    _tio.c_cc[VINTR] = 0;\n    _tio.c_cc[VTIME] = 0;\n    _tio.c_cc[VMIN] = 1;\n    _fd = 0;\n}\n\nSerialPort::~SerialPort(){\n\t  if (_fd){\n\t\t  close(_fd);\n\t  }\n}\n\nint SerialPort::open(XBeeConfig config){\n  return open(config.device, config.baudrate, false, 1, config.flag);\n}\n\nint SerialPort::open(const char* devName, unsigned int baudrate,  bool parity, unsigned int stopbit, unsigned int flg){\n\t_fd = ::open(devName, flg | O_NOCTTY);\n\tif(_fd < 0){\n\t  return _fd;\n\t}\n\n\tif (parity){\n\t  _tio.c_cflag = _tio.c_cflag | PARENB;\n\t}\n\tif (stopbit == 2){\n\t  _tio.c_cflag = _tio.c_cflag | CSTOPB ;\n\t}\n\tswitch(baudrate){\n\tcase B9600:\n\tcase B19200:\n\tcase B38400:\n\tcase B57600:\n\tcase B115200:\n\t  if( cfsetspeed(&_tio, baudrate)<0){\n\t\treturn errno;\n\t  }\n\t  break;\n\tdefault:\n\t  return -1;\n\t}\n\treturn tcsetattr(_fd, TCSANOW, &_tio);\n}\n\nbool SerialPort::send(unsigned char b){\n\tif (write(_fd, &b,1) != 1){\n\t    return false;\n\t}else{\n\t\tD_NWSTACK( \" %02x\", b);\n\t    return true;\n\t}\n}\n\nbool SerialPort::recv(unsigned char* buf){\n\tif(read(_fd, buf, 1) == 0){\n\t    return false;\n\t}else{\n\t\tD_NWSTACK( \" %02x\",buf[0] );\n\t    return true;\n\t}\n}\n\nvoid SerialPort::flush(void){\n\ttcsetattr(_fd, TCSAFLUSH, &_tio);\n}\n\n#endif /* NETWORK_XBEE */\n"
  },
  {
    "path": "Gateway/src/lib/ZBStack.h",
    "content": "/*\r\n * ZBStack.h\r\n  *\r\n *                      The BSD License\r\n *\r\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\r\n *                    All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without modification,\r\n * are permitted provided that the following conditions are met:\r\n *\r\n * 1. Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimer.\r\n *\r\n * 2. Redistributions in binary form must reproduce the above copyright notice,\r\n *    this list of conditions and the following disclaimer in the documentation\r\n *   and/or other materials provided with the distribution.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r\n * THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *  Created on: 2014/06/01\r\n *    Modified:\r\n *      Author: Tomoaki YAMAGUCHI\r\n *     Version: 0.0.0\r\n */\r\n\r\n#ifndef ZBSTACK_H_\r\n#define ZBSTACK_H_\r\n\r\n#include \"Defines.h\"\r\n#ifdef NETWORK_XBEE\r\n\r\n#include <sys/time.h>\r\n#include <iostream>\r\n#include \"ProcessFramework.h\"\r\n\r\n\r\n#define START_BYTE 0x7e\r\n#define ESCAPE     0x7d\r\n#define XON        0x11\r\n#define XOFF       0x13\r\n\r\n#define MAX_FRAME_DATA_SIZE  128\r\n\r\n#define XB_BROADCAST_ADDRESS32    0x0000ffff\r\n#define XB_BROADCAST_ADDRESS16     0xfffe\r\n\r\n#define DEFAULT_FRAME_ID 1\r\n\r\n#define XB_PACKET_ACKNOWLEGED  0x01\r\n#define XB_BROADCAST_PACKET    0x02\r\n#define XB_BROADCAST_RADIUS_MAX_HOPS 0\r\n\r\n#define API_ID_INDEX  3\r\n#define PACKET_OVERHEAD_LENGTH 6\r\n#define ZB_TX_API_LENGTH  12\r\n#define ZB_PAYLOAD_OFFSET 11\r\n\r\n/**\r\n * API ID Constant\r\n */\r\n#define XB_TX_REQUEST          0x10\r\n#define XB_RX_RESPONSE         0x90\r\n\r\n/**\r\n * TX STATUS\r\n */\r\n#define SUCCESS           0x0\r\n\r\n#define NO_ERROR                          0\r\n#define CHECKSUM_FAILURE                  1\r\n#define PACKET_EXCEEDS_BYTE_ARRAY_LENGTH  2\r\n#define UNEXPECTED_START_BYTE             3\r\n\r\n\r\n#define NW_TX_UNICAST 0\r\n#define NW_TX_BROADCAST 8\r\n\r\n#define NW_MAX_NODEID 24\r\n\r\n/*\r\n *   MQTTS  Client's state\r\n */\r\n#define MQTTS_DEVICE_DISCONNECTED     0\r\n#define MQTTS_DEVICE_ACTIVE           1\r\n#define MQTTS_DEVICE_ASLEEP           2\r\n#define MQTTS_DEVICE_AWAKE            3\r\n#define MQTTS_DEVICE_LOST             4\r\n\r\nnamespace tomyGateway{\r\n\r\n/*============================================\r\n              NWAddress64\r\n =============================================*/\r\nclass NWAddress64 {\r\npublic:\r\n\tNWAddress64(uint32_t msb, uint32_t lsb);\r\n\tNWAddress64();\r\n\tuint32_t getMsb();\r\n\tuint32_t getLsb();\r\n\tvoid setMsb(uint32_t msb);\r\n\tvoid setLsb(uint32_t lsb);\r\n\tbool operator==(NWAddress64&);\r\nprivate:\r\n\tuint32_t _msb;\r\n\tuint32_t _lsb;\r\n};\r\n\r\n /*============================================\r\n                NWResponse\r\n =============================================*/\r\nclass NWResponse {\r\npublic:\r\n\t NWResponse();\r\n\t~NWResponse();\r\n\tuint8_t getMsbLength();\r\n\tuint8_t getLsbLength();\r\n\tuint8_t getChecksum();\r\n\tuint8_t getFrameDataLength();\r\n\tuint8_t getOption();\r\n\tuint8_t getType();\r\n\tuint8_t getPayload(int index);\r\n\tuint8_t getPayloadLength();\r\n\tuint8_t getPayloadOffset();\r\n\tuint8_t getApiId();\r\n\tuint8_t getMsgType();\r\n\tuint8_t getErrorCode();\r\n\tuint8_t* getFrameData();\r\n\tuint8_t* getPayloadPtr();\r\n\tuint16_t getPacketLength();\r\n\tuint16_t getClientAddress16();\r\n\tNWAddress64* getClientAddress64();\r\n\r\n\tbool isBroadcast();\r\n\tbool isAvailable();\r\n\tbool isError();\r\n\r\n\tvoid setApiId(uint8_t apiId);\r\n\tvoid setMsbLength(uint8_t msbLength);\r\n\tvoid setLsbLength(uint8_t lsbLength);\r\n\tvoid setChecksum(uint8_t checksum);\r\n\tvoid setFrameData(uint8_t *frameDataPtr);\r\n\tvoid setFrameDataLength(uint8_t frameLength);\r\n\tvoid setAvailable(bool complete);\r\n\tvoid setErrorCode(uint8_t errorCode);\r\n\r\nvoid reset();\r\n\tvoid absorb(NWResponse* resp);\r\nprotected:\r\n\tuint8_t *_frameDataPtr;\r\nprivate:\r\n\tuint32_t getRemoteAddressMsb();\r\n\tuint32_t getRemoteAddressLsb();\r\n\r\n\tuint8_t _apiId;\r\n\tuint8_t _msbLength;\r\n\tuint8_t _lsbLength;\r\n\tuint8_t _checksum;\r\n\tuint8_t _frameLength;\r\n\tuint8_t _errorCode;\r\n\tbool _complete;\r\n\tNWAddress64 _addr64;\r\n};\r\n\r\n/*============================================\r\n          Class NWRequest\r\n =============================================*/\r\n\r\nclass NWRequest{\r\npublic:\r\n\tNWRequest();\r\n\tNWRequest(NWAddress64 &addr64, uint8_t *payload, uint8_t payLoadLength);\r\n\tNWRequest(NWAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius,\r\n\t\t\t\tuint8_t option, uint8_t *payload, uint8_t payloadLength);\r\n\t~NWRequest();\r\n\tuint8_t* getPayloadPtr();\r\n\tuint8_t getBroadcastRadius();\r\n\tuint8_t getOption();\r\n\tuint8_t getPayloadLength();\r\n\tuint8_t getApiId();\r\n\tuint8_t getFrameData(uint8_t pos);\r\n\tuint8_t getFrameDataLength();\r\n\tuint16_t getAddress16();\r\n\tNWAddress64& getAddress64();\r\n\r\n\tvoid setApiId(uint8_t apiId);\r\n\tvoid setClientAddress64(NWAddress64* addr64);\r\n\tvoid setClientAddress16(uint16_t addr16);\r\n\tvoid setBroadcastRadius(uint8_t broadcastRadius);\r\n\tvoid setOption(uint8_t option);\r\n\tvoid setPayload(uint8_t *payload);\r\n\tvoid setPayloadLength(uint8_t payLoadLength);\r\n\r\nprivate:\r\n\tuint8_t _apiId;\r\n\tuint8_t _broadcastRadius;\r\n\tuint8_t _option;\r\n\tuint8_t _payloadLength;\r\n\tuint8_t* _payloadPtr;\r\n\tuint16_t _addr16;\r\n\tNWAddress64 _addr64;\r\n};\r\n\r\n/*===========================================\r\n                SerialPort\r\n ============================================*/\r\n#include <termios.h>\r\nclass SerialPort{\r\npublic:\r\n\tSerialPort();\r\n\t~SerialPort();\r\n\tint open(XBeeConfig  config);\r\n\tbool send(unsigned char b);\r\n\tbool recv(unsigned char* b);\r\n\tvoid flush();\r\n\r\nprivate:\r\n\tint open(const char* devName, unsigned int boaurate,  bool parity, unsigned int stopbit, unsigned int flg);\r\n\r\n\tint _fd;  // file descriptor\r\n\tstruct termios _tio;\r\n};\r\n\r\n\r\n/*============================================\r\n                 XBee\r\n ============================================*/\r\n\r\nclass XBee {\r\npublic:\r\n\tXBee();\r\n\t~XBee();\r\n\r\nprotected:\r\n\tint  initialize(XBeeConfig  config);\r\n\tbool receiveResponse(NWResponse* response);\r\n\tvoid sendRequest(NWRequest& request);\r\nprivate:\r\n\tvoid readPacket(void);\r\n\tbool read(uint8_t* buff);\r\n\tbool write(uint8_t val);\r\n\tvoid sendByte(uint8_t, bool escape);\r\n\tvoid resetResponse();\r\n\tvoid flush();\r\n\r\n\tSerialPort *_serialPort;\r\n\tNWResponse _response;\r\n\tbool _escape;\r\n\tuint8_t _pos;\r\n\tuint8_t _checksumTotal;\r\n\tuint8_t _bd;\r\n};\r\n\r\n/*===========================================\r\n               Class  NetworkStack\r\n ============================================*/\r\nclass Network : public XBee{\r\npublic:\r\n\tNetwork();\r\n\t~Network();\r\n\tvoid unicast(NWAddress64* addr64, uint16_t addr16,\r\n\t\t\tuint8_t* payload, uint16_t payloadLength);\r\n\tvoid broadcast(uint8_t* payloadLength, uint16_t bodyLenght);\r\n\tbool getResponse(NWResponse* response);\r\n\tint initialize(NETWORK_CONFIG  config);\r\n\r\nprivate:\r\n\tNWRequest   _txRequest;\r\n};\r\n\r\n}\r\n\r\n#endif /* NETWORK_XBEE */\r\n#endif  /* ZBSTACK_H_ */\r\n"
  },
  {
    "path": "LogMonitor/Makefile",
    "content": "PROGNAME := LogMonitor\nSRCDIR := src\nSUBDIR := src/lib\n\nSRCS := $(SRCDIR)/LogMonitorApp.cpp \\\n$(SRCDIR)/LogMonitor.cpp \\\n$(SUBDIR)/ProcessFramework.cpp \n\nCXX := g++\nCPPFLAGS += \nDEFS :=\nLDFLAGS += \nLIBS +=\nLDADD := -lpthread -lrt\n\nCXXFLAGS := -Wall -O3\n\nOUTDIR := Build\n\nPROG := $(OUTDIR)/$(PROGNAME)\nOBJS := $(SRCS:%.cpp=$(OUTDIR)/%.o)\nDEPS := $(SRCS:%.cpp=$(OUTDIR)/%.d)\n\n.PHONY: install clean distclean\n\nall: $(PROG)\n\n-include $(DEPS)\n\n$(PROG): $(OBJS)\n\t$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)\n\n$(OUTDIR)/%.o:%.cpp\n\t@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi\n\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<\n\nclean:\n\trm -rf $(OUTDIR)\n\ninstall:\n\tcp -p $(PROG) ../../\n"
  },
  {
    "path": "LogMonitor/src/LogMonitor.cpp",
    "content": "/*\n * LogMonitor.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef LOGMONITOR_H_\n#define LOGMONITOR_H_\n\n#include \"lib/ProcessFramework.h\"\n\nusing namespace std;\n\nclass LogMonitor:public Process{\npublic:\n\tLogMonitor();\n\t~LogMonitor();\n\tvoid initialize(int argc, char** argv);\n\tvoid run();\n};\n\n\nLogMonitor::LogMonitor(){\n\ttheProcess = this;\n}\n\nLogMonitor::~LogMonitor(){\n\n}\n\nvoid LogMonitor::initialize(int argc, char** argv){\n\tProcess::initialize(0, NULL);\n}\n\nvoid LogMonitor::run(){\n\twhile(true){\n\t\tconst char* data = getLog();\n\t\tprintf(\"%s\", data);\n\t\tif(int rc = checkSignal()){\n\t\t\tprintf(\"\\n\\n\\n\");\n\t\t\tTHROW_EXCEPTION(ExInfo, rc, \" Terminated normally\\n\");\n\t\t}\n\t}\n}\n\n\n#endif /* LOGMONITOR_H_ */\n\n\n\n\n"
  },
  {
    "path": "LogMonitor/src/LogMonitor.h",
    "content": "/*\n * LogMonitor.h\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef LOGMONITOR_H_\n#define LOGMONITOR_H_\n\n#include \"lib/ProcessFramework.h\"\n\nusing namespace std;\n\nclass LogMonitor:public Process{\npublic:\n\tLogMonitor();\n\t~LogMonitor();\n\tvoid initialize(int argc, char** argv);\n\tvoid run();\n};\n\n\n#endif /* LOGMONITOR_H_ */\n"
  },
  {
    "path": "LogMonitor/src/LogMonitorApp.cpp",
    "content": "/*\n * LogMonitorApp.cpp\n *\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#include \"lib/ProcessFramework.h\"\n#include \"LogMonitor.h\"\n\n/**************************************\n *       LogMonitor Application\n **************************************/\nconst char* theCmdlineParameter = \"\";\n\nLogMonitor lp = LogMonitor();\n\n\n"
  },
  {
    "path": "LogMonitor/src/lib/Defines.h",
    "content": "/*\n *   Defines.h\n *                      The BSD License\n *\n *           Copyright (c) 2014, tomoaki@tomy-tech.com\n *                    All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n *    this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n * THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  Created on: 2014/06/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n#ifndef  DEFINES_H_\n#define  DEFINES_H_\n\n/*=================================\n *    CPU TYPE\n ==================================*/\n#define CPU_LITTLEENDIANN\n//#define CPU_BIGENDIANN\n\n/*=================================\n *    Data Type\n ==================================*/\ntypedef unsigned char  uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int   uint32_t;\n\n#endif  /*  DEFINES_H_  */\n"
  },
  {
    "path": "LogMonitor/src/lib/ProcessFramework.cpp",
    "content": "/*\n * ProcessFramework.cpp\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2015 tomoaki@tomy-tech.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n *  Created on: 2015/05/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#include \"ProcessFramework.h\"\n#include \"Defines.h\"\n#include <string.h>\n#include <exception>\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <iostream>\n#include <sys/time.h>\n#include <time.h>\n#include <unistd.h>\n#include <sys/ipc.h>\n#include <sys/sem.h>\n#include <sys/shm.h>\n#include <sys/types.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <signal.h>\n\nusing namespace std;\nextern const char* theCmdlineParameter;\nextern int optind;\n\n/*=====================================\n        Global functions & variables\n ======================================*/\nProcess* theProcess = 0;\nMultiTaskProcess* theMultiTask = 0;\nstatic volatile int theSignaled = 0;\n\nstatic void signalHandler(int sig){\n\tassert(sig == SIGINT || sig == SIGHUP || sig == SIGTERM);\n\ttheSignaled = sig;\n\ttheProcess->releaseLog();\n\texit(-1);\n}\n\nint main(int argc, char** argv){\n\ttry{\n\t\tsignal(SIGHUP, signalHandler);\n\t\tsignal(SIGINT, signalHandler);\n\t\tsignal(SIGTERM, signalHandler);\n\n\t\ttheProcess->initialize(argc, argv);\n\t\ttheProcess->run();\n\t}catch(Exception& ex){\n\t\tex.writeMessage();\n\t}\n\treturn 0;\n}\n\nuint8_t* mqcalloc(uint8_t len){\n\tuint8_t* pos = (uint8_t*)calloc(len, sizeof(uint8_t));\n\tif( pos == 0){\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't allocate memory.\");\n\t}\n\treturn pos;\n}\n\n#ifdef CPU_LITTLEENDIANN\n\n/*--- For Little endianness ---*/\n\nuint16_t getUint16(uint8_t* pos){\n\tuint16_t val = ((uint16_t)*pos++ << 8);\n\treturn val += *pos;\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n    *pos++ = (val >> 8) & 0xff;\n\t*pos   = val & 0xff;\n}\n\nuint32_t getUint32(uint8_t* pos){\n    uint32_t val = (uint32_t(*pos++ <<  24));\n\tval += (uint32_t(*pos++ << 16));\n\tval += (uint32_t(*pos++ <<  8));\n\treturn val += *pos++;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n\t*pos++ = (val >> 24) & 0xff;\n\t*pos++ = (val >> 16) & 0xff;\n\t*pos++ = (val >>  8) & 0xff;\n\t*pos   =  val & 0xff;\n}\n\n#endif\n#ifdef CPU_BIGENDIANN\n/*--- For Big endianness ---*/\n\nuint16_t getUint16(uint8_t* pos){\n  uint16_t val = *pos++;\n  return val += ((uint16_t)*pos++ << 8);\n}\n\nvoid setUint16(uint8_t* pos, uint16_t val){\n\t*pos++ =  val & 0xff;\n\t*pos   = (val >>  8) & 0xff;\n}\n\nlong getUint32(uint8_t* pos){\n    long val = (uint32_t(*(pos + 3)) << 24) +\n        (uint32_t(*(pos + 2)) << 16) +\n        (uint32_t(*(pos + 1)) <<  8);\n        return val += *pos;\n}\n\nvoid setUint32(uint8_t* pos, uint32_t val){\n    *pos++ =  val & 0xff;\n    *pos++ = (val >>  8) & 0xff;\n    *pos++ = (val >> 16) & 0xff;\n    *pos   = (val >> 24) & 0xff;\n}\n\n\n#endif\n\n\nvoid utfSerialize(uint8_t* pos, string str){\n\tsetUint16(pos, (uint16_t)str.size());\n\tstr.copy((char*)pos + 2, str.size(), 0);\n}\n\nchar theCurrentTime[32];\n\nchar* currentDateTime() {\n    time_t     now = time(0);\n    struct tm  tstruct;\n    tstruct = *localtime(&now);\n    strftime(theCurrentTime, sizeof(theCurrentTime), \"%Y%m%d %H%M%S\", &tstruct);\n    return theCurrentTime;\n}\n\n/*=====================================\n         Class Process\n  ======================================*/\nProcess::Process(){\n\t_argc = 0;\n\t_argv = 0;\n\t_rb = new RingBuffer();\n\t_rbsem = new Semaphore(TOMYFRAME_RB_SEMAPHOR_NAME, 0);\n}\n\nProcess::~Process(){\n\tdelete(_rb);\n\tdelete(_rbsem);\n}\n\nvoid Process::run(){\n\n}\n\nvoid Process::initialize(int argc, char** argv){\n\t_argc = argc;\n\t_argv = argv;\n}\n\nint Process::getArgc(){\n\treturn _argc;\n}\n\nchar** Process::getArgv(){\n\treturn _argv;\n}\n\nchar* Process::getArgv(char option){\n\tchar arg;\n\toptind = 1;\n\twhile((arg = getopt(_argc, _argv, theCmdlineParameter))!= -1 && (arg != 255)){\n\t\tif(arg == option){\n\t\t\treturn optarg;\n\t\t}\n\t}\n\treturn 0;\n}\n\nint Process::getParam(const char* parameter, char* value){\n\tchar str[TOMYFRAME_PARAM_MAX], param[TOMYFRAME_PARAM_MAX];\n\tFILE *fp;\n\tint i = 0, j = 0;\n\n\tif ((fp = fopen(TOMYFRAME_CONFIG_FILE, \"r\")) == NULL) {\n\t\tLOGWRITE(\"No config file:[%s]\\n\", TOMYFRAME_CONFIG_FILE);\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"No config file.\");\n\t\treturn -1;\n\t}\n\n\twhile(true) {\n\t\tif (fgets(str, TOMYFRAME_PARAM_MAX - 1, fp) == NULL) {\n\t\t\tfclose(fp);\n\t\t\treturn -3;\n\t\t}\n\t\tif (!strncmp(str, parameter,strlen(parameter))) {\n\t\t\twhile (str[i++] != '=') {\n\t\t\t\t;\n\t\t\t}\n\t\t\twhile (str[i] != '\\n') {\n\t\t\t\tparam[j++] = str[i++];\n\t\t\t}\n\t\t\tparam[j] = '\\0';\n\n\t\t    for( i = strlen(param)-1; i >= 0 && isspace( param[i] ); i-- ) ;\n\t\t    param[i+1] = '\\0';\n\t\t    for( i = 0; isspace( param[i] ); i++ ) ;\n\t\t    if( i > 0 ) {\n\t\t        j = 0;\n\t\t        while( param[i] ) param[j++] = param[i++];\n\t\t        param[j] = '\\0';\n\t\t    }\n\t\t\tstrcpy(value,param);\n\t\t\tfclose(fp);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tfclose(fp);\n\treturn -1;\n}\n\n\nvoid Process::putLog(const char* format, ...){\n\t_mt.lock();\n\tva_list arg;\n\tva_start(arg, format);\n\tvsprintf(_rbdata, format, arg);\n\tva_end(arg);\n\tif(strlen(_rbdata)){\n\t\t_rb->put(_rbdata);\n\t\t_rbsem->post();\n\t}\n\t_mt.unlock();\n}\n\nconst char* Process::getLog(){\n\tint len = 0;\n\t_mt.lock();\n\twhile((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0){\n\t\t_rbsem->wait();\n\t}\n\t*(_rbdata + len) = 0;\n\t_mt.unlock();\n\treturn _rbdata;\n}\n\nvoid   Process::releaseLog(void){\n\t_mt.unlock();\n}\n\nvoid Process::resetRingBuffer(){\n\t_rb->reset();\n}\n\nint Process::checkSignal(){\n\treturn theSignaled;\n}\n/*=====================================\n         Class MultiTaskProcess\n  ======================================*/\nMultiTaskProcess::MultiTaskProcess(){\n\ttheMultiTask = this;\n}\n\nMultiTaskProcess::~MultiTaskProcess(){\n\n}\n\nvoid MultiTaskProcess::initialize(int argc, char** argv){\n\tProcess::initialize(argc, argv);\n\tlist<Thread*>::iterator thread = _threadList.begin();\n\twhile( thread != _threadList.end()){\n\t\t(*thread)->initialize(argc, argv);\n\t\t++thread;\n\t}\n}\n\nvoid MultiTaskProcess::run(){\n\tlist<Thread*>::iterator thread = _threadList.begin();\n\twhile(thread != _threadList.end()){\n\t\t(*thread)->start();\n\t\tthread++;\n\t}\n\n\t_stopProcessEvent.wait();\n\n\tthread = _threadList.begin();\n\twhile(thread != _threadList.end()){\n\t\t(*thread)->cancel();\n\t\t(*thread)->join();\n\t\tthread++;\n\t}\n}\n\nSemaphore* MultiTaskProcess::getStopProcessEvent(){\n\treturn &_stopProcessEvent;\n}\n\nvoid MultiTaskProcess::attach(Thread* thread){\n\t_threadList.push_back(thread);\n}\n\nchar* MultiTaskProcess::getArgv(char option){\n\t_mutex.lock();\n\tchar* arg = Process::getArgv(option);\n\t_mutex.unlock();\n\treturn arg;\n}\n\nint MultiTaskProcess::getParam(const char* parameter, char* value){\n\t_mutex.lock();\n\tint rc = Process::getParam(parameter, value);\n\t_mutex.unlock();\n\treturn rc;\n}\n/*=====================================\n        Class Thread\n =====================================*/\nThread::Thread(){\n\t_stopProcessEvent = theMultiTask->getStopProcessEvent();\n\t_threadID = 0;\n\t_stopProcessEvent = 0;\n}\n\nThread::~Thread(){\n\n}\n\nvoid* Thread::_run(void* runnable){\n\tstatic_cast<Runnable*>(runnable)->EXECRUN();\n\treturn 0;\n}\n\nvoid Thread::initialize(int argc, char** argv){\n\n}\n\npthread_t Thread::getID(){\n\treturn pthread_self();\n}\n\nbool Thread::equals(pthread_t *t1, pthread_t *t2){\n\t\treturn (pthread_equal(*t1, *t2) ? false : true);\n}\n\nint Thread::start(void){\n\tRunnable *runnable = this;\n\treturn pthread_create(&_threadID, 0, _run, runnable);\n}\n\nint Thread::join(void){\n\treturn pthread_join(_threadID, 0);\n}\n\nint Thread::cancel(void){\n\treturn pthread_cancel(_threadID);\n}\n\n\nvoid Thread::stopProcess(void){\n\t_stopProcessEvent->post();\n}\n\n/*=====================================\n        Class Mutex\n =====================================*/\n\nMutex::Mutex(void){\n\tpthread_mutexattr_t  attr;\n\tpthread_mutexattr_init(&attr);\n\tpthread_mutex_init(&_mutex, &attr);\n\tpthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);\n\t_shmid = 0;\n\t_pmutex = 0;\n}\n\nMutex::Mutex(const char* fileName){\n\tpthread_mutexattr_t  attr;\n\n\tkey_t key = ftok(fileName, 1);\n\n\tif((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0){\n\t\tperror(\"Mutex\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t}\n\t_pmutex = (pthread_mutex_t*)shmat(_shmid, NULL, 0);\n\tif(_pmutex  < 0 ){\n\t\tperror(\"Mutex\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't attach shared memory for Mutex.\");\n\t}\n\n\tpthread_mutexattr_init(&attr);\n\n\tif(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0) {\n\t\tperror(\"Mutex pthread_mutexattr_setpshared\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Mutex.\");\n\t}\n\tif(pthread_mutex_init(_pmutex, &attr) != 0) {\n\t\tperror(\"Mutex pthread_mutexattr_setpshared\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Mutex.\");\n\t}\n}\n\nMutex::~Mutex(void){\n\tif(_pmutex){\n\t\tpthread_mutex_lock(_pmutex);\n\t\tpthread_mutex_unlock(_pmutex);\n\t\tpthread_mutex_destroy(_pmutex);\n\t}else{\n\t\tpthread_mutex_lock(&_mutex);\n\t\tpthread_mutex_unlock(&_mutex);\n\t\tpthread_mutex_destroy(&_mutex);\n\t}\n\tif(_shmid){\n\t\tshmctl(_shmid, IPC_RMID, NULL);\n\t}\n}\n\nvoid Mutex::lock(void){\n\tif(_pmutex){\n\t\tpthread_mutex_lock(_pmutex);\n\t}else{\n\t\ttry{\n\t\t\tif(pthread_mutex_lock(&_mutex)){\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}catch(char* errmsg){\n\t\t\tperror(\"Mutex\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"The same thread can't aquire a mutex twice.\");\n\t\t}\n\t}\n}\n\nvoid Mutex::unlock(void){\n\n\tif(_pmutex){\n\t\tpthread_mutex_unlock(_pmutex);\n\t}else{\n\t\ttry {\n\t\t\tif(pthread_mutex_unlock(&_mutex)){\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}catch(char* errmsg){\n\t\t\tperror(\"Mutex\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't release a mutex.\");\n\t\t}\n\t}\n}\n\n/*=====================================\n        Class Semaphore\n =====================================*/\n\nSemaphore::Semaphore(){\n\tSemaphore(0);\n}\n\nSemaphore::Semaphore(unsigned int val){\n\tsem_init(&_sem, 0, val);\n\t_name = 0;\n\t_psem = 0;\n}\n\nSemaphore::Semaphore(const char* name,unsigned int val){\n\t_psem = sem_open(name, O_CREAT, 0666, val);\n\tif(_psem == SEM_FAILED ){\n\t\tperror(\"Semaphore\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a Semaphore.\");\n\t}\n\t_name = (char*)mqcalloc(strlen(name + 1));\n\tstrcpy(_name, name);\n}\n\nSemaphore::~Semaphore(){\n\tif(_name){\n\t\tsem_close(_psem);\n\t\tsem_unlink(_name);\n\t\tfree((void*)_name);\n\t}else{\n\t\tsem_destroy(&_sem);\n\t}\n}\n\nvoid Semaphore::post(void){\n\tint val = 0;\n\tif(_psem){\n\t\tsem_getvalue(_psem,&val);\n\t\tif(val <= 0){\n\t\t\tsem_post(_psem);\n\t\t}\n\t}else{\n\t\tsem_getvalue(&_sem,&val);\n\t\tif(val <= 0){\n\t\t\tsem_post(&_sem);\n\t\t}\n\t}\n}\n\nvoid Semaphore::wait(void){\n\tif(_psem){\n\t\tsem_wait(_psem);\n\t}else{\n\t\tsem_wait(&_sem);\n\t}\n}\n\nvoid Semaphore::timedwait(uint16_t millsec){\n\tstruct timespec ts;\n\tclock_gettime(CLOCK_REALTIME, &ts);\n\tts.tv_sec += millsec / 1000;\n\tts.tv_nsec = (millsec % 1000) * 1000000;\n\tif(_psem){\n\t\tsem_timedwait(_psem, &ts);\n\t}else{\n\t\tsem_timedwait(&_sem, &ts);\n\t}\n}\n\n/*=========================================\n             Class RingBuffer\n =========================================*/\nRingBuffer::RingBuffer(){\n\tkey_t key = ftok(TOMYFRAME_RINGBUFFER_KEY, 1);\n\n\tif((_shmid = shmget(key, RINGBUFFER_SIZE, IPC_CREAT | IPC_EXCL | 0666)) >= 0){\n\t\tif((_shmaddr = (uint16_t*)shmat(_shmid, NULL, 0)) > 0 ){\n\t\t\t_length = (uint16_t*)_shmaddr;\n\t\t\t_start = (uint16_t*)_length + sizeof(uint16_t*);\n\t\t\t_end = (uint16_t*)_start + sizeof(uint16_t*);\n\t\t\t_buffer = (char*)_end + sizeof(uint16_t*);\n\t\t\t_createFlg = true;\n\n\t\t\t*_length = RINGBUFFER_SIZE - sizeof(uint16_t*) * 3 - 16;\n\t\t\t*_start = *_end = 0;\n\t\t}else{\n\t\t\tperror(\"RingBuffer\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"can't attach shared memory.\");\n\t\t}\n\t}else if((_shmid = shmget(key, RINGBUFFER_SIZE, IPC_CREAT | 0666)) >= 0){\n\t\tif((_shmaddr = (uint16_t*)shmat(_shmid, NULL, 0)) > 0 ){\n\t\t\t_length = (uint16_t*)_shmaddr;\n\t\t\t_start = (uint16_t*)_length + sizeof(uint16_t*);\n\t\t\t_end = (uint16_t*)_start + sizeof(uint16_t*);\n\t\t\t_buffer = (char*)_end + sizeof(uint16_t*);\n\t\t\t_createFlg = false;\n\t\t}else{\n\t\t\tperror(\"RingBuffer\");\n\t\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t\t}\n\t}else{\n\t\tperror(\"RingBuffer\");\n\t\tTHROW_EXCEPTION(ExFatal, ERRNO_SYS_01, \"Can't create a shared memory.\");\n\t}\n\n\t_pmx = new Mutex(TOMYFRAME_RB_MUTEX_KEY);\n}\n\nRingBuffer::~RingBuffer(){\n\tif(_createFlg){\n\t\tif(_shmid > 0){\n\t\t\tshmctl(_shmid, IPC_RMID, NULL);\n\t\t}\n\t\tif(_pmx > 0){\n\t\t\tdelete _pmx;\n\t\t}\n\t}else{\n\t\tif(_shmid > 0){\n\t\t\tshmdt(_shmaddr);\n\t\t}\n\t}\n}\n\nvoid RingBuffer::put(char* data){\n\t_pmx->lock();\n\n\tuint16_t dlen = strlen(data);\n\tuint16_t blen = *_length - *_end;\n\n\tif(*_end > *_start){\n\t\tif(dlen < blen){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\tif(*_end - *_start == 1){ // Buffer is empty.\n\t\t\t\t*_start = *_end;\n\t\t\t}\n\t\t\t*_end += dlen;\n\t\t}else{\n\t\t\tstrncpy(_buffer + *_end, data, blen);\n\t\t\tstrncpy(_buffer, data + blen, dlen - blen);\n\t\t\tif(*_end - *_start == 1){ // Buffer is empty.\n\t\t\t\t*_start = *_end;\n\t\t\t\t*_end = dlen - blen;\n\t\t\t}else{\n\t\t\t\t*_end = dlen - blen;\n\t\t\t\t*_start = *_end + 1;\n\t\t\t}\n\t\t}\n\t}else if(*_end == *_start){\n\t\tif(dlen < blen){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t*_end += dlen;\n\t\t}else{\n\t\t\tconst char* errmsg = \"RingBuffer Error: data is too long\";\n\t\t\tstrcpy(_buffer + *_end, errmsg);\n\t\t\t*_end += strlen(errmsg);\n\t\t}\n\t}else{    // *_end < *_start\n\t\tif(dlen < *_start - *_end){\n\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t*_end += dlen;\n\t\t\t*_start = *_end + 1;\n\t\t}else {\n\t\t\tif( dlen < blen){\n\t\t\t\tstrncpy(_buffer + *_end, data, dlen);\n\t\t\t\t*_end += dlen;\n\t\t\t\t*_start = *_end + 1;\n\t\t\t}else {\n\t\t\t\tstrncpy(_buffer + *_end, data, blen);\n\t\t\t\tstrncpy(_buffer, data + blen, dlen - blen);\n\t\t\t\t*_start = *_end;\n\t\t\t\t*_end = dlen - blen;\n\t\t\t}\n\t\t}\n\t}\n\t_pmx->unlock();\n}\n\nint RingBuffer::get(char* buf, int length){\n\tint len = 0;\n\t_pmx->lock();\n\n\tif(*_end > *_start){\n\t\tif(length > *_end - *_start){\n\t\t\tlen = *_end - *_start;\n\t\t\tif (len == 1){\n\t\t\t\tlen = 0;\n\t\t\t}\n\t\t\tstrncpy(buf, _buffer + *_start, len);\n\t\t\t*_start = *_end - 1;\n\t\t}else{\n\t\t\tlen = length;\n\t\t\tstrncpy(buf, _buffer + *_start, len);\n\t\t\t*_start = *_start + len;\n\t\t}\n\t}else if(*_end < *_start){\n\t\tint blen = *_length - *_start;\n\t\tif(length > blen ){\n\t\t\tstrncpy(buf, _buffer + *_start, blen);\n\t\t\t*_start = 0;\n\t\t\tif(length - (blen + *_end) > 0){\n\t\t\t\tstrncpy(buf + blen , _buffer, *_end);\n\t\t\t\tlen = blen + *_end;\n\t\t\t\tif(*_end > 0){\n\t\t\t\t\t*_start = *_end - 1;\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\tprintf(\"length=%d blen=%d len = %d\\n\", length, blen, length - *_end );\n\t\t\t\tstrncpy(buf + blen, _buffer, length - blen);\n\t\t\t\tlen = length;\n\t\t\t\t*_start = length - blen;\n\t\t\t}\n\t\t}else{\n\t\t\tstrncpy(buf, _buffer + *_start, length);\n\t\t\t*_start += length;\n\t\t\tlen = length;\n\t\t}\n\t}\n\t_pmx->unlock();\n\treturn len;\n}\n\nvoid RingBuffer::reset(){\n\t_pmx->lock();\n\t*_start = *_end = 0;\n\t_pmx->unlock();\n}\n\n/*=====================================\n        Class Exception\n ======================================*/\nException::Exception(const ExceptionType type, const int exNo, const string& message){\n\t_message = message;\n\t_type = type;\n\t_exNo = exNo;\n\t_fileName = 0;\n\t_functionName = 0;\n\t_line = 0;\n}\n\nException::Exception(const ExceptionType type, const int exNo, const string& message,\n\t\t                const char* file, const char* function, const int line){\n\t_message = message;\n\t_type = type;\n\t_exNo = exNo;\n\t_fileName = file;\n\t_functionName = function;\n\t_line = line;\n}\n\nException::~Exception() throw(){\n\n}\n\nconst char* Exception::what() const throw() {\n    return _message.c_str();\n}\n\nconst char* Exception::getFileName(){\n        return _fileName;\n}\n\nconst char* Exception::getFunctionName(){\n        return _functionName;\n}\n\nconst int Exception::getLineNo(){\n        return _line;\n}\n\nconst int Exception::getExceptionNo(){\n        return _exNo;\n}\n\nbool Exception::isFatal(){\n\treturn _type == ExFatal;\n}\n\nconst char* Exception::strType(){\n\tswitch(_type){\n\tcase ExInfo:\n\t\treturn \"Info\";\n\t\tbreak;\n\tcase ExWarn:\n\t\treturn \"Warn\";\n\t\tbreak;\n\tcase ExError:\n\t\treturn \"Error\";\n\t\tbreak;\n\tcase ExFatal:\n\t\treturn \"Fatal\";\n\t\tbreak;\n\tcase ExDebug:\n\t\treturn \"Debug\";\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn \"\";\n}\n\nvoid Exception::writeMessage(){\n\n\tfprintf(stdout, \"%s %5s:%-6d   %s  line %-4d %s() : %s\\n\",\n\t\t\tcurrentDateTime(), strType(), getExceptionNo(), getFileName(), getLineNo(), getFunctionName(), what());\n}\n\n/*=========================================\n             Class Timer\n =========================================*/\n\nTimer::Timer(){\n  stop();\n}\n\nvoid Timer::start(uint32_t msec){\n  gettimeofday(&_startTime, 0);\n  _millis = msec;\n}\n\nbool Timer::isTimeup(){\n  return isTimeup(_millis);\n}\n\nbool Timer::isTimeup(uint32_t msec){\n    struct timeval curTime;\n    long secs, usecs;\n    if (_startTime.tv_sec == 0){\n        return false;\n    }else{\n        gettimeofday(&curTime, 0);\n        secs  = (curTime.tv_sec  - _startTime.tv_sec) * 1000;\n        usecs = (curTime.tv_usec - _startTime.tv_usec) / 1000.0;\n        return ((secs + usecs) > (long)msec);\n    }\n}\n\nvoid Timer::stop(){\n  _startTime.tv_sec = 0;\n  _millis = 0;\n}\n\n"
  },
  {
    "path": "LogMonitor/src/lib/ProcessFramework.h",
    "content": "/*\n * ProcessFramework.h\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2015 tomoaki@tomy-tech.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n *  Created on: 2015/05/01\n *    Modified:\n *      Author: Tomoaki YAMAGUCHI\n *     Version: 0.0.0\n */\n\n#ifndef PROCESSFRAMEWORK_H_\n#define PROCESSFRAMEWORK_H_\n\n#include <stdlib.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <semaphore.h>\n#include <list>\n#include <queue>\n#include <exception>\n#include <string>\n#include <iostream>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netdb.h>\n#include <unistd.h>\n#include <string>\n#include <arpa/inet.h>\n#include \"Defines.h\"\n#include <sys/ipc.h>\n#include <sys/sem.h>\n#include <sys/shm.h>\n\n#define TOMYFRAME_PARAM_MAX     128\n#define TOMYFRAME_CONFIG_FILE      \"/usr/local/etc/tomygateway/config/param.conf\"\n\n#define TOMYFRAME_RINGBUFFER_KEY   \"/usr/local/etc/tomygateway/config/ringbuffer.key\"\n#define TOMYFRAME_RB_MUTEX_KEY     \"/usr/local/etc/tomygateway/config/rbmutex.key\"\n#define TOMYFRAME_RB_SEMAPHOR_NAME \"/rbsemaphor\"\n\n#define LOGWRITE theProcess->putLog\n//#define LOGWRITE printf\n#define RINGBUFFER_SIZE 16384\n#define PROCESS_LOG_BUFFER_SIZE  2048\n\n#define ERRNO_SYS_01  1   // Application Frame Error\n\nusing namespace std;\n\n/*=================================\n *    Data Type\n ==================================*/\ntypedef unsigned char  uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int   uint32_t;\n\n/*=====================================\n         Class Mutex\n  ====================================*/\nclass Mutex{\npublic:\n\tMutex();\n\tMutex(const char* name);\n\t~Mutex();\n\tvoid lock(void);\n\tvoid unlock(void);\n\nprivate:\n\tpthread_mutex_t _mutex;\n\tpthread_mutex_t* _pmutex;\n\tint   _shmid;\n};\n\n/*=====================================\n         Class Semaphore\n  ====================================*/\nclass Semaphore{\npublic:\n\tSemaphore();\n\tSemaphore(unsigned int val);\n\tSemaphore(const char* name, unsigned int val);\n\t~Semaphore();\n\tvoid post(void);\n\tvoid wait(void);\n\tvoid timedwait(uint16_t millsec);\n\nprivate:\n\tsem_t* _psem;\n\tsem_t  _sem;\n\tchar*  _name;\n};\n\n/*=====================================\n         Class EventQue\n  ====================================*/\ntemplate <class T>\nclass EventQue{\npublic:\n\tEventQue();\n\t~EventQue();\n\tT*  wait(void);\n\tT*  timedwait(uint16_t millsec);\n    int post(T*);\n    int size();\n\nprivate:\n    queue<T*> _que;\n    Mutex         _mutex;\n    Semaphore     _sem;\n};\n\n/*=====================================\n        Class RingBuffer\n =====================================*/\nclass RingBuffer{\npublic:\n\tRingBuffer();\n\t~RingBuffer();\n\tvoid put(char* buffer);\n\tint get(char* buffer, int bufferLength);\n\tvoid reset();\nprivate:\n\tvoid* _shmaddr;\n\tuint16_t* _length;\n\tuint16_t* _start;\n\tuint16_t* _end;\n\tchar* _buffer;\n\tint _shmid;\n\tMutex* _pmx;\n\tbool _createFlg;\n};\n\n/*=====================================\n         Class Thread\n  ====================================*/\n#define MAGIC_WORD_FOR_TASK \\\n\tpublic: void EXECRUN(){try{run();}catch(Exception& ex){ex.writeMessage();\\\n    if(ex.isFatal()){stopProcess();}}catch(...){throw;}}\n\nclass Runnable{\npublic:\n\tRunnable(){}\n\tvirtual ~Runnable(){}\n\tvirtual void initialized(int argc, char** argv){}\n\tvirtual void EXECRUN(){}\n};\n\nclass Thread : virtual public Runnable{\npublic:\n\tThread();\n    ~Thread();\n\tint start(void);\n\tint join(void);\n\tint cancel(void);\n\tstatic pthread_t getID();\n\tstatic bool equals(pthread_t*, pthread_t*);\n\tvoid initialize(int argc, char** argv);\n\tvoid stopProcess(void);\nprivate:\n\tpthread_t _threadID;\n\tSemaphore* _stopProcessEvent;\n\tvoid (*_initializePtr)(int argc, char** argv);\n\n\tstatic void* _run(void*);\n\n};\n\n/*=====================================\n         Class Process\n  ====================================*/\nclass Process{\npublic:\n\tProcess();\n\tvirtual ~Process();\n\tvoid initialize(int argc, char** argv);\n\tvirtual void run();\n\tint getArgc();\n\tchar** getArgv();\n\tchar*  getArgv(char option);\n\tint    getParam(const char* param, char* value);\n\tvoid   putLog(const char* format, ...);\n\tvoid   resetRingBuffer();\n\tint    checkSignal();\n\tconst char*  getLog(void);\n\tvoid   releaseLog(void);\nprivate:\n\tint _argc;\n\tchar** _argv;\n\tRingBuffer* _rb;\n\tMutex _mt;\n\tSemaphore* _rbsem;\n\tchar _rbdata[PROCESS_LOG_BUFFER_SIZE + 1];\n\n};\n\nextern Process* theProcess;\n\n/*=====================================\n         Class MultiTaskProcess\n  ====================================*/\nclass MultiTaskProcess: public Process{\n\tfriend int main(int, char**);\n\tfriend class Thread;\npublic:\n\tMultiTaskProcess();\n\tvirtual ~MultiTaskProcess();\n\tvoid attach(Thread* thread);\n\tint getArgc();\n\tchar** getArgv();\n\tchar*  getArgv(char option);\n\tint    getParam(const char* param, char* value);\nprotected:\n\tvoid initialize(int argc, char** argv);\n\tvoid run();\n\tSemaphore* getStopProcessEvent();\n\nprivate:\n\tlist<Thread*> _threadList;\n\tSemaphore _stopProcessEvent;\n\tMutex  _mutex;\n};\n\nextern MultiTaskProcess* theMultiTask;\n\n\n/*=====================================\n        Class Exception\n =====================================*/\nenum ExceptionType {\n\tExInfo = 0,\n\tExWarn,\n\tExError,\n\tExFatal,\n\tExDebug\n};\n\n#define THROW_EXCEPTION(type, exceptionNo, message) \\\n\tthrow Exception(type, exceptionNo, message, __FILE__, __func__, __LINE__)\n\n\nclass Exception : public exception {\npublic:\n    Exception(const ExceptionType type, const int exNo, const string& message);\n    Exception(const ExceptionType type, const int exNo, const string& message,\n    \t\t   const char*, const char*, const int);\n    virtual ~Exception() throw();\n    const char* getFileName();\n    const char* getFunctionName();\n    const int getLineNo();\n    const int getExceptionNo();\n    virtual const char* what() const throw();\n    void writeMessage();\n    bool isFatal();\n\nprivate:\n    const char* strType();\n    ExceptionType _type;\n    int _exNo;\n    string _message;\n    const char* _fileName;\n    const char* _functionName;\n    int _line;\n};\n\n\n/*============================================\n                Timer\n ============================================*/\nclass Timer {\npublic:\n    Timer();\n    void start(uint32_t msec = 0);\n    bool isTimeup(uint32_t msec);\n    bool isTimeup(void);\n    void stop();\nprivate:\n    struct timeval _startTime;\n    uint32_t _millis;\n};\n\n/*=====================================\n        Class EventQue\n =====================================*/\ntemplate<class T> EventQue<T>::EventQue(){\n\n}\n\ntemplate<class T> EventQue<T>::~EventQue(){\n\t_mutex.lock();\n\twhile(!_que.empty()){\n\t\tdelete _que.front();\n\t\t_que.pop();\n\t}\n\t_mutex.unlock();\n}\n\ntemplate<class T> T* EventQue<T>::wait(void){\n\tT* ev;\n\t_sem.wait();\n\t_mutex.lock();\n\tev = _que.front();\n\t_que.pop();\n\t_mutex.unlock();\n\treturn ev;\n}\n\ntemplate<class T> T* EventQue<T>::timedwait(uint16_t millsec){\n\tT* ev;\n\t_sem.timedwait(millsec);\n\t_mutex.lock();\n\n\tif(_que.empty()){\n\t\tev = new T();\n\t\tev->setTimeout();\n\t}else{\n\t\tev = _que.front();\n\t\t_que.pop();\n\t}\n\t_mutex.unlock();\n\treturn ev;\n}\n\ntemplate<class T> int EventQue<T>::post(T* ev){\n\t_mutex.lock();\n\t_que.push(ev);\n\t_mutex.unlock();\n\t_sem.post();\n\treturn 0;\n}\n\ntemplate<class T> int EventQue<T>::size(){\n\t_mutex.lock();\n\tint sz = _que.size();\n\t_mutex.unlock();\n\treturn sz;\n}\n\n\n#endif /* PROCESSFRAMEWORK_H_ */\n"
  },
  {
    "path": "README.md",
    "content": "MQTT-SN  over UDP and XBee \n======\n***Updated Gateway has been contributed to paho.***       \n***Latest Gateway can connect to AWS IoT.***            \nhttps://github.com/eclipse/paho.mqtt-sn.embedded-c/tree/gateway\n\n*  MQTT-SN Gateway over XBee or UDP (running on linux)    \n*  MQTT-SN Client over XBee (running on linux, Arduino and mbed)     \n*  MQTT-SN Client over UDP  (running on linux and Arduino)    \n\nAsyncMQTT-SN is available.  https://github.com/ty4tw/AsyncMQTT-SN\n  \n\nSupported functions\n-------------------\n\n*  QOS Level 0 and 1    \n*  SEARCHGW, GWINFO    \n*  CONNECT, WILLTOPICREQ, WILLTOPIC, WILLMSGREQ, WILLMSG    \n*  PINGREQ, PINGRESP    \n*  CONNACK, REGISTER, REGACK, SUBACK, PUBACK, UNSUBACK     \n*  SUBSCRIBE, PUBLISH, UNSUBSCRIBE, DISCONNECT    \n\nImplemented control flows:  \n   Application program executes PUBLISH() function,   \n   Protocol flow as berrow is conducted automaticaly.  \n\n\n                 Client              Gateway               Broker\n                    |                   |                    |      \n       PUBLISH() -->| --- SERCHGW ----> |                    |  \n                    | <-- GWINFO  ----- |                    |  \n                    | --- CONNECT ----> |                    |  \n                    | <--WILLTOPICREQ-- |                    |  \n                    | --- WILLTOPIC --> |                    |  \n                    | <-- WILLMSGREQ -- |                    |  \n                    | --- WILLMSG ----> | ---- CONNECT ----> |(accepted)     \n                    | <-- CONNACK ----- | <--- CONNACK ----- |   \n                    | --- PUBLISH ----> |                    |  \n                    | <-- PUBACK  ----- | (invalid TopicId)  |  \n                    | --- REGISTER ---> |                    |  \n                    | <-- REGACK  ----- |                    |  \n                    | --- PUBLISH ----> | ---- PUBLISH ----> |(accepted)  \n                    | <-- PUBACK  ----- | <---- PUBACK ----- |    \n                    |                   |                    |    \n                    //                  //                   //      \n                    |                   |                    |          \n     SUBSCRIBE() -->| --- SUBSCRIBE --> | ---- SUBSCRIBE --> |     \n     [set Callback] | <-- SUBACK ------ | <--- SUBACK ------ |    \n                    |                   |                    |    \n                    //                  //                   //    \n                    |                   |                    |    \n                    | <-- REGISTER ---- | <--- PUBLISH ----- |<-- PUBLISH  \n    [exec Callback] | <-- PUBLISH  ---- |                    |  \n                    | --- PUBACK   ---> | ---- PUBACK  ----> |--> PUBACK  \n                    |                   |                    |  \n                \nLicense\n-------------------\nThis source code is available under the BSD license \n  \n\n"
  }
]