mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2026-02-03 12:03:44 +01:00
232
.cproject
232
.cproject
@@ -1,352 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.767762182" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.default" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitleak.778932189" name="Sanitize memory leak (-fsanitize=leak)" superClass="gnu.cpp.compiler.option.debugging.sanitleak" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitpointers.435146187" name="Sanitize pointer operations (-fsanitize=pointer-compare -fsanitize=pointer-subtract)" superClass="gnu.cpp.compiler.option.debugging.sanitpointers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.sanitaddress.501742254" name="Sanitize address (-fsanitize=address)" superClass="gnu.cpp.compiler.option.debugging.sanitaddress" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.1354093543" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DTLS"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.798283837" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1870583388" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
|
||||
<listOptionValue builtIn="false" value="ssl"/>
|
||||
<listOptionValue builtIn="false" value="crypto"/>
|
||||
<listOptionValue builtIn="false" value="pthread"/>
|
||||
<listOptionValue builtIn="false" value="bluetooth"/>
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.170974409" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="MQTTSNGateway/src/linux/loralink|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNGateway/src/linux/udp6|MQTTSNClient|MQTTSNGateway/src/MQTTSNGWProxy.cpp|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/src/linux/xbee|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src/tests|MQTTSNGateway/src/tests/mainTestProcessFramework.cpp|ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
<entry excluding="GatewayTester|src/linux/udp6|src/linux/udp|src/linux/dtls/SensorNetSubTask.cpp|GatewayTester/samples/ClientSub|GatewayTester/samples/ClientPubQoS-1|GatewayTester/samples/ClientPub|src/linux/rfcomm|src/tests|src/linux/xbee|src/mainLogmonitor.cpp|src/linux/loralink" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNGateway"/>
|
||||
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
|
||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="gnu.cpp.compiler.option.dialect.std.216116103" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1094525037" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.162341902" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.456127079" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1623573602" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.68366124" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||
|
||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||
|
||||
</option>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1879517971" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
|
||||
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||
|
||||
</option>
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
||||
</inputType>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
||||
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNClient|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
|
||||
<entry excluding="udp6|xbee|loralink" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src/linux"/>
|
||||
|
||||
<entry excluding="MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/GatewayTester/samples/ClientPub|MQTTSNGateway/src/tests/mainTestProcess.cpp|MQTTSNGateway/src/linux|MQTTSNGateway|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp|MQTTSNGateway/GatewayTester/samples/ClientSub|MQTTSNClient|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/GatewayTester/samples/ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src|MQTTSNPacket/src|MQTTSNGateway/GatewayTester|ClientPubQoS-1" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug"/>
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.246546722;cdt.managedbuild.tool.gnu.c.compiler.input.456127079">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</scannerConfigBuildInfo>
|
||||
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -5,8 +5,15 @@
|
||||
*.pyc
|
||||
/doc/MQTTSNClient/
|
||||
/doc/MQTTSNPacket/
|
||||
/rbmutex.key
|
||||
/ringbuffer.key
|
||||
rbmutex.key
|
||||
ringbuffer.key
|
||||
/Release/
|
||||
/Debug/
|
||||
/core
|
||||
Build/
|
||||
*.a
|
||||
CMakeFiles/
|
||||
*.cmake
|
||||
CMakeCache.txt
|
||||
bin/
|
||||
/build.gateway/
|
||||
@@ -1,48 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176156747064280842" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-176157551606184930" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
</project>
|
||||
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
@@ -0,0 +1,77 @@
|
||||
eclipse.preferences.version=1
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem=Error
|
||||
fr.ac6.mcu.ide.source.checker.libnano.problem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Float formatting support\\")"}
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
||||
org.eclipse.cdt.qt.core.qtproblem=Warning
|
||||
org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null}
|
||||
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_settings_version=1
|
||||
12
.travis.yml
12
.travis.yml
@@ -13,20 +13,12 @@ addons:
|
||||
- g++-4.8
|
||||
- cmake
|
||||
- cmake-data
|
||||
- bluez
|
||||
- libbluetooth-dev
|
||||
|
||||
script:
|
||||
- ./travis-build.sh
|
||||
|
||||
- cd MQTTSNGateway
|
||||
- make SENSORNET="xbee"
|
||||
- make SENSORNET="udp"
|
||||
- make SENSORNET="udp6"
|
||||
|
||||
- make test
|
||||
|
||||
- cd GatewayTester
|
||||
- make
|
||||
|
||||
notifications:
|
||||
emails:
|
||||
- tomoaki@tomy-tech.com
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# Ian Craggs - initial version
|
||||
#*******************************************************************************/
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
|
||||
PROJECT("paho-mqttsn" CXX)
|
||||
MESSAGE(STATUS "CMake version: " ${CMAKE_VERSION})
|
||||
MESSAGE(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
|
||||
@@ -39,3 +39,4 @@ INCLUDE(CPack)
|
||||
ENABLE_TESTING()
|
||||
|
||||
ADD_SUBDIRECTORY(MQTTSNPacket)
|
||||
ADD_SUBDIRECTORY(MQTTSNGateway)
|
||||
16
MQTTSNGateway/CMakeLists.txt
Normal file
16
MQTTSNGateway/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
#*******************************************************************************/
|
||||
ADD_SUBDIRECTORY(src)
|
||||
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
Binary file not shown.
@@ -20,6 +20,10 @@ CPPSRCS := \
|
||||
$(SUBDIR)/LGwProxy.cpp \
|
||||
$(SUBDIR)/LMqttsnClient.cpp \
|
||||
$(SUBDIR)/LNetworkUdp.cpp \
|
||||
$(SUBDIR)/LNetworkUdp6.cpp \
|
||||
$(SUBDIR)/LNetworkRfcomm.cpp \
|
||||
$(SUBDIR)/LNetworkDtls.cpp \
|
||||
$(SUBDIR)/LNetworkDtls6.cpp \
|
||||
$(SUBDIR)/LPublishManager.cpp \
|
||||
$(SUBDIR)/LRegisterManager.cpp \
|
||||
$(SUBDIR)/LSubscribeManager.cpp \
|
||||
@@ -36,12 +40,14 @@ $(SUBDIR)/Util.cpp \
|
||||
CXX := g++
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDES += -I$(SUBDIR)
|
||||
DEFS :=
|
||||
LIBS +=
|
||||
INCLUDES += -I$(SUBDIR) -I/usr/local/opt/openssl/include
|
||||
DEF1 :=
|
||||
DEF2 :=
|
||||
DEFS := -D$(SN) $(DEF1) $(DEF2)
|
||||
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl/lib
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD :=
|
||||
LDADD := -lssl -lcrypto $(LDADDBLT)
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGTEST)
|
||||
@@ -75,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
$(CXX) $(DEFS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
###Gateway Test Program.
|
||||
# Gateway Test Program.
|
||||
**sample/mainTest.cpp** is a Test sample coading.
|
||||
Each test is described as one function. test1(), test2()...
|
||||
````
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*
|
||||
* you can use 4 commands in Test functions
|
||||
*
|
||||
* 1) PUBLISH(const char* topicName,
|
||||
* uint8_t* payload,
|
||||
* uint16_t len,
|
||||
* uint8_t qos,
|
||||
* bool retain = false);
|
||||
*
|
||||
* 2) SUBSCRIBE(const char* topicName,
|
||||
* TopicCallback onPublish,
|
||||
* uint8_t qos);
|
||||
*
|
||||
* 3) UNSUBSCRIBE(const char* topicName);
|
||||
*
|
||||
* 4) DISCONNECT(uint16_t sleepInSecs);
|
||||
*
|
||||
*------------------------------------------------------*/
|
||||
|
||||
```
|
||||
void test1(void)
|
||||
{
|
||||
char payload[300];
|
||||
@@ -36,9 +15,35 @@ void test2(void)
|
||||
uint8_t qos = 1;
|
||||
SUBSCRIBE(topic2, on_publish02, qos);
|
||||
}
|
||||
````
|
||||
**TEST_LIST** is a test senario. Test functions are executed one by one.
|
||||
````
|
||||
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* MQTT-SN GATEWAY TEST CLIENT
|
||||
*
|
||||
* Supported functions.
|
||||
*
|
||||
* void PUBLISH ( const char* topicName, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void PUBLISH ( uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false );
|
||||
*
|
||||
* void SUBSCRIBE ( const char* topicName, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
|
||||
*
|
||||
* void UNSUBSCRIBE ( const char* topicName );
|
||||
*
|
||||
* void UNSUBSCRIBE ( uint16_t topicId );
|
||||
*
|
||||
* void DISCONNECT ( uint16_t sleepInSecs );
|
||||
*
|
||||
* void CONNECT ( void );
|
||||
*
|
||||
* void DISPLAY( format, .....); <== instead of printf()
|
||||
*--------------------------------------------------------------------------
|
||||
|
||||
```
|
||||
**TEST_LIST** is a test senario. Test functions are executed interactively.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* A List of Test Tasks
|
||||
*------------------------------------------------------*/
|
||||
@@ -52,68 +57,61 @@ TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Disconnect", test5),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
````
|
||||
|
||||
### **step1. Build **
|
||||
````
|
||||
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
||||
$ make
|
||||
$ make install
|
||||
$ make clean
|
||||
```
|
||||
MQTT-SNGatewayTester program is copied into ../../../ directory.
|
||||
|
||||
**UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
|
||||
```
|
||||
/*------------------------------------------------------
|
||||
* UDP, DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff12::feed:caca:dead", // Multicast group IP
|
||||
"wlp4s0",
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### **step2. Execute Gateway Tester.**
|
||||
## How to Build
|
||||
```
|
||||
copy codes from the github.
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
||||
$ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
|
||||
```
|
||||
|
||||
````
|
||||
$ cd ../../..
|
||||
$ ./MQTT-SNGatewayTester
|
||||
|
||||
## Execute Gateway Tester
|
||||
```
|
||||
$ ./Build/MQTT-SNGatewayTester
|
||||
|
||||
***************************************************************************
|
||||
* MQTT-SN Gateway Tester
|
||||
* MQTT-SN Gateway Tester DTLS
|
||||
* Part of Project Paho in Eclipse
|
||||
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
|
||||
*
|
||||
* Author : Tomoaki YAMAGUCHI
|
||||
* Version: 0.0.0
|
||||
* Version: 2.0.0
|
||||
***************************************************************************
|
||||
|
||||
Attempting to Connect the Broker.....
|
||||
Execute "Step0:Connect" ? ( y/n ) :
|
||||
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
sendto 225.1.1.1 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.5 :1883 03 01 00
|
||||
|
||||
recved 192.168.11.17 :10000 03 02 01
|
||||
sendto 192.168.11.17 :10000 13 04 0c 01 03 84 47 61 74 65 77 61 79 54 65 73 74 65 72
|
||||
|
||||
recved 192.168.11.17 :10000 02 06
|
||||
sendto 192.168.11.17 :10000 0c 07 00 77 69 6c 6c 54 6f 70 69 63
|
||||
|
||||
recved 192.168.11.17 :10000 02 08
|
||||
sendto 192.168.11.17 :10000 0d 09 77 69 6c 6c 4d 65 73 73 61 67 65
|
||||
|
||||
recved 192.168.11.17 :10000 03 05 00
|
||||
|
||||
|
||||
Connected to the Broker
|
||||
|
||||
Attempting OnConnect.....
|
||||
sendto 192.168.11.17 :10000 13 12 20 00 01 74 79 34 74 77 2f 63 6c 69 65 6e 74 49 64
|
||||
|
||||
recved 192.168.11.17 :10000 08 13 20 00 01 00 01 00
|
||||
|
||||
|
||||
SUBSCRIBE complete. ty4tw/clientId
|
||||
|
||||
OnConnect complete
|
||||
Test Ready.
|
||||
|
||||
Execute Publish topic1 Test ? ( Y/N ) :
|
||||
|
||||
````
|
||||
```
|
||||
|
||||
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEF1="DEF1=${2}"
|
||||
DEF2="DEF2=${3}"
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
make SN=UDP $DEF1 $DEF2
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
make SN=UDP6 $DEF1 $DEF2
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
export LDADDBLT=-lbluetooth
|
||||
make SN=RFCOMM $DEF1 $DEF2
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
make SN=DTLS $DEF1 $DEF2
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
make SN=DTLS6 $DEF1 $DEF2
|
||||
elif [ $1 == "clean" ] ; then
|
||||
make clean
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -51,12 +51,29 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientPUB", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
UDPCONF = { "ClientPUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20010, // Local PortNo
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientPUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "ClientPUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
@@ -117,7 +134,7 @@ void publishTopic57(void)
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic57\" \n");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos);
|
||||
PUBLISH(topic57, (uint8_t* )payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,12 +51,29 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"QoS-1_Client01", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
UDPCONF = { "QoS-1_Client01", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20001, // Local PortNo
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "QoS-1_Client01", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "QoS-1_Client01", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
|
||||
@@ -51,12 +51,29 @@ extern LScreen* theScreen;
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"ClientSUB", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
UDPCONF = { "ClientSUB", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20011, // Local PortNo
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "ClientSUB", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "ClientSUB", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
|
||||
@@ -49,27 +49,43 @@ extern LMqttsnClient* theClient;
|
||||
extern LScreen* theScreen;
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP Configuration (theNetcon)
|
||||
* UDP,DTLS Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDPCONF = {
|
||||
"GatewayTestClient", // ClientId
|
||||
{225,1,1,1}, // Multicast group IP
|
||||
UDPCONF = { "GatewayTestClient", // ClientId
|
||||
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* UDP6, DTLS6 Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||
"ff1e:feed:caca:dead::1", // Multicast group IP
|
||||
"wlp4s0", // Network Interface
|
||||
1883, // Multicast group Port
|
||||
20020, // Local PortNo
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* RFCOMM Configuration (theNetcon)
|
||||
*------------------------------------------------------*/
|
||||
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||
"60:57:18:06:8B:72", // GW Address
|
||||
1, // Rfcomm channel
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Client Configuration (theMqcon)
|
||||
*------------------------------------------------------*/
|
||||
MQTTSNCONF = {
|
||||
60, //KeepAlive [seconds]
|
||||
MQTTSNCONF = { 60, //KeepAlive [seconds]
|
||||
true, //Clean session
|
||||
300, //Sleep duration [seconds]
|
||||
"", //WillTopic
|
||||
"", //WillMessage
|
||||
0, //WillQos
|
||||
false //WillRetain
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Define Topics
|
||||
@@ -78,37 +94,45 @@ const char* topic1 = "ty4tw/topic1";
|
||||
const char* topic2 = "ty4tw/topic2";
|
||||
const char* topic3 = "ty4tw/topic3";
|
||||
const char* topic4 = "ty4tw/topic4";
|
||||
const char* topic40 = "ty4tw/#";
|
||||
const char* topic51 = "ty4tw/topic5/1";
|
||||
const char* topic52 = "ty4tw/topic5/2";
|
||||
const char* topic53 = "ty4tw/topic5/3";
|
||||
const char* topic50 = "ty4tw/topic5/+";
|
||||
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Callback routines for Subscribed Topics
|
||||
*------------------------------------------------------*/
|
||||
int on_Topic01(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nTopic1 recv.\n");
|
||||
char c = pload[ploadlen-1];
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s%c<--\n\n",pload, c);
|
||||
char c = pload[ploadlen - 1];
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s%c<--\n\n", pload, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_Topic02(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nTopic2 recv.\n");
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n",pload);
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nNew callback recv Topic3\n");
|
||||
pload[ploadlen-1]= 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n",pload);
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_TopicWildcard(uint8_t* pload, uint16_t ploadlen)
|
||||
{
|
||||
DISPLAY("\n\nNew callback recv TopicWildcard\n");
|
||||
pload[ploadlen - 1] = 0; // set null terminator
|
||||
DISPLAY("Payload -->%s <--\n\n", pload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -116,40 +140,51 @@ int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
||||
* A Link list of Callback routines and Topics
|
||||
*------------------------------------------------------*/
|
||||
|
||||
SUBSCRIBE_LIST = {// e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUBSCRIBE_LIST =
|
||||
{ // e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
||||
END_OF_SUBSCRIBE_LIST
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Test functions
|
||||
*------------------------------------------------------*/
|
||||
void subscribePredefTopic1(void)
|
||||
{
|
||||
SUBSCRIBE(1, on_Topic03, QoS1);
|
||||
SUBSCRIBE_PREDEF(1, on_Topic03, QoS1);
|
||||
}
|
||||
|
||||
void publishTopic1(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/Topic1\" \n");
|
||||
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), QoS0);
|
||||
}
|
||||
|
||||
void subscribeTopic10(void)
|
||||
{
|
||||
SUBSCRIBE(10, on_Topic02, QoS1);
|
||||
sprintf(payload, "publish \"ty4tw/topic1\" \n");
|
||||
PUBLISH(topic1, (uint8_t* )payload, strlen(payload), QoS0);
|
||||
}
|
||||
|
||||
void publishTopic2(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic2\" \n");
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), QoS1);
|
||||
PUBLISH(topic2, (uint8_t* )payload, strlen(payload), QoS1);
|
||||
}
|
||||
|
||||
void publishTopic4(void)
|
||||
{
|
||||
char payload[300];
|
||||
sprintf(payload, "publish \"ty4tw/topic40\" \n");
|
||||
PUBLISH(topic4, (uint8_t* )payload, strlen(payload), QoS1);
|
||||
}
|
||||
|
||||
void subscribeTopic10(void)
|
||||
{
|
||||
SUBSCRIBE_PREDEF(10, on_Topic02, QoS1);
|
||||
}
|
||||
|
||||
void subscribeWildcardTopic(void)
|
||||
{
|
||||
SUBSCRIBE(topic50, on_TopicWildcard, QoS1);
|
||||
}
|
||||
|
||||
|
||||
void unsubscribe(void)
|
||||
@@ -167,7 +202,7 @@ void test3(void)
|
||||
char payload[300];
|
||||
sprintf(payload, "TEST3 ");
|
||||
uint8_t qos = 0;
|
||||
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos);
|
||||
PUBLISH(topic2, (uint8_t* )payload, strlen(payload), qos);
|
||||
}
|
||||
|
||||
void disconnect(void)
|
||||
@@ -180,40 +215,69 @@ void asleep(void)
|
||||
DISCONNECT(theMqcon.sleepDuration);
|
||||
}
|
||||
|
||||
void onconnect(void)
|
||||
{
|
||||
ONCONNECT();
|
||||
}
|
||||
|
||||
void connect(void)
|
||||
{
|
||||
CONNECT();
|
||||
}
|
||||
|
||||
void DisableAutoPingreq(void)
|
||||
{
|
||||
SetAutoPingReqMode(false);
|
||||
}
|
||||
|
||||
void CleanSessionOff(void)
|
||||
{
|
||||
SetCleanSession(false);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------
|
||||
* A List of Test functions is valid in case of
|
||||
* line 23 of LMqttsnClientApp.h is commented out.
|
||||
* //#define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
|
||||
TEST_LIST = {// e.g. TEST( Label, Test),
|
||||
TEST("Step0:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step1:Publish topic1", publishTopic1),
|
||||
TEST("Step2:Publish topic2", publishTopic2),
|
||||
TEST("Step3:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST_LIST =
|
||||
{ // e.g. TEST( Label, Test),
|
||||
TEST("Step0:Connect", connect),
|
||||
TEST("Step1:Subscribe list", onconnect),
|
||||
TEST("Step2:Subscribe predef topic1", subscribePredefTopic1),
|
||||
TEST("Step3:Publish topic1", publishTopic1),
|
||||
TEST("Step4:Publish topic2", publishTopic2),
|
||||
TEST("Step5:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step5:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||
TEST("Step6:Publish topic2", publishTopic2),
|
||||
TEST("Step7:subscribe again", subscribechangeCallback),
|
||||
TEST("Step7:Unsubscribe topic2", unsubscribe),
|
||||
TEST("Step8:Publish topic2", publishTopic2),
|
||||
TEST("Step9:Sleep ", asleep),
|
||||
TEST("Step10:Publish topic1", publishTopic1),
|
||||
TEST("Step11:Disconnect", disconnect),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
TEST("Step9:subscribe again", subscribechangeCallback),
|
||||
TEST("Step10:Publish topic2", publishTopic2),
|
||||
|
||||
TEST("Step11:Sleep ", asleep),
|
||||
TEST("Step12:Publish topic1", publishTopic1),
|
||||
TEST("Step13:Disconnect", disconnect),
|
||||
TEST("Step14:Publish topic2", publishTopic1),
|
||||
TEST("Step15:Connect", connect),
|
||||
TEST("Step16:Publish topic2", publishTopic2),
|
||||
TEST("Step17:Auto Pingreq mode off", DisableAutoPingreq),
|
||||
TEST("Step18:Publish topic2", publishTopic1),
|
||||
TEST("Step19:Disconnect", disconnect),
|
||||
END_OF_TEST_LIST
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* List of tasks is valid in case of line23 of
|
||||
* LMqttsnClientApp.h is uncommented.
|
||||
* #define CLIENT_MODE
|
||||
*------------------------------------------------------*/
|
||||
TASK_LIST = {// e.g. TASK( task, executing duration in second),
|
||||
TASK(publishTopic1, 4), // publishTopic1() is executed every 4 seconds
|
||||
TASK(publishTopic2, 7), // publishTopic2() is executed every 7 seconds
|
||||
TASK_LIST =
|
||||
{ // e.g. TASK( task, executing duration in second),
|
||||
TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
|
||||
TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
|
||||
END_OF_TASK_LIST
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*------------------------------------------------------
|
||||
* Initialize function
|
||||
@@ -223,5 +287,4 @@ void setup(void)
|
||||
SetForwarderMode(false);
|
||||
}
|
||||
|
||||
|
||||
/***************** END OF PROGRAM ********************/
|
||||
|
||||
@@ -57,6 +57,8 @@ LGwProxy::LGwProxy()
|
||||
_initialized = 0;
|
||||
_isForwarderMode = false;
|
||||
_isQoSMinus1Mode = false;
|
||||
_isPingReqMode = true;
|
||||
_isAutoConnectMode = true;
|
||||
}
|
||||
|
||||
LGwProxy::~LGwProxy()
|
||||
@@ -64,16 +66,20 @@ LGwProxy::~LGwProxy()
|
||||
_topicTbl.clearTopic();
|
||||
}
|
||||
|
||||
void LGwProxy::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LGwProxy::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_network.initialize(netconf);
|
||||
_clientId = netconf.clientId;
|
||||
_willTopic = mqconf.willTopic;
|
||||
_willMsg = mqconf.willMsg;
|
||||
_qosWill = mqconf.willQos;
|
||||
_retainWill = mqconf.willRetain;
|
||||
_cleanSession = mqconf.cleanSession;
|
||||
_tkeepAlive = mqconf.keepAlive;
|
||||
if (_network.initialize(netconf) == false)
|
||||
{
|
||||
DISPLAY("Can't open SensorNetwork\n");
|
||||
exit(-1);
|
||||
}
|
||||
_clientId = netconf->clientId;
|
||||
_willTopic = mqconf->willTopic;
|
||||
_willMsg = mqconf->willMsg;
|
||||
_qosWill = mqconf->willQos;
|
||||
_retainWill = mqconf->willRetain;
|
||||
_cleanSession = mqconf->cleanSession;
|
||||
_tkeepAlive = mqconf->keepAlive;
|
||||
_initialized = 1;
|
||||
}
|
||||
|
||||
@@ -85,6 +91,12 @@ void LGwProxy::connect()
|
||||
{
|
||||
pos = _msg;
|
||||
|
||||
if (!_network.isBroadcastable() && _status == GW_LOST)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_status == GW_LOST)
|
||||
{
|
||||
|
||||
@@ -188,7 +200,24 @@ int LGwProxy::getConnectResponce(void)
|
||||
{
|
||||
_network.setGwAddress();
|
||||
_gwId = _mqttsnMsg[1];
|
||||
|
||||
#if defined(DTLS) || defined(DTLS6)
|
||||
for (int i = 0; i < MQTTSN_RETRY_COUNT; i++)
|
||||
{
|
||||
if (_network.sslConnect() > 0)
|
||||
{
|
||||
_status = GW_CONNECTING;
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection established.\033[0m\033[0;37m\n\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection failed.\033[0m\033[0;37m\n\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
_status = GW_CONNECTING;
|
||||
#endif
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
||||
{
|
||||
@@ -231,9 +260,12 @@ int LGwProxy::getConnectResponce(void)
|
||||
|
||||
void LGwProxy::reconnect(void)
|
||||
{
|
||||
if (_isAutoConnectMode)
|
||||
{
|
||||
D_MQTTLOG("...Gateway reconnect\r\n");
|
||||
_status = GW_DISCONNECTED;
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
void LGwProxy::disconnect(uint16_t secs)
|
||||
@@ -395,7 +427,7 @@ int LGwProxy::getMessage(void)
|
||||
}
|
||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_DISCONNECT)
|
||||
{
|
||||
_status = GW_LOST;
|
||||
_status = GW_DISCONNECTED;
|
||||
_gwAliveTimer.stop();
|
||||
_keepAliveTimer.stop();
|
||||
}
|
||||
@@ -586,7 +618,7 @@ uint16_t LGwProxy::getNextMsgId(void)
|
||||
|
||||
void LGwProxy::checkPingReq(void)
|
||||
{
|
||||
if ( _isQoSMinus1Mode )
|
||||
if (_isQoSMinus1Mode || _isPingReqMode == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -671,3 +703,23 @@ void LGwProxy::setQoSMinus1Mode(bool valid)
|
||||
{
|
||||
_isQoSMinus1Mode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setPingReqMode(bool valid)
|
||||
{
|
||||
_isPingReqMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setAutoConnectMode(bool valid)
|
||||
{
|
||||
_isAutoConnectMode = valid;
|
||||
}
|
||||
|
||||
void LGwProxy::setSessionMode(bool valid)
|
||||
{
|
||||
_cleanSession = valid;
|
||||
}
|
||||
|
||||
uint8_t LGwProxy::getStatus(void)
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LRegisterManager.h"
|
||||
#include "LTimer.h"
|
||||
#include "LTopicTable.h"
|
||||
@@ -42,6 +46,7 @@ using namespace std;
|
||||
#define GW_SLEEPING 10
|
||||
#define GW_DISCONNECTED 11
|
||||
#define GW_SLEPT 12
|
||||
#define SSL_CONNECTING 13
|
||||
|
||||
#define GW_WAIT_PINGRESP 1
|
||||
|
||||
@@ -54,7 +59,7 @@ public:
|
||||
LGwProxy();
|
||||
~LGwProxy();
|
||||
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void connect(void);
|
||||
void disconnect(uint16_t sec = 0);
|
||||
int getMessage(void);
|
||||
@@ -67,6 +72,9 @@ public:
|
||||
void setAdvertiseDuration(uint16_t duration);
|
||||
void setForwarderMode(bool valid);
|
||||
void setQoSMinus1Mode(bool valid);
|
||||
void setPingReqMode(bool valid);
|
||||
void setAutoConnectMode(bool valid);
|
||||
void setSessionMode(bool valid);
|
||||
void reconnect(void);
|
||||
int writeMsg(const uint8_t* msg);
|
||||
void setPingReqTimer(void);
|
||||
@@ -74,6 +82,7 @@ public:
|
||||
LTopicTable* getTopicTable(void);
|
||||
LRegisterManager* getRegisterManager(void);
|
||||
const char* getClientId(void);
|
||||
uint8_t getStatus(void);
|
||||
private:
|
||||
int readMsg(void);
|
||||
void writeGwMsg(void);
|
||||
@@ -111,6 +120,8 @@ private:
|
||||
uint16_t _tWake;
|
||||
bool _isForwarderMode;
|
||||
bool _isQoSMinus1Mode;
|
||||
bool _isPingReqMode;
|
||||
bool _isAutoConnectMode;
|
||||
char _msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern TaskList theTaskList[];
|
||||
extern TestList theTestList[];
|
||||
extern OnPublishList theOnPublishList[];
|
||||
extern MQTTSNCONF;
|
||||
extern UDPCONF;
|
||||
extern SENSORNET_CONFIG_t theNetcon;
|
||||
extern void setup(void);
|
||||
|
||||
/*=====================================
|
||||
@@ -50,7 +50,20 @@ int main(int argc, char** argv)
|
||||
#ifndef CLIENT_MODE
|
||||
char c = 0;
|
||||
printf("\n%s", PAHO_COPYRIGHT4);
|
||||
printf("\n%s\n", PAHO_COPYRIGHT0);
|
||||
printf("\n%s", PAHO_COPYRIGHT0);
|
||||
#if defined(UDP)
|
||||
printf("UDP ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(UDP6)
|
||||
printf("UDP6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS)
|
||||
printf("DTLS ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(DTLS6)
|
||||
printf("DTLS6 ClientId:%s PortNo:%d\n", theNetcon.clientId, theNetcon.uPortNo);
|
||||
#elif defined(RFCOMM)
|
||||
printf("RFCOMM ClientId:%s channel:%d\n", theNetcon.clientId, theNetcon.channel);
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
printf("%s\n", PAHO_COPYRIGHT1);
|
||||
printf("%s\n", PAHO_COPYRIGHT2);
|
||||
printf(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
@@ -77,11 +90,13 @@ int main(int argc, char** argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
theClient->setAutoConnectMode(false);
|
||||
theClient->getPublishManager()->setAutoConnectMode(false);
|
||||
#endif
|
||||
|
||||
setup();
|
||||
theClient->addTask(theClientMode);
|
||||
theClient->initialize( theNetcon, theMqcon);
|
||||
theClient->initialize( &theNetcon, &theMqcon);
|
||||
do
|
||||
{
|
||||
theClient->run();
|
||||
@@ -98,7 +113,7 @@ int main(int argc, char** argv)
|
||||
======================================*/
|
||||
LMqttsnClient::LMqttsnClient()
|
||||
{
|
||||
|
||||
_isAutoConnect = true;
|
||||
}
|
||||
|
||||
LMqttsnClient::~LMqttsnClient()
|
||||
@@ -106,10 +121,10 @@ LMqttsnClient::~LMqttsnClient()
|
||||
|
||||
}
|
||||
|
||||
void LMqttsnClient::initialize(LUdpConfig netconf, LMqttsnConfig mqconf)
|
||||
void LMqttsnClient::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
|
||||
{
|
||||
_gwProxy.initialize(netconf, mqconf);
|
||||
setSleepDuration(mqconf.sleepDuration);
|
||||
setSleepDuration(mqconf->sleepDuration);
|
||||
}
|
||||
|
||||
void LMqttsnClient::addTask(bool clientMode)
|
||||
@@ -183,9 +198,10 @@ void LMqttsnClient::subscribe(const char* topicName, TopicCallback onPublish, ui
|
||||
_subMgr.subscribe(topicName, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LMqttsnClient::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish,
|
||||
uint8_t qos)
|
||||
{
|
||||
_subMgr.subscribe(topicId, onPublish, qos);
|
||||
_subMgr.subscribePredefinedId(topicId, onPublish, qos);
|
||||
}
|
||||
|
||||
void LMqttsnClient::unsubscribe(const char* topicName)
|
||||
@@ -205,10 +221,20 @@ void LMqttsnClient::disconnect(uint16_t sleepInSecs)
|
||||
|
||||
void LMqttsnClient::run()
|
||||
{
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_gwProxy.connect();
|
||||
}
|
||||
_taskMgr.run();
|
||||
}
|
||||
|
||||
void LMqttsnClient::setAutoConnectMode(uint8_t flg)
|
||||
{
|
||||
_isAutoConnect = flg;
|
||||
_pubMgr.setAutoConnectMode(flg);
|
||||
_gwProxy.setAutoConnectMode(flg);
|
||||
}
|
||||
|
||||
void LMqttsnClient::setSleepMode(uint32_t duration)
|
||||
{
|
||||
// ToDo: set WDT and sleep mode
|
||||
@@ -227,7 +253,10 @@ void LMqttsnClient::setSleepDuration(uint32_t duration)
|
||||
|
||||
void LMqttsnClient::onConnect(void)
|
||||
{
|
||||
if (_isAutoConnect)
|
||||
{
|
||||
_subMgr.onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
const char* LMqttsnClient::getClientId(void)
|
||||
|
||||
@@ -54,15 +54,16 @@ public:
|
||||
void publish(uint16_t topicId, Payload* payload, uint8_t qos, bool retain = false);
|
||||
void publish(uint16_t topicId, uint8_t* payload, uint16_t len, uint8_t qos, bool retain = false);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(const uint16_t topicId);
|
||||
void disconnect(uint16_t sleepInSecs);
|
||||
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf);
|
||||
void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
|
||||
void run(void);
|
||||
void addTask(bool test);
|
||||
void setSleepDuration(uint32_t duration);
|
||||
void setSleepMode(uint32_t duration);
|
||||
void setAutoConnectMode(uint8_t flg);
|
||||
void sleep(void);
|
||||
const char* getClientId(void);
|
||||
uint16_t getTopicId(const char* topicName);
|
||||
@@ -78,6 +79,7 @@ private:
|
||||
LSubscribeManager _subMgr;
|
||||
LGwProxy _gwProxy;
|
||||
uint32_t _sleepDuration;
|
||||
uint8_t _isAutoConnect;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
#ifndef MQTTSNCLIENTAPP_H_
|
||||
#define MQTTSNCLIENTAPP_H_
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/*======================================
|
||||
* Debug Flag
|
||||
======================================*/
|
||||
//#define DEBUG_NW
|
||||
//#define DEBUG_MQTTSN
|
||||
|
||||
/*======================================
|
||||
* Program mode Flag
|
||||
======================================*/
|
||||
//#define CLIENT_MODE
|
||||
|
||||
/****************************************
|
||||
MQTT-SN Parameters
|
||||
*****************************************/
|
||||
@@ -55,7 +55,8 @@ typedef signed int int32_t;
|
||||
Application config structures
|
||||
*****************************************/
|
||||
|
||||
struct LMqttsnConfig{
|
||||
struct LMqttsnConfig
|
||||
{
|
||||
uint16_t keepAlive;
|
||||
bool cleanSession;
|
||||
uint32_t sleepDuration;
|
||||
@@ -65,13 +66,30 @@ struct LMqttsnConfig{
|
||||
bool willRetain;
|
||||
};
|
||||
|
||||
struct LUdpConfig{
|
||||
struct LUdpConfig
|
||||
{
|
||||
const char* clientId;
|
||||
uint8_t ipAddress[4];
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LUdp6Config
|
||||
{
|
||||
const char* clientId;
|
||||
const char* ipAddress;
|
||||
const char *interface;
|
||||
uint16_t gPortNo;
|
||||
uint16_t uPortNo;
|
||||
};
|
||||
|
||||
struct LRfcommConfig
|
||||
{
|
||||
const char* clientId;
|
||||
const char* gwAddress;
|
||||
uint8_t channel;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -85,13 +103,50 @@ typedef enum
|
||||
MACROs for Application
|
||||
=======================================*/
|
||||
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig
|
||||
#define NETWORK_CONFIG UdpConfig theNetworkConfig
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
#if defined(UDP)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(UDP6)
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
|
||||
#elif defined(RFCOMM)
|
||||
#define RFCOMMCONF LRfcommConfig theNetcon
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define SENSORNET_CONFIG_t LRfcommConfig
|
||||
|
||||
#elif defined(DTLS)
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define UDP6CONF LUdp6Config theU6Conf
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdpConfig
|
||||
|
||||
#elif defined(DTLS6)
|
||||
#define UDPCONF LUdpConfig theUConf
|
||||
#define UDP6CONF LUdp6Config theNetcon
|
||||
#define RFCOMMCONF LRfcommConfig theRfConf
|
||||
#define SENSORNET_CONFIG_t LUdp6Config
|
||||
#else
|
||||
#error "UDP, UDP6, DTLS, DTLS6 or RFCOMM is not defined in LMqttsnClientApp.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
|
||||
#define PUBLISH(...) theClient->publish(__VA_ARGS__)
|
||||
#define SUBSCRIBE(...) theClient->subscribe(__VA_ARGS__)
|
||||
#define SUBSCRIBE_PREDEF(...) theClient->subscribePredefinedId(__VA_ARGS__)
|
||||
#define UNSUBSCRIBE(...) theClient->unsubscribe(__VA_ARGS__)
|
||||
#define DISCONNECT(...) theClient->disconnect(__VA_ARGS__)
|
||||
#define ONCONNECT() theClient->getSubscribeManager()->onConnect()
|
||||
|
||||
#define TASK_LIST TaskList theTaskList[]
|
||||
#define TASK(...) {__VA_ARGS__, 0, 0}
|
||||
@@ -102,11 +157,13 @@ typedef enum
|
||||
#define SUBSCRIBE_LIST OnPublishList theOnPublishList[]
|
||||
#define SUB(...) {__VA_ARGS__}
|
||||
#define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0}
|
||||
#define UDPCONF LUdpConfig theNetcon
|
||||
#define MQTTSNCONF LMqttsnConfig theMqcon
|
||||
|
||||
|
||||
#define SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__)
|
||||
#define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__VA_ARGS__)
|
||||
|
||||
#define SetAutoConnectMode(...) theClient->setAutoConnectMode(__VA_ARGS__)
|
||||
#define SetAutoPingReqMode(...) theClient->getGwProxy()->setPingReqMode(__VA_ARGS__)
|
||||
#define SetCleanSession(...) theClient->getGwProxy()->setSessionMode(__VA_ARGS__)
|
||||
#ifdef CLIENT_MODE
|
||||
#define DISPLAY(...)
|
||||
#define PROMPT(...)
|
||||
@@ -195,11 +252,11 @@ typedef enum
|
||||
/*=================================
|
||||
* Starting prompt
|
||||
==================================*/
|
||||
#define TESTER_VERSION " * Version: 2.0.0"
|
||||
#define TESTER_VERSION " * Version: 2.1.0"
|
||||
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway Tester"
|
||||
#define PAHO_COPYRIGHT0 " * "
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
#define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)"
|
||||
#define PAHO_COPYRIGHT2 " * (https://github.com/eclipse/paho.mqtt-sn.embedded-c.git)"
|
||||
#define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
|
||||
#define PAHO_COPYRIGHT4 " ***************************************************************************"
|
||||
|
||||
|
||||
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtlsPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
uint16_t recvLen = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
recvLen = LDtlsPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LDtlsPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtlsPort::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class DtlsPort
|
||||
=========================================*/
|
||||
LDtlsPort::LDtlsPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LDtlsPort::~LDtlsPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LDtlsPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtlsPort::open(LUdpConfig *config)
|
||||
{
|
||||
char errmsg[256];
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
/* setup Multicast socket */
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_mreq mreq;
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtlsPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtlsPort::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int LDtlsPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LDtlsPort::checkRecvBuf()
|
||||
{
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtlsPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtlsPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo)
|
||||
{
|
||||
int reuse = 1;
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl < 0)
|
||||
{
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = portNo;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
int rc = 0;
|
||||
errno = 0;
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in));
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest);
|
||||
_ssl = SSL_new(_ctx);
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
D_NWLOG("LDtlsPort::sslConnect connect to %-15s:%-6u\n", inet_ntoa(dest.sin_addr), htons(dest.sin_port));
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS_H_
|
||||
#define NETWORKDTLS_H_
|
||||
|
||||
#ifdef DTLS
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
/*========================================
|
||||
Class LDtlsPort
|
||||
=======================================*/
|
||||
class LDtlsPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtlsPort();
|
||||
virtual ~LDtlsPort();
|
||||
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(uint32_t ipAddress, in_port_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
uint32_t _gIpAddr;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtlsPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
uint32_t _gwIpAddress;
|
||||
uint32_t _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS */
|
||||
#endif /* NETWORKDTLS_H_ */
|
||||
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <termios.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <poll.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkDtls6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
|
||||
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LDtls6Port::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LDtls6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int addrFlg = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && addrFlg && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
memcpy(&_gwIpAddress.s6_addr, &_ipAddress.s6_addr, sizeof(_ipAddress.s6_addr));
|
||||
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(&_gwIpAddress, 0, sizeof(_gwIpAddress));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LDtls6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int LNetwork::sslConnect(void)
|
||||
{
|
||||
return LDtls6Port::sslConnect(_gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class Dtls6Port
|
||||
=========================================*/
|
||||
LDtls6Port::LDtls6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
_castStat = STAT_NONE;
|
||||
_ifIndex = 0;
|
||||
_gIpAddrStr = nullptr;
|
||||
_sockfdMcast = 0;
|
||||
_sockfdSsl = 0;
|
||||
_ctx = nullptr;
|
||||
_ssl = nullptr;
|
||||
_gPortNo = _uPortNo = 0;
|
||||
}
|
||||
|
||||
LDtls6Port::~LDtls6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
}
|
||||
|
||||
void LDtls6Port::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = 0;
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
_sockfdSsl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
sockaddr_in6 addr6;
|
||||
char errmsg[256];
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Client certification and cookie are not required */
|
||||
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
_ifIndex = if_nametoindex(config->interface);
|
||||
_interfaceName = config->interface;
|
||||
}
|
||||
|
||||
/* create a multicast socket */
|
||||
_sockfdMcast = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdMcast, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = _ifIndex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LDtls6Port::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
int LDtls6Port::unicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
int status = SSL_write(_ssl, buf, length);
|
||||
if (status <= 0)
|
||||
{
|
||||
int rc = 0;
|
||||
SSL_get_error(_ssl, rc);
|
||||
DISPLAY("errno == %d in LDtls6Port::unicast\n", rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto gateway via DTLS6 ");
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gIpAddr.sin6_port));
|
||||
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LDtls6Port::checkRecvBuf()
|
||||
{
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
|
||||
uint8_t buf[2];
|
||||
fd_set recvfds;
|
||||
int maxSock = 0;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
if (_sockfdMcast)
|
||||
{
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
}
|
||||
if (_sockfdSsl)
|
||||
{
|
||||
FD_SET(_sockfdSsl, &recvfds);
|
||||
}
|
||||
|
||||
if (_sockfdMcast > _sockfdSsl)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdSsl;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_SSL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_castStat = STAT_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int LDtls6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LDtls6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||
{
|
||||
sockaddr_in6 sender;
|
||||
int status = 0;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (_castStat == STAT_SSL)
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
if (SSL_read(_ssl, buf, length) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
D_NWLOG("recved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LDtls6Port::sslConnect(in6_addr ipAddress, in_port_t portNo)
|
||||
{
|
||||
int optval = 1;
|
||||
|
||||
if (_ssl != 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect SSL exists.\n");
|
||||
SSL_shutdown(_ssl);
|
||||
SSL_free(_ssl);
|
||||
_sockfdSsl = 0;
|
||||
_ssl = 0;
|
||||
}
|
||||
|
||||
if (_sockfdSsl > 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect socket exists.\n");
|
||||
::close(_sockfdSsl);
|
||||
}
|
||||
|
||||
_sockfdSsl = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (_sockfdSsl <= 0)
|
||||
{
|
||||
D_NWLOG("LDtls6Port::sslConnect Can't create a socket\n");
|
||||
return -1;
|
||||
}
|
||||
optval = 1;
|
||||
setsockopt(_sockfdSsl, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &optval, sizeof(optval));
|
||||
|
||||
if (_ifIndex > 0)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
setsockopt(_sockfdSsl, IPPROTO_IP, IP_BOUND_IF, &_ifIndex, sizeof(_ifIndex));
|
||||
#else
|
||||
setsockopt(_sockfdSsl, SOL_SOCKET, SO_BINDTODEVICE, _interfaceName.c_str(), _interfaceName.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
sockaddr_in6 addr;
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = _uPortNo;
|
||||
addr.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
::close(_sockfdSsl);
|
||||
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Destination is a gateway address and portNo
|
||||
int rc = 0;
|
||||
sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = portNo;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||
if (connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in6)) < 0)
|
||||
{
|
||||
D_NWLOG("socket can't connect %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest) <0)
|
||||
{
|
||||
D_NWLOG("BIO_ctrl %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
_ssl = SSL_new(_ctx);
|
||||
if (_ssl == nullptr)
|
||||
{
|
||||
D_NWLOG("SSL_new %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
SSL_set_bio(_ssl, cbio, cbio);
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("connect to %-15s:%-6u\n", addrBuf, ntohs(dest.sin6_port));
|
||||
#endif
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||
errno = 0;
|
||||
|
||||
int stat = SSL_connect(_ssl);
|
||||
if (stat != 1)
|
||||
{
|
||||
rc = -1;
|
||||
D_NWLOG("SSL fail to connect %s\n",strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
D_NWLOG("SSL connected\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKDTLS6_H_
|
||||
#define NETWORKDTLS6_H_
|
||||
|
||||
#ifdef DTLS6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_NONE 0
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
#define STAT_SSL 3
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LDtls6Port
|
||||
=======================================*/
|
||||
class LDtls6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LDtls6Port();
|
||||
virtual ~LDtls6Port();
|
||||
|
||||
bool open(LUdp6Config* config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock, in6_addr* ipaddress, in_port_t* port );
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
SSL* getSSL(void);
|
||||
int sslConnect(in6_addr ipAddress, uint16_t port);
|
||||
private:
|
||||
void close();
|
||||
int recvfrom ( uint8_t* buf, uint16_t len, int flags, in6_addr* ipaddress, in_port_t* port );
|
||||
|
||||
int _sockfdMcast;
|
||||
int _sockfdSsl;
|
||||
SSL_CTX *_ctx;
|
||||
SSL *_ssl;
|
||||
in_port_t _gPortNo;
|
||||
in_port_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
uint32_t _ifIndex;
|
||||
string _interfaceName;
|
||||
uint8_t _castStat;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LDtls6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
int sslConnect(void);
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
in_port_t _gwPortNo;
|
||||
in_port_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* DTLS6 */
|
||||
#endif /* NETWORKDTLS6_H_ */
|
||||
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkRfcomm.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern bool theClientMode;
|
||||
extern LRfcommConfig theNetcon;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
_returnCode = 0;
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LRfcommPort::unicast(xmitData, dataLen);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LRfcommPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false);
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_channel = LRfcommPort::_channel;
|
||||
str2ba( theNetcon.gwAddress, (bdaddr_t*)_gwAddress);
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LRfcommConfig* config)
|
||||
{
|
||||
return LRfcommPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*=========================================
|
||||
Class RFCOMM Stack
|
||||
=========================================*/
|
||||
LRfcommPort::LRfcommPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockRfcomm = 0;
|
||||
_channel = 0;
|
||||
}
|
||||
|
||||
LRfcommPort::~LRfcommPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void LRfcommPort::close()
|
||||
{
|
||||
if (_sockRfcomm > 0)
|
||||
{
|
||||
::close(_sockRfcomm);
|
||||
_sockRfcomm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LRfcommPort::open(LRfcommConfig* config)
|
||||
{
|
||||
const int reuse = 1;
|
||||
str2ba(config->gwAddress, (bdaddr_t*)_gwAddress);
|
||||
_channel = config->channel;
|
||||
|
||||
if (_channel == 0 || _gwAddress == 0 )
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockRfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||
if (_sockRfcomm < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockRfcomm, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
|
||||
struct sockaddr_rc addru = { 0 };
|
||||
addru.rc_family = AF_BLUETOOTH;
|
||||
addru.rc_channel = _channel;
|
||||
memcpy(&addru.rc_bdaddr, _gwAddress, 6);
|
||||
|
||||
char bufgw[30];
|
||||
ba2str(&addru.rc_bdaddr, bufgw);
|
||||
DISPLAY("GW MAC = %s RFCOMM CH = %d\n", bufgw, addru.rc_channel);
|
||||
|
||||
// connect to server
|
||||
errno = 0;
|
||||
int status = connect(_sockRfcomm, (struct sockaddr *) &addru, sizeof(addru));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror = %d Can't connect to GW in LRfcommPort::open\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merror = %d Can't connect to GW Ble socket in LRfcommPort::open\033[0m\033[0;37m\n",errno);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int LRfcommPort::unicast(const uint8_t* buf, uint32_t length)
|
||||
{
|
||||
int status = ::write(_sockRfcomm, buf, length);
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
DISPLAY("errno == %d in LRfcommPort::unicast\n", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-2d", _channel);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34msendto %-2dch", _channel);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LRfcommPort::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
if (::recv(_sockRfcomm, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int LRfcommPort::recv(uint8_t* buf, uint16_t length, bool flg)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
int status = ::recv(_sockRfcomm, buf, length, flags);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
D_NWLOG("\nrecved ");
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved ");
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKRFCOMM_H_
|
||||
#define NETWORKRFCOMM_H_
|
||||
|
||||
#ifdef RFCOMM
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient
|
||||
{
|
||||
/*========================================
|
||||
Class LRfcommPort
|
||||
=======================================*/
|
||||
class LRfcommPort
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LRfcommPort();
|
||||
virtual ~LRfcommPort();
|
||||
bool open(LRfcommConfig* config);
|
||||
int unicast(const uint8_t* buf, uint32_t length);
|
||||
int recv(uint8_t* buf, uint16_t len, bool nonblock);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
|
||||
int _sockRfcomm;
|
||||
uint8_t _gwAddress[6];
|
||||
uint8_t _channel;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LRfcommPort
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LRfcommConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* RFCOMM */
|
||||
#endif /* NETWORKRFCOM_H_ */
|
||||
@@ -13,6 +13,7 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
@@ -25,55 +26,66 @@
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t* pos);
|
||||
extern uint32_t getUint32(const uint8_t* pos);
|
||||
extern LScreen* theScreen;
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork(){
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork(){
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
return LUdpPort::multicast(xmitData, (uint32_t)dataLen);
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen){
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* LNetwork::getMessage(int* len){
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf()){
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){
|
||||
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(recvLen < 0){
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}else{
|
||||
if(_rxDataBuf[0] == 0x01){
|
||||
*len = getUint16(_rxDataBuf + 1 );
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
//if(recvLen != *len){
|
||||
@@ -87,111 +99,125 @@ uint8_t* LNetwork::getMessage(int* len){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void){
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
_gwPortNo = _portNo;
|
||||
_gwIpAddress = _ipAddress;
|
||||
}
|
||||
|
||||
void LNetwork::setFixedGwAddress(void){
|
||||
void LNetwork::setFixedGwAddress(void)
|
||||
{
|
||||
_gwPortNo = LUdpPort::_gPortNo;
|
||||
_gwIpAddress = LUdpPort::_gIpAddr;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void){
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
_gwIpAddress = 0;
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
|
||||
bool LNetwork::initialize(LUdpConfig config){
|
||||
bool LNetwork::initialize(LUdpConfig *config)
|
||||
{
|
||||
return LUdpPort::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep(){
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udpStack
|
||||
=========================================*/
|
||||
LUdpPort::LUdpPort(){
|
||||
LUdpPort::LUdpPort()
|
||||
{
|
||||
_disconReq = false;
|
||||
_sockfdUcast = -1;
|
||||
_sockfdMcast = -1;
|
||||
_castStat = 0;
|
||||
}
|
||||
|
||||
LUdpPort::~LUdpPort(){
|
||||
LUdpPort::~LUdpPort()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void LUdpPort::close(){
|
||||
if(_sockfdMcast > 0){
|
||||
::close( _sockfdMcast);
|
||||
void LUdpPort::close()
|
||||
{
|
||||
if (_sockfdMcast > 0)
|
||||
{
|
||||
::close(_sockfdMcast);
|
||||
_sockfdMcast = -1;
|
||||
if(_sockfdUcast > 0){
|
||||
::close( _sockfdUcast);
|
||||
if (_sockfdUcast > 0)
|
||||
{
|
||||
::close(_sockfdUcast);
|
||||
_sockfdUcast = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdpPort::open(LUdpConfig config){
|
||||
const int reuse = 1;
|
||||
char loopch = 1;
|
||||
bool LUdpPort::open(LUdpConfig *config)
|
||||
{
|
||||
int optval = 0;
|
||||
|
||||
uint8_t sav = config.ipAddress[3];
|
||||
config.ipAddress[3] = config.ipAddress[0];
|
||||
config.ipAddress[0] = sav;
|
||||
sav = config.ipAddress[2];
|
||||
config.ipAddress[2] = config.ipAddress[1];
|
||||
config.ipAddress[1] = sav;
|
||||
uint8_t sav = config->ipAddress[3];
|
||||
config->ipAddress[3] = config->ipAddress[0];
|
||||
config->ipAddress[0] = sav;
|
||||
sav = config->ipAddress[2];
|
||||
config->ipAddress[2] = config->ipAddress[1];
|
||||
config->ipAddress[1] = sav;
|
||||
|
||||
_gPortNo = htons(config.gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*)config.ipAddress);
|
||||
_uPortNo = htons(config.uPortNo);
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){
|
||||
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (_sockfdUcast < 0){
|
||||
if (_sockfdUcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdUcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = _uPortNo;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if( ::bind ( _sockfdUcast, (struct sockaddr*)&addr, sizeof(addr)) <0){
|
||||
if (::bind(_sockfdUcast, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (_sockfdMcast < 0){
|
||||
if (_sockfdMcast < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addrm;
|
||||
sockaddr_in addrm;
|
||||
addrm.sin_family = AF_INET;
|
||||
addrm.sin_port = _gPortNo;
|
||||
addrm.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||
optval = 1;
|
||||
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if( ::bind ( _sockfdMcast, (struct sockaddr*)&addrm, sizeof(addrm)) <0){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in UdpPort::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,88 +225,101 @@ bool LUdpPort::open(LUdpConfig config){
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||
|
||||
if( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
||||
DISPLAY("\033[0m\033[0;31m\nerror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
optval= 1;
|
||||
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUdpPort::isUnicast(){
|
||||
return ( _castStat == STAT_UNICAST);
|
||||
bool LUdpPort::isUnicast()
|
||||
{
|
||||
return (_castStat == STAT_UNICAST);
|
||||
}
|
||||
|
||||
|
||||
int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){
|
||||
int LUdpPort::unicast(const uint8_t *buf, uint32_t length, uint32_t ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = port;
|
||||
dest.sin_addr.s_addr = ipAddress;
|
||||
|
||||
int status = ::sendto( _sockfdUcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
if( status < 0){
|
||||
int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
|
||||
DISPLAY("errno == %d in UdpPort::unicast\n", errno);
|
||||
}else{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if ( !theClientMode )
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf,"\033[0;34msendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20 ) // -20 for Escape sequence
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
||||
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = _gPortNo;
|
||||
dest.sin_addr.s_addr = _gIpAddr;
|
||||
|
||||
int status = ::sendto( _sockfdMcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) );
|
||||
if( status < 0){
|
||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||
return errno;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
DISPLAY(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if ( !theClientMode )
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf,"\033[0;34msendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < length ; i++){
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20 )
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +333,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
||||
|
||||
}
|
||||
|
||||
bool LUdpPort::checkRecvBuf(){
|
||||
bool LUdpPort::checkRecvBuf()
|
||||
{
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 50000; // 50 msec
|
||||
@@ -307,21 +347,29 @@ bool LUdpPort::checkRecvBuf(){
|
||||
FD_SET(_sockfdUcast, &recvfds);
|
||||
FD_SET(_sockfdMcast, &recvfds);
|
||||
|
||||
if(_sockfdMcast > _sockfdUcast){
|
||||
if (_sockfdMcast > _sockfdUcast)
|
||||
{
|
||||
maxSock = _sockfdMcast;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
maxSock = _sockfdUcast;
|
||||
}
|
||||
|
||||
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||
|
||||
if(FD_ISSET(_sockfdUcast, &recvfds)){
|
||||
if( ::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
if (FD_ISSET(_sockfdUcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_UNICAST;
|
||||
return true;
|
||||
}
|
||||
}else if(FD_ISSET(_sockfdMcast, &recvfds)){
|
||||
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
||||
}
|
||||
else if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||
{
|
||||
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_castStat = STAT_MULTICAST;
|
||||
return true;
|
||||
}
|
||||
@@ -330,46 +378,58 @@ bool LUdpPort::checkRecvBuf(){
|
||||
return false;
|
||||
}
|
||||
|
||||
int LUdpPort::recv(uint8_t* buf, uint16_t len, bool flg, uint32_t* ipAddressPtr, uint16_t* portPtr){
|
||||
int LUdpPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom (buf, len, flags, ipAddressPtr, portPtr );
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){
|
||||
int LUdpPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
|
||||
if(isUnicast()){
|
||||
status = ::recvfrom( _sockfdUcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen );
|
||||
}else if(_castStat == STAT_MULTICAST){
|
||||
status = ::recvfrom( _sockfdMcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen );
|
||||
}else{
|
||||
if (isUnicast())
|
||||
{
|
||||
D_NWLOG("Ucast ");
|
||||
status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else if (_castStat == STAT_MULTICAST)
|
||||
{
|
||||
D_NWLOG("Mcast ");
|
||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status < 0 && errno != EAGAIN) {
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}else if(status > 0){
|
||||
}
|
||||
else if (status > 0)
|
||||
{
|
||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||
*portPtr = sender.sin_port;
|
||||
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
} D_NWLOG("\n");
|
||||
|
||||
if ( !theClientMode )
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for(uint16_t i = 0; i < status ; i++){
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20 )
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -379,11 +439,13 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef NETWORKUDP_H_
|
||||
#define NETWORKUDP_H_
|
||||
|
||||
#ifdef UDP
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
@@ -27,8 +29,6 @@
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "LMqttsnClientApp.h"
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
LUdpPort();
|
||||
virtual ~LUdpPort();
|
||||
|
||||
bool open(LUdpConfig config);
|
||||
bool open(LUdpConfig* config);
|
||||
|
||||
int unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port );
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
@@ -87,8 +87,9 @@ public:
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
void setFixedGwAddress(void);
|
||||
bool initialize(LUdpConfig config);
|
||||
bool initialize(LUdpConfig* config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
@@ -103,6 +104,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
|
||||
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
#ifdef UDP6
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include "LMqttsnClientApp.h"
|
||||
#include "LNetworkUdp6.h"
|
||||
#include "LTimer.h"
|
||||
#include "LScreen.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace linuxAsyncClient;
|
||||
|
||||
extern uint16_t getUint16(const uint8_t *pos);
|
||||
extern uint32_t getUint32(const uint8_t *pos);
|
||||
extern LScreen *theScreen;
|
||||
extern bool theClientMode;
|
||||
/*=========================================
|
||||
Class LNetwork
|
||||
=========================================*/
|
||||
LNetwork::LNetwork()
|
||||
{
|
||||
_sleepflg = false;
|
||||
resetGwAddress();
|
||||
}
|
||||
|
||||
LNetwork::~LNetwork()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||
}
|
||||
|
||||
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||
{
|
||||
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||
}
|
||||
|
||||
uint8_t* LNetwork::getMessage(int *len)
|
||||
{
|
||||
*len = 0;
|
||||
if (checkRecvBuf())
|
||||
{
|
||||
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recvLen < 0)
|
||||
{
|
||||
*len = recvLen;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rxDataBuf[0] == 0x01)
|
||||
{
|
||||
*len = getUint16(_rxDataBuf + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = _rxDataBuf[0];
|
||||
}
|
||||
return _rxDataBuf;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LNetwork::setGwAddress(void)
|
||||
{
|
||||
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = _portNo;
|
||||
}
|
||||
|
||||
void LNetwork::resetGwAddress(void)
|
||||
{
|
||||
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
|
||||
_gwPortNo = 0;
|
||||
}
|
||||
|
||||
bool LNetwork::initialize(LUdp6Config *config)
|
||||
{
|
||||
return LUdp6Port::open(config);
|
||||
}
|
||||
|
||||
void LNetwork::setSleep()
|
||||
{
|
||||
_sleepflg = true;
|
||||
}
|
||||
|
||||
bool LNetwork::isBroadcastable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*=========================================
|
||||
Class udp6Stack
|
||||
=========================================*/
|
||||
LUdp6Port::LUdp6Port()
|
||||
{
|
||||
_disconReq = false;
|
||||
memset(_pollfds, 0, sizeof(_pollfds));
|
||||
_sock = 0;
|
||||
_interface = NULL;
|
||||
_gIpAddrStr = NULL;
|
||||
}
|
||||
|
||||
LUdp6Port::~LUdp6Port()
|
||||
{
|
||||
close();
|
||||
if (_gIpAddrStr)
|
||||
{
|
||||
free(_gIpAddrStr);
|
||||
}
|
||||
if (_interface)
|
||||
{
|
||||
free(_interface);
|
||||
}
|
||||
}
|
||||
|
||||
void LUdp6Port::close()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].fd > 0)
|
||||
{
|
||||
::close(_pollfds[i].fd);
|
||||
_pollfds[i].fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::open(LUdp6Config *config)
|
||||
{
|
||||
int optval = 1;
|
||||
int sock = 0;
|
||||
uint32_t ifindex = 0;
|
||||
sockaddr_in6 addr6;
|
||||
|
||||
_gPortNo = htons(config->gPortNo);
|
||||
_uPortNo = htons(config->uPortNo);
|
||||
|
||||
if (_gPortNo == 0 || _uPortNo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create a unicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
|
||||
if (strlen(config->interface) > 0)
|
||||
{
|
||||
ifindex = if_nametoindex(config->interface);
|
||||
#ifdef __APPLE__
|
||||
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||
#else
|
||||
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
|
||||
#endif
|
||||
}
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _uPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
_pollfds[0].fd = sock;
|
||||
_pollfds[0].events = POLLIN;
|
||||
|
||||
/* create a multicast socket */
|
||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = _gPortNo;
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
|
||||
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ipv6_mreq addrm;
|
||||
addrm.ipv6mr_interface = ifindex;
|
||||
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
optval = 1;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
_pollfds[1].fd = sock;
|
||||
_pollfds[1].events = POLLIN;
|
||||
_gIpAddr.sin6_family = AF_INET6;
|
||||
_gIpAddr.sin6_port = _gPortNo;
|
||||
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||
_gIpAddrStr = strdup(config->ipAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
|
||||
{
|
||||
struct sockaddr_in6 dest;
|
||||
dest.sin6_family = AF_INET6;
|
||||
dest.sin6_port = port;
|
||||
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
|
||||
|
||||
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
char portStr[8];
|
||||
sprintf(portStr, "%d", ntohs(_gPortNo));
|
||||
|
||||
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||
if (status < 0)
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
|
||||
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
D_NWLOG(" %02x", *(buf + i));
|
||||
}
|
||||
D_NWLOG("\n");
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bool LUdp6Port::checkRecvBuf()
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
int cnt = poll(_pollfds, 2, 50); // Timeout 50m secs
|
||||
if (cnt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_pollfds[i].revents & POLLIN)
|
||||
{
|
||||
if (::recv(_pollfds[i].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||
{
|
||||
_sock = _pollfds[i].fd;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
int LUdp6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
int flags = flg ? MSG_DONTWAIT : 0;
|
||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||
}
|
||||
|
||||
int LUdp6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||
{
|
||||
struct sockaddr_in6 sender;
|
||||
int status;
|
||||
socklen_t addrlen = sizeof(sender);
|
||||
memset(&sender, 0, addrlen);
|
||||
char addrBuf[INET6_ADDRSTRLEN];
|
||||
|
||||
status = ::recvfrom(_sock, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||
|
||||
if (status < 0 && errno != EAGAIN)
|
||||
{
|
||||
D_NWLOG("\033[0m\033[0;31merrno == %d in Udp6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||
}
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||
*portPtr = sender.sin6_port;
|
||||
|
||||
if (!theClientMode)
|
||||
{
|
||||
char sbuf[SCREEN_BUFF_SIZE];
|
||||
int pos = 0;
|
||||
sprintf(sbuf, "\033[0;34mrecv from [%s]:%-6u", addrBuf, htons(*portPtr));
|
||||
pos = strlen(sbuf);
|
||||
for (uint16_t i = 0; i < status; i++)
|
||||
{
|
||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += 3;
|
||||
}
|
||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||
theScreen->display(sbuf);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LUdp6Port::isUnicast(void)
|
||||
{
|
||||
return (_sock == _pollfds[0].fd && _sock > 0);
|
||||
}
|
||||
#endif /* UDP6 */
|
||||
|
||||
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**************************************************************************************
|
||||
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* and the Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#ifndef NETWORKUDP6_H_
|
||||
#define NETWORKUDP6_H_
|
||||
|
||||
#ifdef UDP6
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
#define SOCKET_MAXHOSTNAME 200
|
||||
#define SOCKET_MAXCONNECTIONS 5
|
||||
#define SOCKET_MAXRECV 500
|
||||
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||
|
||||
#define STAT_UNICAST 1
|
||||
#define STAT_MULTICAST 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace linuxAsyncClient {
|
||||
/*========================================
|
||||
Class LUpd6Port
|
||||
=======================================*/
|
||||
class LUdp6Port
|
||||
{
|
||||
friend class LNetwork;
|
||||
public:
|
||||
LUdp6Port();
|
||||
virtual ~LUdp6Port();
|
||||
|
||||
bool open(LUdp6Config *config);
|
||||
|
||||
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
|
||||
int multicast( const uint8_t* buf, uint32_t length );
|
||||
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
|
||||
int recv(uint8_t* buf, int flags);
|
||||
bool checkRecvBuf();
|
||||
bool isUnicast();
|
||||
|
||||
private:
|
||||
void close();
|
||||
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
|
||||
|
||||
pollfd _pollfds[2];
|
||||
uint16_t _gPortNo;
|
||||
uint16_t _uPortNo;
|
||||
sockaddr_in6 _gIpAddr;
|
||||
char *_gIpAddrStr;
|
||||
char* _interface;
|
||||
int _sock;
|
||||
bool _disconReq;
|
||||
|
||||
};
|
||||
|
||||
#define NO_ERROR 0
|
||||
#define PACKET_EXCEEDS_LENGTH 1
|
||||
/*===========================================
|
||||
Class Network
|
||||
============================================*/
|
||||
class LNetwork: public LUdp6Port
|
||||
{
|
||||
public:
|
||||
LNetwork();
|
||||
~LNetwork();
|
||||
|
||||
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||
void setGwAddress(void);
|
||||
void resetGwAddress(void);
|
||||
bool initialize(LUdp6Config *config);
|
||||
uint8_t* getMessage(int* len);
|
||||
bool isBroadcastable();
|
||||
private:
|
||||
void setSleep();
|
||||
int readApiFrame(void);
|
||||
|
||||
in6_addr _gwIpAddress;
|
||||
in6_addr _ipAddress;
|
||||
uint16_t _gwPortNo;
|
||||
uint16_t _portNo;
|
||||
int _returnCode;
|
||||
bool _sleepflg;
|
||||
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||
|
||||
};
|
||||
|
||||
} /* end of namespace */
|
||||
#endif /* UDP6 */
|
||||
#endif /* NETWORKUDP_H_ */
|
||||
@@ -44,6 +44,7 @@ LPublishManager::LPublishManager()
|
||||
_last = 0;
|
||||
_elmCnt = 0;
|
||||
_publishedFlg = SAVE_TASK_INDEX;
|
||||
_autoConnectFlg = false;
|
||||
}
|
||||
|
||||
LPublishManager::~LPublishManager()
|
||||
@@ -115,7 +116,10 @@ void LPublishManager::sendPublish(PubElement* elm)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_autoConnectFlg)
|
||||
{
|
||||
theClient->getGwProxy()->connect();
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
uint8_t org = 0;
|
||||
@@ -310,6 +314,11 @@ void LPublishManager::checkTimeout(void)
|
||||
}
|
||||
}
|
||||
|
||||
void LPublishManager::setAutoConnectMode(bool flg)
|
||||
{
|
||||
_autoConnectFlg = flg;
|
||||
}
|
||||
|
||||
PubElement* LPublishManager::getElement(uint16_t msgId)
|
||||
{
|
||||
PubElement* elm = _first;
|
||||
|
||||
@@ -70,6 +70,7 @@ public:
|
||||
void sendSuspend(const char* topicName, uint16_t topicId, uint8_t topicType);
|
||||
bool isDone(void);
|
||||
bool isMaxFlight(void);
|
||||
void setAutoConnectMode(bool);
|
||||
private:
|
||||
PubElement* getElement(uint16_t msgId);
|
||||
PubElement* getElement(const char* topicName);
|
||||
@@ -84,6 +85,7 @@ private:
|
||||
PubElement* _last;
|
||||
uint8_t _elmCnt;
|
||||
uint8_t _publishedFlg;
|
||||
uint8_t _autoConnectFlg;
|
||||
};
|
||||
|
||||
} /* tomyAsyncClient */
|
||||
|
||||
@@ -67,7 +67,9 @@ void LSubscribeManager::onConnect(void)
|
||||
{
|
||||
if ( theOnPublishList[i].type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
subscribe(theOnPublishList[i].id, theOnPublishList[i].pubCallback, theOnPublishList[i].qos);
|
||||
subscribePredefinedId(theOnPublishList[i].id,
|
||||
theOnPublishList[i].pubCallback,
|
||||
theOnPublishList[i].qos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,6 +124,7 @@ void LSubscribeManager::send(SubElement* elm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
|
||||
if (elm->topicType == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
@@ -169,7 +172,7 @@ void LSubscribeManager::subscribe(const char* topicName, TopicCallback onPublish
|
||||
send(elm);
|
||||
}
|
||||
|
||||
void LSubscribeManager::subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
void LSubscribeManager::subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos)
|
||||
{
|
||||
SubElement* elm = add(MQTTSN_TYPE_SUBSCRIBE, 0, MQTTSN_TOPIC_TYPE_PREDEFINED, topicId, qos, onPublish);
|
||||
send(elm);
|
||||
@@ -262,7 +265,9 @@ void LSubscribeManager::responce(const uint8_t* msg)
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;31m UNSUBACK Invalid messageId. \033[0m\033[0;37m\n\n");
|
||||
DISPLAY(
|
||||
"\033[0m\033[0;31m UNSUBACK Invalid messageId=%04x. \033[0m\033[0;37m\n\n",
|
||||
msgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
~LSubscribeManager();
|
||||
void onConnect(void);
|
||||
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribe(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void subscribePredefinedId(uint16_t topicId, TopicCallback onPublish, uint8_t qos);
|
||||
void unsubscribe(const char* topicName);
|
||||
void unsubscribe(uint16_t topicId);
|
||||
void responce(const uint8_t* msg);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -34,32 +33,37 @@ extern bool theClientMode;
|
||||
/*=====================================
|
||||
TaskManager
|
||||
======================================*/
|
||||
LTaskManager::LTaskManager(void){
|
||||
LTaskManager::LTaskManager(void)
|
||||
{
|
||||
_tasks = 0;
|
||||
_tests = 0;
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
LTaskManager::~LTaskManager(void){
|
||||
LTaskManager::~LTaskManager(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LTaskManager::add(TaskList* task){
|
||||
void LTaskManager::add(TaskList* task)
|
||||
{
|
||||
_tasks = task;
|
||||
}
|
||||
|
||||
void LTaskManager::add(TestList* test){
|
||||
void LTaskManager::add(TestList* test)
|
||||
{
|
||||
_tests = test;
|
||||
}
|
||||
|
||||
void LTaskManager::run(void){
|
||||
void LTaskManager::run(void)
|
||||
{
|
||||
int i = 0;
|
||||
char c = 0;
|
||||
bool cancelFlg = false;
|
||||
TestList test = {0};
|
||||
TaskList task = {0};
|
||||
TestList test = { 0 };
|
||||
TaskList task = { 0 };
|
||||
|
||||
if ( !theClientMode )
|
||||
if (!theClientMode)
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
|
||||
@@ -70,7 +74,7 @@ void LTaskManager::run(void){
|
||||
{
|
||||
if (CHECKKEYIN(&c))
|
||||
{
|
||||
if ( toupper(c) == 'N' )
|
||||
if (toupper(c) == 'N')
|
||||
{
|
||||
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s is canceled ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
@@ -78,7 +82,7 @@ void LTaskManager::run(void){
|
||||
cancelFlg = true;
|
||||
break;
|
||||
}
|
||||
else if ( toupper(c) == 'Y' )
|
||||
else if (toupper(c) == 'Y')
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n\n**** %s start ****\033[0m\033[0;37m\n", _tests[i].testLabel);
|
||||
theScreen->prompt("");
|
||||
@@ -93,22 +97,21 @@ void LTaskManager::run(void){
|
||||
}
|
||||
}
|
||||
|
||||
while ( true )
|
||||
while (true)
|
||||
{
|
||||
do
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !cancelFlg )
|
||||
if (!cancelFlg)
|
||||
{
|
||||
DISPLAY("\033[0m\033[0;32m\n**** %s complete ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
|
||||
}
|
||||
@@ -122,8 +125,7 @@ void LTaskManager::run(void){
|
||||
theClient->getGwProxy()->getMessage();
|
||||
for (_index = 0; _tasks[_index].callback > task.callback; _index++)
|
||||
{
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) &&
|
||||
_tasks[_index].count == 0)
|
||||
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) && _tasks[_index].count == 0)
|
||||
{
|
||||
_tasks[_index].prevTime = time(NULL);
|
||||
(_tasks[_index].callback)();
|
||||
@@ -134,9 +136,8 @@ void LTaskManager::run(void){
|
||||
{
|
||||
theClient->getGwProxy()->getMessage();
|
||||
}
|
||||
while(theClient->getPublishManager()->isMaxFlight() ||
|
||||
!theClient->getSubscribeManager()->isDone() ||
|
||||
!theClient->getRegisterManager()->isDone());
|
||||
while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
|
||||
|| !theClient->getRegisterManager()->isDone());
|
||||
|
||||
if (theClient->getPublishManager()->isDone())
|
||||
{
|
||||
@@ -146,19 +147,21 @@ void LTaskManager::run(void){
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LTaskManager::getIndex(void){
|
||||
uint8_t LTaskManager::getIndex(void)
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
void LTaskManager::done(uint8_t index){
|
||||
if (_tasks )
|
||||
void LTaskManager::done(uint8_t index)
|
||||
{
|
||||
if (_tasks)
|
||||
{
|
||||
if (_tasks[index].count > 0)
|
||||
{
|
||||
_tasks[index].count--;
|
||||
}
|
||||
}
|
||||
if (_tests )
|
||||
if (_tests)
|
||||
{
|
||||
if (_tests[index].count > 0)
|
||||
{
|
||||
@@ -167,12 +170,13 @@ void LTaskManager::done(uint8_t index){
|
||||
}
|
||||
}
|
||||
|
||||
void LTaskManager::suspend(uint8_t index){
|
||||
if ( _tasks )
|
||||
void LTaskManager::suspend(uint8_t index)
|
||||
{
|
||||
if (_tasks)
|
||||
{
|
||||
_tasks[index].count++;
|
||||
}
|
||||
if ( _tests )
|
||||
if (_tests)
|
||||
{
|
||||
_tests[index].count++;
|
||||
}
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
PROGNAME := MQTT-SNGateway
|
||||
APPL := mainGateway
|
||||
|
||||
LPROGNAME := MQTT-SNLogmonitor
|
||||
LAPPL := mainLogmonitor
|
||||
|
||||
TESTPROGNAME := testPFW
|
||||
TESTAPPL := mainTestProcess
|
||||
|
||||
CONFIG := gateway.conf
|
||||
CLIENTS := clients.conf
|
||||
PREDEFTOPIC := predefinedTopic.conf
|
||||
|
||||
SRCDIR := src
|
||||
SUBDIR := ../MQTTSNPacket/src
|
||||
|
||||
OS := linux
|
||||
SENSORNET := udp
|
||||
TEST := tests
|
||||
|
||||
INSTALL_DIR=../../
|
||||
CONFIG_DIR=../../
|
||||
|
||||
CPPSRCS := \
|
||||
$(SRCDIR)/MQTTGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGateway.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWBrokerSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClient.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientRecvTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientSendTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWLogmonitor.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPacketHandleTask.cpp \
|
||||
$(SRCDIR)/MQTTSNGWProcess.cpp \
|
||||
$(SRCDIR)/MQTTSNGWPublishHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWSubscribeHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWEncapsulatedPacket.cpp \
|
||||
$(SRCDIR)/MQTTSNGWForwarder.cpp \
|
||||
$(SRCDIR)/MQTTSNGWQoSm1Proxy.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapter.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregater.cpp \
|
||||
$(SRCDIR)/MQTTSNGWClientList.cpp \
|
||||
$(SRCDIR)/MQTTSNGWTopic.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAdapterManager.cpp \
|
||||
$(SRCDIR)/MQTTSNAggregateConnectionHandler.cpp \
|
||||
$(SRCDIR)/MQTTSNGWMessageIdTable.cpp \
|
||||
$(SRCDIR)/MQTTSNGWAggregateTopicTable.cpp \
|
||||
$(SRCDIR)/$(OS)/$(SENSORNET)/SensorNetwork.cpp \
|
||||
$(SRCDIR)/$(OS)/Timer.cpp \
|
||||
$(SRCDIR)/$(OS)/Network.cpp \
|
||||
$(SRCDIR)/$(OS)/Threading.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestProcess.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestQue.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTree23.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopics.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTopicIdMap.cpp \
|
||||
$(SRCDIR)/$(TEST)/TestTask.cpp
|
||||
|
||||
|
||||
CSRCS := $(SUBDIR)/MQTTSNConnectClient.c \
|
||||
$(SUBDIR)/MQTTSNConnectServer.c \
|
||||
$(SUBDIR)/MQTTSNDeserializePublish.c \
|
||||
$(SUBDIR)/MQTTSNPacket.c \
|
||||
$(SUBDIR)/MQTTSNSearchClient.c \
|
||||
$(SUBDIR)/MQTTSNSearchServer.c \
|
||||
$(SUBDIR)/MQTTSNSerializePublish.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNSubscribeServer.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeClient.c \
|
||||
$(SUBDIR)/MQTTSNUnsubscribeServer.c
|
||||
|
||||
CPPFLAGS +=
|
||||
|
||||
INCLUDE :=
|
||||
INCLUDES += $(INCLUDE) -I$(SRCDIR) \
|
||||
-I$(SRCDIR)/$(OS) \
|
||||
-I$(SRCDIR)/$(OS)/$(SENSORNET) \
|
||||
-I$(SUBDIR) \
|
||||
-I$(SRCDIR)/$(TEST) \
|
||||
-I/usr/local/opt/openssl/include/
|
||||
|
||||
# preprocessor defines
|
||||
DEFS :=
|
||||
|
||||
CXX := g++
|
||||
|
||||
LIB :=
|
||||
LIBS += $(LIB) -L/usr/local/lib -L/usr/local/opt/openssl/lib/
|
||||
|
||||
LDFLAGS :=
|
||||
CXXFLAGS := -Wall -O3 -std=c++11
|
||||
LDADD := -lpthread -lssl -lcrypto
|
||||
OUTDIR := Build
|
||||
|
||||
PROG := $(OUTDIR)/$(PROGNAME)
|
||||
LPROG := $(OUTDIR)/$(LPROGNAME)
|
||||
TPROG := $(OUTDIR)/$(TESTPROGNAME)
|
||||
|
||||
OBJS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.o)
|
||||
OBJS += $(CSRCS:%.c=$(OUTDIR)/%.o)
|
||||
DEPS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.d)
|
||||
DEPS += $(CSRCS:%.c=$(OUTDIR)/%.d)
|
||||
|
||||
.PHONY: install clean exectest
|
||||
|
||||
all: $(PROG) $(LPROG) $(TPROG)
|
||||
|
||||
monitor: $(LPROG)
|
||||
|
||||
test: $(TPROG) $(LPROG) exectest
|
||||
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
$(PROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(APPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(LPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(LAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
$(TPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o
|
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
||||
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(APPL).o:$(SRCDIR)/$(APPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o:$(SRCDIR)/$(TEST)/$(TESTAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SRCDIR)/$(LAPPL).o:$(SRCDIR)/$(LAPPL).cpp
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.c
|
||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTDIR)
|
||||
|
||||
install:
|
||||
cp -pf $(PROG) $(INSTALL_DIR)
|
||||
cp -pf $(LPROG) $(INSTALL_DIR)
|
||||
cp -pf $(CONFIG) $(CONFIG_DIR)
|
||||
cp -pf $(CLIENTS) $(CONFIG_DIR)
|
||||
cp -pf $(PREDEFTOPIC) $(CONFIG_DIR)
|
||||
|
||||
|
||||
exectest:
|
||||
./$(OUTDIR)/$(TESTPROGNAME) -f ./gateway.conf
|
||||
|
||||
|
||||
@@ -1,145 +1,211 @@
|
||||
# MQTT-SN Transparent / Aggregating Gateway
|
||||
|
||||
**MQTT-SN** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
MQTT-SN requires a MQTT-SN Gateway which acts as a protocol converter to convert MQTT-SN messages to MQTT messages.
|
||||
MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
||||
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||
|
||||
### **step1. Build the gateway**
|
||||
````
|
||||
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
||||
### step1. Build the gateway
|
||||
copy and expand source code then,
|
||||
```
|
||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||
$ make [SENSORNET={udp6|xbee|loralink}]
|
||||
$ make install
|
||||
$ make clean
|
||||
````
|
||||
By default, a gateway for UDP is built.
|
||||
In order to create a gateway for UDP6, XBee or LoRaLink, SENSORNET argument is required.
|
||||
```
|
||||
In order to build a gateway, one sensor network argument is required.
|
||||
```
|
||||
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm|dtls|dtls6]
|
||||
```
|
||||
|
||||
MQTT-SNGateway, MQTT-SNLogmonitor and *.conf files are copied into ../ directory.
|
||||
If you want to install the gateway into specific directories, enter a command line as follows:
|
||||
````
|
||||
$ make install INSTALL_DIR=/path/to/your_directory CONFIG_DIR=/path/to/your_directory
|
||||
````
|
||||
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
|
||||
|
||||
### step2. Execute the Gateway.
|
||||
|
||||
### **step2. Execute the Gateway.**
|
||||
|
||||
````
|
||||
$ cd ../../
|
||||
$ ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNGateway
|
||||
```
|
||||
If you get the error message as follows:
|
||||
````
|
||||
what(): RingBuffer can't create a shared memory.
|
||||
Aborted (core dumped)
|
||||
````
|
||||
|
||||
RingBuffer can't create a shared memory. ABORT Gateway!!!
|
||||
You have to start using sudo command only once for the first time.
|
||||
````
|
||||
$ sudo ./MQTT-SNGateway [-f Config file name]
|
||||
````
|
||||
|
||||
### **How to Change the configuration of the gateway**
|
||||
**../gateway.conf** Contents are follows:
|
||||
|
||||
<pre><dev>
|
||||
```
|
||||
$ sudo ./MQTT-SNGateway
|
||||
```
|
||||
## Contents of the gateway configuration file
|
||||
**gateway.conf** is in bin directory. It's contents are follows:
|
||||
|
||||
```
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#***************************************************************************
|
||||
#
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
```
|
||||
**GatewayID** is a gateway ID which used by GWINFO message.
|
||||
**GatewayName** is a name of the gateway.
|
||||
**MaxNumberOfClients** is a maxmum number of clients. Clients are dynamically allocated.
|
||||
**KeepAlive** is KeepAlive time in seconds.
|
||||
**LoginID** is used by CONNECT message.
|
||||
**Password** is used by CONNECT message.
|
||||
**BrokerName**is a domain name or IP address of a broker.
|
||||
**BrokerPortNo** is a broker's port no.
|
||||
**BrokerSecurePortNo** is a broker's port no of TLS connection.
|
||||
```
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
```
|
||||
**RootCAfile** is a CA file name.
|
||||
**RootCApath** is a CA path. **SSL_CTX_load_verify_locations(ctx, CAfile, CApath)** function requires these parameters.
|
||||
**CertsKey** is a certificate pem file.
|
||||
**PrivateKey** is a private key pem file.
|
||||
Clients can connect to the broker via TLS by setting '**Secure Connection**' for each client in the client conf file.
|
||||
```
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
```
|
||||
The gateway runs as a aggregating gateway when **AggregatingGateway** is 'YES'.
|
||||
If **QoS-1** is 'YES, the gateway prepares a proxy for the QoS-1 client. QoS-1 client has a 'QoS-1' parameter in a clients.conf file. For QoS-1 clients, set the QoS-1 parameters in the clients.conf file.
|
||||
If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
|
||||
If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
|
||||
**ClientsList** defines clients and those address so on.
|
||||
**PredefinedTopicList** file defines Predefined Topic.
|
||||
|
||||
|
||||
# UDP
|
||||
```
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
```
|
||||
**GatewayPortNo** is a unicast port no of the gateway.
|
||||
**MulticastIP** and **MulticastPortNo** are for GWSEARCH messages. Clients can get the gateway address (Gateway IP address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
Client needs to know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**MulticastTTL** is a multicast TTL.
|
||||
```
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::feed:caca:dead
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
```
|
||||
**GatewayIPv6PortNo** is a unicast port no of the gateway.
|
||||
**MulticastIPv6PortNo** and **MulticastIPv6** are for GWSEARCH messages. Set the Global scope Multicast address so that the Global address is used for sending GWINFO.
|
||||
Clients can get the gateway address (Gateway IPv6 address and GatewayPortNo) from GWINFO message by means of std::recvfrom().
|
||||
**MulticastIPv6If** is a multicast interface name.
|
||||
**MulticastHops** is a multicast hops.
|
||||
```
|
||||
#
|
||||
# DTLS | DTLS6 DTLS CertsKey
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
```
|
||||
**DtlsCertsKey** is a certs Key pem file for DTLS connection.
|
||||
**DtlsPrivKey** is a private key pem file for DTLS connection.
|
||||
```
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
```
|
||||
**Baudrate** is a baudrate of xbee.
|
||||
```
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
#LoRaLink
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx
|
||||
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
```
|
||||
https://github.com/ty4tw/MQTT-SN-LoRa
|
||||
|
||||
```
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
```
|
||||
**RFCOMMAddress** is a bluetooth mac address and channel. channel should be * for the gateway.
|
||||
```
|
||||
#
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
|
||||
</dev></pre>
|
||||
ShearedMemory=NO
|
||||
```
|
||||
|
||||
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. **BrokerSecurePortNo** is for TLS connection.
|
||||
**MulticastIP** and **MulticastPortNo** is a multicast address for GWSEARCH messages. Gateway is waiting GWSEARCH and when receiving it send GWINFO message via MulticastIP address. Clients can get the gateway address (Gateway IP address and **GatewayPortNo**) from GWINFO message by means of std::recvfrom().
|
||||
Client should know the MulticastIP and MulticastPortNo to send a SEARCHGW message.
|
||||
**GatewayId** is used by GWINFO message.
|
||||
**KeepAlive** is a duration of ADVERTISE message in seconds.
|
||||
when **AggregatingGateway** or **ClientAuthentication** is **YES**, All clients which connect to the gateway must be declared by a **ClientsList** file.
|
||||
Format of the file is ClientId and SensorNetwork Address. e.g. IP address and Port No etc, in CSV. more detail see clients.conf.
|
||||
When **QoS-1** is **YES**, QoS-1 PUBLISH is available. All clients which send QoS-1 PUBLISH must be specified by Client.conf file.
|
||||
When **PredefinedTopic** is **YES**, **Pre-definedTopicId**s specified by **PredefinedTopicList** are effective. This file defines Pre-definedTopics of the clients. In this file, ClientID,TopicName and TopicID are declared in CSV format.
|
||||
When **Forwarder** is **YES**, Forwarder Encapsulation Message is available. Connectable Forwarders must be declared by a **ClientsList** file.
|
||||
|
||||
### ** How to monitor the gateway from remote. **
|
||||
### How to monitor the gateway from a remote terminal.
|
||||
Change gateway.conf as follows:
|
||||
```
|
||||
# LOG
|
||||
ShearedMemory=YES;
|
||||
````
|
||||
|
||||
```
|
||||
Restart the gateway with sudo only once to create shared memories.
|
||||
|
||||
open ssh terminal and execute LogMonitor.
|
||||
|
||||
`$ ./MQTT-SNLogmonitor`
|
||||
|
||||
```
|
||||
$ cd bin
|
||||
$ ./MQTT-SNLogmonitor
|
||||
```
|
||||
Now you can get the Log on your terminal.
|
||||
|
||||
|
||||
## ** Tips **
|
||||
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs.
|
||||
##### Tips
|
||||
Use compiler definitions then you can get more precise logs.
|
||||
**-DDEBUG_NW** is a flag for debug logs of Sensor network.
|
||||
**-DDEBUG_MQTTSN** is a flag for debug logs of MQTT-SN message haandling.
|
||||
One or both flags can be specified.
|
||||
|
||||
```
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
./build.sh udp -DDEBUG -DDEBUG_NW
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
42
MQTTSNGateway/build.sh
Executable file
42
MQTTSNGateway/build.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
build () {
|
||||
echo "Start building MQTT-SN Gateway $1"
|
||||
|
||||
cd $SCRIPT_DIR/..
|
||||
BDIR='build.gateway'
|
||||
if [ ! -d ./$BDIR ]; then
|
||||
mkdir $BDIR
|
||||
fi
|
||||
cd $BDIR
|
||||
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
|
||||
make MQTTSNPacket
|
||||
make MQTT-SNGateway
|
||||
make MQTT-SNLogmonitor
|
||||
cd ../MQTTSNGateway
|
||||
cp *.conf ./bin/
|
||||
}
|
||||
|
||||
SCRIPT_DIR=$(cd $(dirname $0); pwd)
|
||||
|
||||
if [ $1 == "udp" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "udp6" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "xbee" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "loralink" ]; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "rfcomm" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls" ] ; then
|
||||
build $1 $2 $3
|
||||
elif [ $1 == "dtls6" ] ; then
|
||||
build dtls "${2} ${3} -DDTLS6"
|
||||
elif [ $1 == "clean" ] ; then
|
||||
rm -rf ../builg.gateway
|
||||
else
|
||||
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm | dtls | dtls6 | clean]"
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
# Lines bigning with # are comment line.
|
||||
# ClientId, SensorNetAddress, "unstableLine", "secureConnection"
|
||||
# in case of UDP, SensorNetAddress format is IPAddress: port no.
|
||||
# if the SensorNetwork is not stable, write "unstableLine".
|
||||
# if Broker's Connection is SSL, write "secureConnection".
|
||||
# if the client is a forwarder, "forwarder" is required.
|
||||
# if the client send PUBLISH QoS-1, "QoS-1" is required.
|
||||
# if the SensorNetwork is not stable, specify "unstableLine".
|
||||
# if Broker's Connection is TLS, specify "secureConnection".
|
||||
# if the client is a forwarder,specify "forwarder".
|
||||
# if the client send PUBLISH QoS-1, specify "QoS-1".
|
||||
#
|
||||
# Ex:
|
||||
# #Client List
|
||||
@@ -31,6 +31,17 @@
|
||||
#
|
||||
# SensorNetwork address format is defined by SensorNetAddress::setAddress(string* data) function.
|
||||
#
|
||||
# UDP6 (IPv6 UDP) [IPv6 address]:PortNo
|
||||
# RFCOMM Device_address.channel (1-30)
|
||||
# XBee FFFFFFFFFFFFFFFF 8bytes Hex
|
||||
# LoRaLink 1-254
|
||||
#
|
||||
#
|
||||
# This is a sample of UDP.
|
||||
#
|
||||
# REWRITE ALL ACCORDING TO YOUR CLIENTS.
|
||||
#
|
||||
|
||||
GatewayTester, 172.16.1.11:20020
|
||||
ClientPUB,172.16.1.11:2010
|
||||
Client01,172.16.1.11:12001
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#**************************************************************************
|
||||
# Copyright (c) 2016-2019, Tomoaki Yamaguchi
|
||||
# Copyright (c) 2016-2021, Tomoaki Yamaguchi
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
@@ -14,55 +14,95 @@
|
||||
# config file of MQTT-SN Gateway
|
||||
#
|
||||
|
||||
BrokerName=mqtt.eclipse.org
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
MaxNumberOfClients=30
|
||||
KeepAlive=60
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
BrokerName=mqtt.eclipseprojects.io
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
#
|
||||
# CertsKey for TLS connections to a broker
|
||||
#
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsKey=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
#
|
||||
# When AggregatingGateway=YES or ClientAuthentication=YES,
|
||||
# All clients must be specified by the ClientList File
|
||||
#
|
||||
|
||||
ClientAuthentication=NO
|
||||
AggregatingGateway=NO
|
||||
QoS-1=NO
|
||||
Forwarder=NO
|
||||
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
PredefinedTopic=NO
|
||||
#PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
ClientAuthentication=NO
|
||||
|
||||
#RootCAfile=/etc/ssl/certs/ca-certificates.crt
|
||||
#RootCApath=/etc/ssl/certs/
|
||||
#CertsFile=/path/to/certKey.pem
|
||||
#PrivateKey=/path/to/privateKey.pem
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
ClientsList=/path/to/your_clients.conf
|
||||
PredefinedTopicList=/path/to/your_predefinedTopic.conf
|
||||
|
||||
|
||||
# UDP
|
||||
#==============================
|
||||
# SensorNetworks parameters
|
||||
#==============================
|
||||
#
|
||||
# UDP | DTLS
|
||||
#
|
||||
|
||||
GatewayPortNo=10000
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastPortNo=1883
|
||||
MulticastIP=225.1.1.1
|
||||
MulticastTTL=1
|
||||
|
||||
# UDP6
|
||||
GatewayUDP6Bind=FFFF:FFFE::1
|
||||
GatewayUDP6Port=10000
|
||||
GatewayUDP6Broadcast=FF02::1
|
||||
GatewayUDP6If=wpan0
|
||||
GatewayUDP6Hops=1
|
||||
#
|
||||
# UDP6 | DTLS6
|
||||
#
|
||||
|
||||
GatewayIPv6PortNo=10000
|
||||
MulticastIPv6PortNo=1883
|
||||
MulticastIPv6=ff1e:feed:caca:dead::1
|
||||
MulticastIPv6If=wlp4s0
|
||||
MulticastHops=1
|
||||
|
||||
#
|
||||
# DTLS | DTLS6
|
||||
#
|
||||
|
||||
DtlsCertsKey=/etc/ssl/certs/gateway.pem
|
||||
DtlsPrivKey=/etc/ssl/private/privkey.pem
|
||||
|
||||
#
|
||||
# XBee
|
||||
#
|
||||
|
||||
Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
ApiMode=2
|
||||
|
||||
# LOG
|
||||
ShearedMemory=NO;
|
||||
#
|
||||
# LoRaLink
|
||||
#
|
||||
|
||||
BaudrateLoRaLink=115200
|
||||
DeviceRxLoRaLink=/dev/loralinkRx
|
||||
DeviceTxLoRaLink=/dev/loralinkTx
|
||||
|
||||
#
|
||||
# Bluetooth RFCOMM
|
||||
#
|
||||
|
||||
RFCOMMAddress=60:57:18:06:8B:72.*
|
||||
|
||||
#
|
||||
# LOG
|
||||
#
|
||||
|
||||
ShearedMemory=NO
|
||||
|
||||
|
||||
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
@@ -0,0 +1,151 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2022 a1lu
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
#
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# and the Eclipse Distribution License is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# Contributors:
|
||||
# a1lu - initial version
|
||||
# ty4tw - modify
|
||||
#*******************************************************************************/
|
||||
PROJECT(mqtt-sn-gateway CXX)
|
||||
|
||||
SET(GW_VERSION_MAJOR 1)
|
||||
SET(GW_VERSION_MINOR 5)
|
||||
SET(GW_VERSION_PATCH 1)
|
||||
|
||||
SET(GATEWAY_VERSION ${GW_VERSION_MAJOR}.${GW_VERSION_MINOR}.${GW_VERSION_PATCH})
|
||||
MESSAGE(STATUS "VERSION : ${GATEWAY_VERSION}")
|
||||
|
||||
configure_file( MQTTSNGWVersion.h.in ${CMAKE_CURRENT_SOURCE_DIR}/MQTTSNGWVersion.h )
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../bin)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
SET(OS linux)
|
||||
|
||||
IF(NOT DEFINED SENSORNET)
|
||||
SET(SENSORNET udp)
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
|
||||
|
||||
ADD_DEFINITIONS(${DEFS})
|
||||
MESSAGE(STATUS "Definitions: " ${DEFS})
|
||||
|
||||
ADD_LIBRARY(mqtt-sngateway_common
|
||||
MQTTGWConnectionHandler.cpp
|
||||
MQTTGWPacket.cpp
|
||||
MQTTGWPublishHandler.cpp
|
||||
MQTTGWSubscribeHandler.cpp
|
||||
MQTTSNGateway.cpp
|
||||
MQTTSNGWBrokerRecvTask.cpp
|
||||
MQTTSNGWBrokerSendTask.cpp
|
||||
MQTTSNGWClient.cpp
|
||||
MQTTSNGWClientRecvTask.cpp
|
||||
MQTTSNGWClientSendTask.cpp
|
||||
MQTTSNGWConnectionHandler.cpp
|
||||
MQTTSNGWLogmonitor.cpp
|
||||
MQTTSNGWPacket.cpp
|
||||
MQTTSNGWPacketHandleTask.cpp
|
||||
MQTTSNGWProcess.cpp
|
||||
MQTTSNGWPublishHandler.cpp
|
||||
MQTTSNGWSubscribeHandler.cpp
|
||||
MQTTSNGWEncapsulatedPacket.cpp
|
||||
MQTTSNGWForwarder.cpp
|
||||
MQTTSNGWQoSm1Proxy.cpp
|
||||
MQTTSNGWAdapter.cpp
|
||||
MQTTSNGWAggregater.cpp
|
||||
MQTTSNGWClientList.cpp
|
||||
MQTTSNGWTopic.cpp
|
||||
MQTTSNGWAdapterManager.cpp
|
||||
MQTTSNAggregateConnectionHandler.cpp
|
||||
MQTTSNGWMessageIdTable.cpp
|
||||
MQTTSNGWAggregateTopicTable.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.cpp
|
||||
${OS}/${SENSORNET}/SensorNetwork.h
|
||||
${OS}/Timer.cpp
|
||||
${OS}/Timer.h
|
||||
${OS}/Network.cpp
|
||||
${OS}/Network.h
|
||||
${OS}/Threading.cpp
|
||||
${OS}/Threading.h
|
||||
)
|
||||
|
||||
# linux
|
||||
link_directories("/usr/local/lib")
|
||||
|
||||
# Mac
|
||||
link_directories("/usr/local/opt/openssl/lib")
|
||||
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
|
||||
PUBLIC
|
||||
.
|
||||
${OS}
|
||||
${OS}/${SENSORNET}
|
||||
../../MQTTSNPacket/src
|
||||
/usr/local/include
|
||||
/usr/local/opt/openssl/include
|
||||
)
|
||||
|
||||
IF(SENSORNET MATCHES "rfcomm")
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
bluetooth
|
||||
)
|
||||
ELSE()
|
||||
|
||||
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||
PRIVATE
|
||||
MQTTSNPacket
|
||||
pthread
|
||||
ssl
|
||||
crypto
|
||||
)
|
||||
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNGateway
|
||||
mainGateway.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNGateway
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(MQTT-SNLogmonitor
|
||||
mainLogmonitor.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(MQTT-SNLogmonitor
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(testPFW
|
||||
tests/mainTestProcess.cpp
|
||||
tests/TestProcess.cpp
|
||||
tests/TestQue.cpp
|
||||
tests/TestTree23.cpp
|
||||
tests/TestTopics.cpp
|
||||
tests/TestTopicIdMap.cpp
|
||||
tests/TestTask.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(testPFW
|
||||
mqtt-sngateway_common
|
||||
)
|
||||
|
||||
|
||||
ADD_TEST(NAME testPFW
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/..
|
||||
COMMAND testPFW -f ./gateway.conf)
|
||||
@@ -49,8 +49,7 @@ void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet
|
||||
else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
|
||||
{
|
||||
rc = MQTTSN_RC_NOT_SUPPORTED;
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n",
|
||||
client->getClientId());
|
||||
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", client->getClientId());
|
||||
}
|
||||
else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
|
||||
{
|
||||
|
||||
@@ -28,9 +28,8 @@ void writeInt(unsigned char** pptr, int msgId);
|
||||
/**
|
||||
* List of the predefined MQTT v3 packet names.
|
||||
*/
|
||||
static const char* mqtt_packet_names[] =
|
||||
{ "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP", "SUBSCRIBE", "SUBACK",
|
||||
"UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
static const char* mqtt_packet_names[] = { "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
|
||||
"SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
|
||||
|
||||
/**
|
||||
* Encodes the message length according to the MQTT algorithm
|
||||
@@ -49,7 +48,8 @@ int MQTTPacket_encode(char* buf, int length)
|
||||
if (length > 0)
|
||||
d |= 0x80;
|
||||
buf[rc++] = d;
|
||||
} while (length > 0);
|
||||
}
|
||||
while (length > 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ char* readUTFlen(char** pptr, char* enddata, int* len)
|
||||
*len = readInt(pptr);
|
||||
if (&(*pptr)[*len] <= enddata)
|
||||
{
|
||||
string = (char*)calloc(*len + 1, 1);
|
||||
memcpy(string, *pptr, (size_t)*len);
|
||||
string = (char*) calloc(*len + 1, 1);
|
||||
memcpy(string, *pptr, (size_t) *len);
|
||||
string[*len] = '\0';
|
||||
*pptr += *len;
|
||||
}
|
||||
@@ -142,9 +142,9 @@ void writeChar(unsigned char** pptr, char c)
|
||||
*/
|
||||
void writeInt(unsigned char** pptr, int anInt)
|
||||
{
|
||||
**pptr = (unsigned char)(anInt / 256);
|
||||
**pptr = (unsigned char) (anInt / 256);
|
||||
(*pptr)++;
|
||||
**pptr = (unsigned char)(anInt % 256);
|
||||
**pptr = (unsigned char) (anInt % 256);
|
||||
(*pptr)++;
|
||||
}
|
||||
|
||||
@@ -155,9 +155,9 @@ void writeInt(unsigned char** pptr, int anInt)
|
||||
*/
|
||||
void writeUTF(unsigned char** pptr, const char* string)
|
||||
{
|
||||
int len = (int)strlen(string);
|
||||
int len = (int) strlen(string);
|
||||
writeInt(pptr, len);
|
||||
memcpy(*pptr, string, (size_t)len);
|
||||
memcpy(*pptr, string, (size_t) len);
|
||||
*pptr += len;
|
||||
}
|
||||
|
||||
@@ -187,8 +187,8 @@ int MQTTGWPacket::recv(Network* network)
|
||||
unsigned char c;
|
||||
|
||||
/* read First Byte of Packet */
|
||||
int rc = network->recv((unsigned char*)&_header.byte, 1);
|
||||
if ( rc <= 0)
|
||||
int rc = network->recv((unsigned char*) &_header.byte, 1);
|
||||
if (rc <= 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
@@ -205,13 +205,14 @@ int MQTTGWPacket::recv(Network* network)
|
||||
}
|
||||
_remainingLength += (c & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((c & 128) != 0);
|
||||
}
|
||||
while ((c & 128) != 0);
|
||||
|
||||
if ( _remainingLength > 0 )
|
||||
if (_remainingLength > 0)
|
||||
{
|
||||
/* allocate buffer */
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
if ( !_data )
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (!_data)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
@@ -219,11 +220,11 @@ int MQTTGWPacket::recv(Network* network)
|
||||
/* read Payload */
|
||||
int remlen = network->recv(_data, _remainingLength);
|
||||
|
||||
if (remlen == -1 )
|
||||
if (remlen == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if ( remlen != _remainingLength )
|
||||
else if (remlen != _remainingLength)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
@@ -308,21 +309,21 @@ int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, unsigned
|
||||
clearData();
|
||||
_header = connect->header;
|
||||
|
||||
_remainingLength = ((connect->version == 3) ? 12 : 10) + (int)strlen(connect->clientID) + 2;
|
||||
_remainingLength = ((connect->version == 3) ? 12 : 10) + (int) strlen(connect->clientID) + 2;
|
||||
if (connect->flags.bits.will)
|
||||
{
|
||||
_remainingLength += (int)strlen(connect->willTopic) + 2 + (int)strlen(connect->willMsg) + 2;
|
||||
_remainingLength += (int) strlen(connect->willTopic) + 2 + (int) strlen(connect->willMsg) + 2;
|
||||
}
|
||||
if ( connect->flags.bits.username )
|
||||
if (connect->flags.bits.username)
|
||||
{
|
||||
_remainingLength += (int)strlen((char*) username) + 2;
|
||||
_remainingLength += (int) strlen((char*) username) + 2;
|
||||
}
|
||||
if (connect->flags.bits.password)
|
||||
{
|
||||
_remainingLength += (int)strlen((char*) password) + 2;
|
||||
_remainingLength += (int) strlen((char*) password) + 2;
|
||||
}
|
||||
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
unsigned char* ptr = _data;
|
||||
|
||||
if (connect->version == 3)
|
||||
@@ -366,8 +367,8 @@ int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, unsigned sh
|
||||
_header.byte = 0;
|
||||
_header.bits.type = SUBSCRIBE;
|
||||
_header.bits.qos = 1; // Reserved
|
||||
_remainingLength = (int)strlen(topic) + 5;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_remainingLength = (int) strlen(topic) + 5;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
@@ -386,8 +387,8 @@ int MQTTGWPacket::setUNSUBSCRIBE(const char* topic, unsigned short msgid)
|
||||
_header.byte = 0;
|
||||
_header.bits.type = UNSUBSCRIBE;
|
||||
_header.bits.qos = 1;
|
||||
_remainingLength = (int)strlen(topic) + 4;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_remainingLength = (int) strlen(topic) + 4;
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
@@ -406,14 +407,14 @@ int MQTTGWPacket::setPUBLISH(Publish* pub)
|
||||
_header.byte = pub->header.byte;
|
||||
_header.bits.type = PUBLISH;
|
||||
_remainingLength = 4 + pub->topiclen + pub->payloadlen;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* ptr = _data;
|
||||
writeInt(&ptr, pub->topiclen);
|
||||
memcpy(ptr, pub->topic, pub->topiclen);
|
||||
ptr += pub->topiclen;
|
||||
if ( _header.bits.qos > 0 )
|
||||
if (_header.bits.qos > 0)
|
||||
{
|
||||
writeInt(&ptr, pub->msgId);
|
||||
}
|
||||
@@ -438,7 +439,7 @@ int MQTTGWPacket::setAck(unsigned char msgType, unsigned short msgid)
|
||||
_header.bits.type = msgType;
|
||||
_header.bits.qos = (msgType == PUBREL) ? 1 : 0;
|
||||
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
unsigned char* data = _data;
|
||||
@@ -473,7 +474,7 @@ int MQTTGWPacket::getPacketData(unsigned char* buf)
|
||||
{
|
||||
unsigned char* ptr = buf;
|
||||
*ptr++ = _header.byte;
|
||||
int len = MQTTPacket_encode((char*)ptr, _remainingLength);
|
||||
int len = MQTTPacket_encode((char*) ptr, _remainingLength);
|
||||
ptr += len;
|
||||
memcpy(ptr, _data, _remainingLength);
|
||||
return 1 + len + _remainingLength;
|
||||
@@ -499,13 +500,13 @@ char* MQTTGWPacket::getMsgId(char* pbuf)
|
||||
{
|
||||
int type = getType();
|
||||
|
||||
switch ( type )
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
pub.msgId = 0;
|
||||
getPUBLISH(&pub);
|
||||
if ( _header.bits.dup )
|
||||
if (_header.bits.dup)
|
||||
{
|
||||
sprintf(pbuf, "+%04X", pub.msgId);
|
||||
}
|
||||
@@ -528,7 +529,7 @@ char* MQTTGWPacket::getMsgId(char* pbuf)
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if ( strcmp(pbuf, " 0000") == 0 )
|
||||
if (strcmp(pbuf, " 0000") == 0)
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
@@ -540,7 +541,7 @@ int MQTTGWPacket::getMsgId(void)
|
||||
int type = getType();
|
||||
int msgId = 0;
|
||||
|
||||
switch ( type )
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
@@ -556,7 +557,7 @@ int MQTTGWPacket::getMsgId(void)
|
||||
case UNSUBSCRIBE:
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
msgId = 256 * (unsigned char)_data[0] + (unsigned char)_data[1];
|
||||
msgId = 256 * (unsigned char) _data[0] + (unsigned char) _data[1];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -569,7 +570,7 @@ void MQTTGWPacket::setMsgId(int msgId)
|
||||
int type = getType();
|
||||
unsigned char* ptr = 0;
|
||||
|
||||
switch ( type )
|
||||
switch (type)
|
||||
{
|
||||
case PUBLISH:
|
||||
Publish pub;
|
||||
@@ -579,8 +580,8 @@ void MQTTGWPacket::setMsgId(int msgId)
|
||||
pub.msgId = msgId;
|
||||
ptr = _data + pub.topiclen;
|
||||
writeInt(&ptr, pub.msgId);
|
||||
*ptr++ = (unsigned char)(msgId / 256);
|
||||
*ptr = (unsigned char)(msgId % 256);
|
||||
*ptr++ = (unsigned char) (msgId / 256);
|
||||
*ptr = (unsigned char) (msgId % 256);
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
@@ -591,8 +592,8 @@ void MQTTGWPacket::setMsgId(int msgId)
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
ptr = _data;
|
||||
*ptr++ = (unsigned char)(msgId / 256);
|
||||
*ptr = (unsigned char)(msgId % 256);
|
||||
*ptr++ = (unsigned char) (msgId / 256);
|
||||
*ptr = (unsigned char) (msgId % 256);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -620,7 +621,7 @@ MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet)
|
||||
clearData();
|
||||
this->_header.byte = packet._header.byte;
|
||||
this->_remainingLength = packet._remainingLength;
|
||||
_data = (unsigned char*)calloc(_remainingLength, 1);
|
||||
_data = (unsigned char*) calloc(_remainingLength, 1);
|
||||
if (_data)
|
||||
{
|
||||
memcpy(this->_data, packet._data, _remainingLength);
|
||||
@@ -634,12 +635,12 @@ MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet)
|
||||
|
||||
UTF8String MQTTGWPacket::getTopic(void)
|
||||
{
|
||||
UTF8String str = {0, nullptr};
|
||||
if ( _header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE )
|
||||
UTF8String str = { 0, nullptr };
|
||||
if (_header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE)
|
||||
{
|
||||
char* ptr = (char*)(_data + 2);
|
||||
char* ptr = (char*) (_data + 2);
|
||||
str.len = readInt(&ptr);
|
||||
str.data = (char*)(_data + 4);
|
||||
str.data = (char*) (_data + 4);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -31,18 +31,29 @@ typedef void* (*pf)(unsigned char, char*, size_t);
|
||||
|
||||
enum msgTypes
|
||||
{
|
||||
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
|
||||
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
|
||||
PINGREQ, PINGRESP, DISCONNECT
|
||||
CONNECT = 1,
|
||||
CONNACK,
|
||||
PUBLISH,
|
||||
PUBACK,
|
||||
PUBREC,
|
||||
PUBREL,
|
||||
PUBCOMP,
|
||||
SUBSCRIBE,
|
||||
SUBACK,
|
||||
UNSUBSCRIBE,
|
||||
UNSUBACK,
|
||||
PINGREQ,
|
||||
PINGRESP,
|
||||
DISCONNECT
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bitfields for the MQTT header byte.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/*unsigned*/ char byte; /**< the whole byte */
|
||||
/*unsigned*/
|
||||
char byte; /**< the whole byte */
|
||||
#if defined(REVERSED)
|
||||
struct
|
||||
{
|
||||
@@ -50,25 +61,25 @@ typedef union
|
||||
bool dup : 1; /**< DUP flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
bool retain : 1; /**< retained flag bit */
|
||||
} bits;
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
bool retain : 1; /**< retained flag bit */
|
||||
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
|
||||
bool dup : 1; /**< DUP flag bit */
|
||||
unsigned int type : 4; /**< message type nibble */
|
||||
bool retain :1; /**< retained flag bit */
|
||||
unsigned int qos :2; /**< QoS value, 0, 1 or 2 */
|
||||
bool dup :1; /**< DUP flag bit */
|
||||
unsigned int type :4; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} Header;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a connect packet.
|
||||
*/
|
||||
|
||||
enum MQTT_connackCodes{
|
||||
MQTT_CONNECTION_ACCEPTED ,
|
||||
enum MQTT_connackCodes
|
||||
{
|
||||
MQTT_CONNECTION_ACCEPTED,
|
||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
||||
MQTT_IDENTIFIER_REJECTED,
|
||||
MQTT_SERVER_UNAVAILABLE,
|
||||
@@ -92,17 +103,17 @@ typedef struct
|
||||
bool will : 1; /**< will flag */
|
||||
bool cleanstart : 1; /**< cleansession flag */
|
||||
int : 1; /**< unused */
|
||||
} bits;
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
int : 1; /**< unused */
|
||||
bool cleanstart : 1; /**< cleansession flag */
|
||||
bool will : 1; /**< will flag */
|
||||
unsigned int willQoS : 2; /**< will QoS value */
|
||||
bool willRetain : 1; /**< will retain setting */
|
||||
bool password : 1; /**< 3.1 password */
|
||||
bool username : 1; /**< 3.1 user name */
|
||||
int :1; /**< unused */
|
||||
bool cleanstart :1; /**< cleansession flag */
|
||||
bool will :1; /**< will flag */
|
||||
unsigned int willQoS :2; /**< will QoS value */
|
||||
bool willRetain :1; /**< will retain setting */
|
||||
bool password :1; /**< 3.1 password */
|
||||
bool username :1; /**< 3.1 user name */
|
||||
} bits;
|
||||
#endif
|
||||
} flags; /**< connect flags byte */
|
||||
@@ -121,8 +132,6 @@ typedef struct
|
||||
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
|
||||
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data for a willMessage.
|
||||
*/
|
||||
@@ -132,7 +141,7 @@ typedef struct
|
||||
char* msg;
|
||||
int retained;
|
||||
int qos;
|
||||
}willMessages;
|
||||
} willMessages;
|
||||
|
||||
/**
|
||||
* Data for a connack packet.
|
||||
@@ -148,19 +157,18 @@ typedef struct
|
||||
{
|
||||
unsigned int reserved : 7; /**< message type nibble */
|
||||
bool sessionPresent : 1; /**< was a session found on the server? */
|
||||
} bits;
|
||||
}bits;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
bool sessionPresent : 1; /**< was a session found on the server? */
|
||||
unsigned int reserved : 7; /**< message type nibble */
|
||||
bool sessionPresent :1; /**< was a session found on the server? */
|
||||
unsigned int reserved :7; /**< message type nibble */
|
||||
} bits;
|
||||
#endif
|
||||
} flags; /**< connack flags byte */
|
||||
char rc; /**< connack return code */
|
||||
} Connack;
|
||||
|
||||
|
||||
/**
|
||||
* Data for a publish packet.
|
||||
*/
|
||||
@@ -214,11 +222,13 @@ public:
|
||||
int getSUBACK(unsigned short* msgId, unsigned char* rc);
|
||||
int getPUBLISH(Publish* pub);
|
||||
|
||||
int setCONNECT(Connect* conect, unsigned char* username, unsigned char* password);
|
||||
int setCONNECT(Connect* conect, unsigned char* username,
|
||||
unsigned char* password);
|
||||
int setPUBLISH(Publish* pub);
|
||||
int setAck(unsigned char msgType, unsigned short msgid);
|
||||
int setHeader(unsigned char msgType);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId);
|
||||
int setSUBSCRIBE(const char* topic, unsigned char qos,
|
||||
unsigned short msgId);
|
||||
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
||||
|
||||
UTF8String getTopic(void);
|
||||
|
||||
@@ -37,14 +37,15 @@ MQTTGWPublishHandler::~MQTTGWPublishHandler()
|
||||
|
||||
void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
if ( !client->isActive() && !client->isSleep() && !client->isAwake())
|
||||
if (!client->isActive() && !client->isSleep() && !client->isAwake())
|
||||
{
|
||||
WRITELOG("%s The client is neither active nor sleep %s%s\n", ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s The client is neither active nor sleep %s%s\n",
|
||||
ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* client is sleeping. save PUBLISH */
|
||||
if ( client->isSleep() )
|
||||
if (client->isSleep())
|
||||
{
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
@@ -56,16 +57,17 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if ( pub.header.bits.qos == 2)
|
||||
else if (pub.header.bits.qos == 2)
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
if ( msg->getType() == 0 )
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTGWPublishHandler::handlePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
return;
|
||||
}
|
||||
@@ -94,26 +96,27 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
topicId.data.long_.name = pub.topic;
|
||||
Topic* tp = client->getTopics()->getTopicByName(&topicId);
|
||||
|
||||
if ( tp )
|
||||
if (tp)
|
||||
{
|
||||
topicId.type = tp->getType();
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = tp->getTopicId();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This message might be subscribed with wild card. */
|
||||
/* This message might be subscribed with wild card or not cleanSession*/
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
Topic* topic = client->getTopics()->match(&topicId);
|
||||
if (topic == nullptr)
|
||||
|
||||
if (topic == nullptr && client->isCleanSession())
|
||||
{
|
||||
WRITELOG(" Invalid Topic. PUBLISH message is canceled.\n");
|
||||
WRITELOG("%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
if (pub.header.bits.qos == 1)
|
||||
{
|
||||
replyACK(client, &pub, PUBACK);
|
||||
}
|
||||
else if ( pub.header.bits.qos == 2 )
|
||||
else if (pub.header.bits.qos == 2)
|
||||
{
|
||||
replyACK(client, &pub, PUBREC);
|
||||
}
|
||||
@@ -122,10 +125,25 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
return;
|
||||
}
|
||||
|
||||
if (topic == nullptr)
|
||||
{
|
||||
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topicId.data.long_.len = pub.topiclen;
|
||||
topicId.data.long_.name = pub.topic;
|
||||
topicId.data.id = 0;
|
||||
}
|
||||
|
||||
/* add the Topic and get a TopicId */
|
||||
topic = client->getTopics()->add(&topicId);
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG(
|
||||
"%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
id = topic->getTopicId();
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
/* create REGISTER */
|
||||
@@ -145,15 +163,15 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
|
||||
/* send PUBLISH */
|
||||
topicId.data.id = id;
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos,
|
||||
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload,
|
||||
pub.payloadlen);
|
||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete snPacket;
|
||||
return;
|
||||
}
|
||||
@@ -171,7 +189,7 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
||||
void MQTTGWPublishHandler::replyACK(Client* client, Publish* pub, int type)
|
||||
{
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(type, (uint16_t)pub->msgId);
|
||||
pubAck->setAck(type, (uint16_t) pub->msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubAck);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
@@ -181,19 +199,20 @@ void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t)ack.msgId);
|
||||
TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t) ack.msgId);
|
||||
if (topicId)
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
mqttsnPacket->setPUBACK(topicId->getTopicId(), (uint16_t)ack.msgId, 0);
|
||||
mqttsnPacket->setPUBACK(topicId->getTopicId(), (uint16_t) ack.msgId, 0);
|
||||
|
||||
client->eraseWaitedPubTopicId((uint16_t)ack.msgId);
|
||||
client->eraseWaitedPubTopicId((uint16_t) ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return;
|
||||
}
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t)ack.msgId, client->getClientId());
|
||||
WRITELOG(" PUBACK from the Broker is invalid. PacketID : %04X ClientID : %s \n", (uint16_t) ack.msgId,
|
||||
client->getClientId());
|
||||
}
|
||||
|
||||
void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int type)
|
||||
@@ -201,7 +220,7 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int t
|
||||
Ack ack;
|
||||
packet->getAck(&ack);
|
||||
|
||||
if ( client->isActive() || client->isAwake() )
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
|
||||
if (type == PUBREC)
|
||||
@@ -221,12 +240,12 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int t
|
||||
ev1->setClientSendEvent(client, mqttsnPacket);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
}
|
||||
else if ( client->isSleep() )
|
||||
else if (client->isSleep())
|
||||
{
|
||||
if (type == PUBREL)
|
||||
{
|
||||
MQTTGWPacket* pubComp = new MQTTGWPacket();
|
||||
pubComp->setAck(PUBCOMP, (uint16_t)ack.msgId);
|
||||
pubComp->setAck(PUBCOMP, (uint16_t) ack.msgId);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, pubComp);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
@@ -234,16 +253,14 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handlePuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
@@ -253,10 +270,10 @@ void MQTTGWPublishHandler::handleAggregateAck(Client* client, MQTTGWPacket* pack
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
handleAck(newClient, packet,type);
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleAck(newClient, packet, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,22 +289,22 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket*
|
||||
Publish pub;
|
||||
packet->getPUBLISH(&pub);
|
||||
|
||||
|
||||
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted
|
||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||
|
||||
// ToDo: need to refactor
|
||||
ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic);
|
||||
|
||||
while ( elm != nullptr )
|
||||
while (elm != nullptr)
|
||||
{
|
||||
Client* devClient = elm->getClient();
|
||||
MQTTGWPacket* msg = new MQTTGWPacket();
|
||||
*msg = *packet;
|
||||
|
||||
if ( msg->getType() == 0 )
|
||||
if (msg->getType() == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
delete msg;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTGWPUBLISHHANDLER_H_ */
|
||||
|
||||
@@ -77,9 +77,9 @@ void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, MQTTGWPacket*
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleSuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
@@ -89,11 +89,10 @@ void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacke
|
||||
uint16_t msgId = packet->getMsgId();
|
||||
uint16_t clientMsgId = 0;
|
||||
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId);
|
||||
if ( newClient != nullptr )
|
||||
if (newClient != nullptr)
|
||||
{
|
||||
packet->setMsgId((int)clientMsgId);
|
||||
packet->setMsgId((int) clientMsgId);
|
||||
handleUnsuback(newClient, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,20 +36,19 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CONNECT
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
if ( packet->getCONNECT(&data) == 0 )
|
||||
if (packet->getCONNECT(&data) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if ( client->isSleep() || client->isAwake() )
|
||||
if (client->isSleep() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
@@ -70,7 +69,6 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
||||
|
||||
/* CONNECT was not sent yet. prepare Connect data */
|
||||
|
||||
|
||||
client->setSessionStatus(false);
|
||||
if (data.cleansession)
|
||||
{
|
||||
@@ -82,9 +80,9 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
||||
if (topics)
|
||||
{
|
||||
Topic* tp = topics->getFirstTopic();
|
||||
while( tp != nullptr )
|
||||
while (tp != nullptr)
|
||||
{
|
||||
if ( tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
if (tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
|
||||
}
|
||||
@@ -120,13 +118,12 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* WILLMSG
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( !client->isWaitWillMsg() )
|
||||
if (!client->isWaitWillMsg())
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
@@ -135,10 +132,10 @@ void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacke
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
//Connect* connectData = client->getConnectData();
|
||||
|
||||
if( client->isConnectSendable() )
|
||||
if (client->isConnectSendable())
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if ( packet->getWILLMSG(&willmsg) == 0 )
|
||||
if (packet->getWILLMSG(&willmsg) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -173,7 +170,7 @@ void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client, MQTTSNPa
|
||||
*/
|
||||
void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() )
|
||||
if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
@@ -195,7 +192,7 @@ void MQTTSNAggregateConnectionHandler::sendStoredPublish(Client* client)
|
||||
{
|
||||
MQTTGWPacket* msg = nullptr;
|
||||
|
||||
while ( ( msg = client->getClientSleepPacket() ) != nullptr )
|
||||
while ((msg = client->getClientSleepPacket()) != nullptr)
|
||||
{
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
|
||||
|
||||
@@ -24,11 +24,10 @@
|
||||
#include <string.h>
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Adapter
|
||||
=====================================*/
|
||||
Adapter:: Adapter(Gateway* gw)
|
||||
Adapter::Adapter(Gateway* gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
_proxy = new Proxy(gw);
|
||||
@@ -37,22 +36,21 @@ Adapter:: Adapter(Gateway* gw)
|
||||
|
||||
Adapter::~Adapter(void)
|
||||
{
|
||||
if ( _proxy )
|
||||
if (_proxy)
|
||||
{
|
||||
delete _proxy;
|
||||
}
|
||||
|
||||
if ( _proxySecure )
|
||||
if (_proxySecure)
|
||||
{
|
||||
delete _proxySecure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||
{
|
||||
_isSecure = false;
|
||||
if ( _gateway->hasSecureConnection() )
|
||||
if (_gateway->hasSecureConnection())
|
||||
{
|
||||
_isSecure = true;
|
||||
}
|
||||
@@ -69,20 +67,20 @@ void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||
setClient(client, false);
|
||||
client->setAdapterType(adapterType);
|
||||
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true, TRANSPEARENT_TYPE);
|
||||
client = _gateway->getClientList()->createClient(0, &idSecure, true, true,
|
||||
TRANSPEARENT_TYPE);
|
||||
setClient(client, true);
|
||||
client->setAdapterType(adapterType);
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getClient(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = _gateway->getClientList()->getClient(addr);
|
||||
if ( !client )
|
||||
if (!client)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if ( client->isQoSm1() )
|
||||
else if (client->isQoSm1())
|
||||
{
|
||||
return client;
|
||||
}
|
||||
@@ -95,11 +93,11 @@ Client* Adapter::getClient(SensorNetAddress* addr)
|
||||
const char* Adapter::getClientId(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = getClient(addr);
|
||||
if ( !client )
|
||||
if (!client)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if ( client->isQoSm1() )
|
||||
else if (client->isQoSm1())
|
||||
{
|
||||
return client->getClientId();
|
||||
}
|
||||
@@ -112,11 +110,11 @@ const char* Adapter::getClientId(SensorNetAddress* addr)
|
||||
bool Adapter::isSecure(SensorNetAddress* addr)
|
||||
{
|
||||
Client* client = getClient(addr);
|
||||
if ( !client )
|
||||
if (!client)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if ( client->isSecureNetwork() )
|
||||
else if (client->isSecureNetwork())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -133,7 +131,7 @@ bool Adapter::isSecure(void)
|
||||
|
||||
void Adapter::setClient(Client* client, bool secure)
|
||||
{
|
||||
if ( secure )
|
||||
if (secure)
|
||||
{
|
||||
_clientSecure = client;
|
||||
}
|
||||
@@ -157,7 +155,7 @@ void Adapter::checkConnection(void)
|
||||
{
|
||||
_proxy->checkConnection(_client);
|
||||
|
||||
if ( _isSecure )
|
||||
if (_isSecure)
|
||||
{
|
||||
_proxySecure->checkConnection(_clientSecure);
|
||||
}
|
||||
@@ -166,15 +164,16 @@ void Adapter::checkConnection(void)
|
||||
void Adapter::send(MQTTSNPacket* packet, Client* client)
|
||||
{
|
||||
Proxy* proxy = _proxy;
|
||||
if ( client->isSecureNetwork() && !_isSecure )
|
||||
if (client->isSecureNetwork() && !_isSecure)
|
||||
{
|
||||
if ( _isSecure )
|
||||
if (_isSecure)
|
||||
{
|
||||
proxy = _proxySecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s %s No Secure connections %s 's packet is discarded.%s\n", ERRMSG_HEADER, client->getClientId() , ERRMSG_FOOTER);
|
||||
WRITELOG("%s %s No Secure connections %s 's packet is discarded.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -185,7 +184,7 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
|
||||
|
||||
void Adapter::resetPingTimer(bool secure)
|
||||
{
|
||||
if ( secure )
|
||||
if (secure)
|
||||
{
|
||||
_proxySecure->resetPingTimer();
|
||||
}
|
||||
@@ -202,7 +201,7 @@ bool Adapter::isActive(void)
|
||||
|
||||
void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( client->isSecureNetwork())
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
_proxySecure->savePacket(client, packet);
|
||||
}
|
||||
@@ -212,10 +211,9 @@ void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Client* Adapter::getAdapterClient(Client* client)
|
||||
{
|
||||
if ( client->isSecureNetwork() )
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
return _clientSecure;
|
||||
}
|
||||
@@ -235,7 +233,7 @@ Proxy::Proxy(Gateway* gw)
|
||||
}
|
||||
Proxy::~Proxy(void)
|
||||
{
|
||||
if ( _suspendedPacketEventQue )
|
||||
if (_suspendedPacketEventQue)
|
||||
{
|
||||
delete _suspendedPacketEventQue;
|
||||
}
|
||||
@@ -243,7 +241,7 @@ Proxy::~Proxy(void)
|
||||
|
||||
void Proxy::checkConnection(Client* client)
|
||||
{
|
||||
if ( client->isDisconnect() || ( client->isConnecting() && _responseTimer.isTimeup()) )
|
||||
if (client->isDisconnect() || (client->isConnecting() && _responseTimer.isTimeup()))
|
||||
{
|
||||
client->connectSended();
|
||||
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
|
||||
@@ -257,7 +255,7 @@ void Proxy::checkConnection(Client* client)
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
}
|
||||
else if ( (client->isActive() && _keepAliveTimer.isTimeup() ) || (_isWaitingResp && _responseTimer.isTimeup() ) )
|
||||
else if ((client->isActive() && _keepAliveTimer.isTimeup()) || (_isWaitingResp && _responseTimer.isTimeup()))
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
@@ -268,7 +266,7 @@ void Proxy::checkConnection(Client* client)
|
||||
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
|
||||
_isWaitingResp = true;
|
||||
|
||||
if ( ++_retryCnt > PROXY_MAX_RETRY_CNT )
|
||||
if (++_retryCnt > PROXY_MAX_RETRY_CNT)
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
@@ -276,7 +274,6 @@ void Proxy::checkConnection(Client* client)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Proxy::resetPingTimer(void)
|
||||
{
|
||||
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
|
||||
@@ -284,9 +281,9 @@ void Proxy::resetPingTimer(void)
|
||||
|
||||
void Proxy::recv(MQTTSNPacket* packet, Client* client)
|
||||
{
|
||||
if ( packet->getType() == MQTTSN_CONNACK )
|
||||
if (packet->getType() == MQTTSN_CONNACK)
|
||||
{
|
||||
if ( packet->isAccepted() )
|
||||
if (packet->isAccepted())
|
||||
{
|
||||
_responseTimer.stop();
|
||||
_retryCnt = 0;
|
||||
@@ -294,14 +291,14 @@ void Proxy::recv(MQTTSNPacket* packet, Client* client)
|
||||
sendSuspendedPacket();
|
||||
}
|
||||
}
|
||||
else if ( packet->getType() == MQTTSN_PINGRESP )
|
||||
else if (packet->getType() == MQTTSN_PINGRESP)
|
||||
{
|
||||
_isWaitingResp = false;
|
||||
_responseTimer.stop();
|
||||
_retryCnt = 0;
|
||||
resetPingTimer();
|
||||
}
|
||||
else if ( packet->getType() == MQTTSN_DISCONNECT )
|
||||
else if (packet->getType() == MQTTSN_DISCONNECT)
|
||||
{
|
||||
// blank
|
||||
}
|
||||
@@ -317,7 +314,7 @@ void Proxy::savePacket(Client* client, MQTTSNPacket* packet)
|
||||
|
||||
void Proxy::sendSuspendedPacket(void)
|
||||
{
|
||||
while ( _suspendedPacketEventQue->size() )
|
||||
while (_suspendedPacketEventQue->size())
|
||||
{
|
||||
Event* ev = _suspendedPacketEventQue->wait();
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
|
||||
@@ -31,9 +31,10 @@ class EventQue;
|
||||
class Timer;
|
||||
|
||||
/* When you add a new type, Client::setAdapterType() and Client::isAdapter() functions must be modified. */
|
||||
typedef enum{
|
||||
typedef enum
|
||||
{
|
||||
Atype_QoSm1Proxy, Atype_Aggregater
|
||||
}AdapterType;
|
||||
} AdapterType;
|
||||
|
||||
/*=====================================
|
||||
Class Adapter
|
||||
@@ -60,16 +61,15 @@ public:
|
||||
void savePacket(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
private:
|
||||
Gateway* _gateway {nullptr};
|
||||
Proxy* _proxy {nullptr};
|
||||
Proxy* _proxySecure {nullptr};
|
||||
Client* _client {nullptr};
|
||||
Client* _clientSecure {nullptr};
|
||||
bool _isActive {false};
|
||||
bool _isSecure{false};
|
||||
Gateway* _gateway { nullptr };
|
||||
Proxy* _proxy { nullptr };
|
||||
Proxy* _proxySecure { nullptr };
|
||||
Client* _client { nullptr };
|
||||
Client* _clientSecure { nullptr };
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Proxy
|
||||
=====================================*/
|
||||
@@ -88,11 +88,12 @@ public:
|
||||
private:
|
||||
void sendSuspendedPacket(void);
|
||||
Gateway* _gateway;
|
||||
EventQue* _suspendedPacketEventQue {nullptr};
|
||||
EventQue* _suspendedPacketEventQue
|
||||
{ nullptr };
|
||||
Timer _keepAliveTimer;
|
||||
Timer _responseTimer;
|
||||
bool _isWaitingResp {false};
|
||||
int _retryCnt {0};
|
||||
bool _isWaitingResp { false };
|
||||
int _retryCnt { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,20 +39,19 @@ AdapterManager::AdapterManager(Gateway* gw)
|
||||
_aggregater = new Aggregater(gw);
|
||||
}
|
||||
|
||||
|
||||
void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1)
|
||||
{
|
||||
if ( aggregate )
|
||||
if (aggregate)
|
||||
{
|
||||
_aggregater->initialize(gwName);
|
||||
}
|
||||
|
||||
if ( qosM1 )
|
||||
if (qosM1)
|
||||
{
|
||||
_qosm1Proxy->initialize(gwName);
|
||||
}
|
||||
|
||||
if ( forwarder )
|
||||
if (forwarder)
|
||||
{
|
||||
_forwarders->initialize(_gateway);
|
||||
}
|
||||
@@ -60,15 +59,15 @@ void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bo
|
||||
|
||||
AdapterManager::~AdapterManager(void)
|
||||
{
|
||||
if ( _forwarders )
|
||||
if (_forwarders)
|
||||
{
|
||||
delete _forwarders;
|
||||
}
|
||||
if ( _qosm1Proxy )
|
||||
if (_qosm1Proxy)
|
||||
{
|
||||
delete _qosm1Proxy;
|
||||
}
|
||||
if ( _aggregater )
|
||||
if (_aggregater)
|
||||
{
|
||||
delete _aggregater;
|
||||
}
|
||||
@@ -91,7 +90,7 @@ Aggregater* AdapterManager::getAggregater(void)
|
||||
|
||||
bool AdapterManager::isAggregatedClient(Client* client)
|
||||
{
|
||||
if ( !_aggregater->isActive() || client->isQoSm1() || client->isAggregater() || client->isQoSm1Proxy())
|
||||
if (!_aggregater->isActive() || client->isQoSm1() || client->isAggregater() || client->isQoSm1Proxy())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -106,21 +105,21 @@ Client* AdapterManager::getClient(Client* client)
|
||||
bool secure = client->isSecureNetwork();
|
||||
Client* newClient = client;
|
||||
|
||||
if ( client->isQoSm1() )
|
||||
if (client->isQoSm1())
|
||||
{
|
||||
newClient = _qosm1Proxy->getAdapterClient(client);
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isAggregated() )
|
||||
else if (client->isAggregated())
|
||||
{
|
||||
newClient = _aggregater->getAdapterClient(client);
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isQoSm1Proxy() )
|
||||
else if (client->isQoSm1Proxy())
|
||||
{
|
||||
_qosm1Proxy->resetPingTimer(secure);
|
||||
}
|
||||
else if ( client->isAggregater() )
|
||||
else if (client->isAggregater())
|
||||
{
|
||||
_aggregater->resetPingTimer(secure);
|
||||
}
|
||||
@@ -133,23 +132,23 @@ int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, Client
|
||||
Forwarder* fwd = client->getForwarder();
|
||||
int rc = 0;
|
||||
|
||||
if ( fwd )
|
||||
if (fwd)
|
||||
{
|
||||
MQTTSNGWEncapsulatedPacket encap(packet);
|
||||
WirelessNodeId* wnId = fwd->getWirelessNodeId(client);
|
||||
encap.setWirelessNodeId(wnId);
|
||||
task->log(client, packet);
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, fwd->getId(), encap.print(pbuf));
|
||||
rc = encap.unicast(_gateway->getSensorNetwork(),fwd->getSensorNetAddr());
|
||||
rc = encap.unicast(_gateway->getSensorNetwork(), fwd->getSensorNetAddr());
|
||||
}
|
||||
else
|
||||
{
|
||||
task->log(client, packet);
|
||||
if ( client->isQoSm1Proxy() )
|
||||
if (client->isQoSm1Proxy())
|
||||
{
|
||||
_qosm1Proxy->send(packet, client);
|
||||
}
|
||||
else if ( client->isAggregater() )
|
||||
else if (client->isAggregater())
|
||||
{
|
||||
_aggregater->send(packet, client);
|
||||
}
|
||||
@@ -163,12 +162,12 @@ int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, Client
|
||||
|
||||
void AdapterManager::checkConnection(void)
|
||||
{
|
||||
if ( _aggregater->isActive())
|
||||
if (_aggregater->isActive())
|
||||
{
|
||||
_aggregater->checkConnection();
|
||||
}
|
||||
|
||||
if ( _qosm1Proxy->isActive())
|
||||
if (_qosm1Proxy->isActive())
|
||||
{
|
||||
_qosm1Proxy->checkConnection();
|
||||
}
|
||||
@@ -185,25 +184,25 @@ bool AdapterManager::isAggregaterActive(void)
|
||||
}
|
||||
|
||||
/*
|
||||
AggregateTopicElement* AdapterManager::findTopic(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* AdapterManager::findTopic(Topic* topic)
|
||||
{
|
||||
return _aggregater->findTopic(topic);
|
||||
}
|
||||
}
|
||||
|
||||
AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
return _aggregater->addAggregateTopic(topic, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AdapterManager::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
void AdapterManager::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
//_aggregater->removeAggregateTopic(topic, client);
|
||||
}
|
||||
}
|
||||
|
||||
void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client)
|
||||
{
|
||||
void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -49,18 +49,16 @@ public:
|
||||
bool isAggregatedClient(Client* client);
|
||||
Client* getClient(Client* client);
|
||||
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task);
|
||||
int unicastToClient(Client* client, MQTTSNPacket* packet,
|
||||
ClientSendTask* task);
|
||||
bool isAggregaterActive(void);
|
||||
|
||||
private:
|
||||
Gateway* _gateway {nullptr};
|
||||
ForwarderList* _forwarders {nullptr};
|
||||
QoSm1Proxy* _qosm1Proxy {nullptr};
|
||||
Aggregater* _aggregater {nullptr};
|
||||
Gateway* _gateway { nullptr };
|
||||
ForwarderList* _forwarders { nullptr };
|
||||
QoSm1Proxy* _qosm1Proxy { nullptr };
|
||||
Aggregater* _aggregater { nullptr };
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */
|
||||
|
||||
@@ -51,7 +51,7 @@ AggregateTopicElement::AggregateTopicElement(Topic* topic, Client* client)
|
||||
{
|
||||
_topic = topic;
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if ( elm != nullptr )
|
||||
if (elm != nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
@@ -61,10 +61,10 @@ AggregateTopicElement::AggregateTopicElement(Topic* topic, Client* client)
|
||||
AggregateTopicElement::~AggregateTopicElement(void)
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _head != nullptr )
|
||||
if (_head != nullptr)
|
||||
{
|
||||
ClientTopicElement* p = _tail;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
ClientTopicElement* pPrev = p;
|
||||
delete p;
|
||||
@@ -78,14 +78,14 @@ AggregateTopicElement::~AggregateTopicElement(void)
|
||||
ClientTopicElement* AggregateTopicElement::add(Client* client)
|
||||
{
|
||||
ClientTopicElement* elm = new ClientTopicElement(client);
|
||||
if ( elm == nullptr )
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
@@ -93,7 +93,7 @@ ClientTopicElement* AggregateTopicElement::add(Client* client)
|
||||
else
|
||||
{
|
||||
ClientTopicElement* p = find(client);
|
||||
if ( p == nullptr )
|
||||
if (p == nullptr)
|
||||
{
|
||||
p = _tail;
|
||||
_tail = elm;
|
||||
@@ -113,9 +113,9 @@ ClientTopicElement* AggregateTopicElement::add(Client* client)
|
||||
ClientTopicElement* AggregateTopicElement::find(Client* client)
|
||||
{
|
||||
ClientTopicElement* p = _head;
|
||||
while ( p != nullptr )
|
||||
while (p != nullptr)
|
||||
{
|
||||
if ( p->_client == client)
|
||||
if (p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -139,12 +139,12 @@ void AggregateTopicElement::eraseClient(Client* client)
|
||||
_mutex.lock();
|
||||
|
||||
ClientTopicElement* p = find(client);
|
||||
if ( p != nullptr )
|
||||
if (p != nullptr)
|
||||
{
|
||||
if ( p->_prev == nullptr ) // head element
|
||||
if (p->_prev == nullptr) // head element
|
||||
{
|
||||
_head = p->_next;
|
||||
if ( p->_next == nullptr ) // head & only one
|
||||
if (p->_next == nullptr) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
@@ -153,7 +153,7 @@ void AggregateTopicElement::eraseClient(Client* client)
|
||||
p->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if ( p->_next != nullptr ) // middle
|
||||
else if (p->_next != nullptr) // middle
|
||||
{
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
@@ -186,9 +186,9 @@ AggregateTopicElement* AggregateTopicTable::add(Topic* topic, Client* client)
|
||||
AggregateTopicElement* elm = nullptr;
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
if ( elm != nullptr )
|
||||
if (elm != nullptr)
|
||||
{
|
||||
if ( elm->find(client) == nullptr )
|
||||
if (elm->find(client) == nullptr)
|
||||
{
|
||||
elm->add(client);
|
||||
}
|
||||
@@ -197,7 +197,7 @@ AggregateTopicElement* AggregateTopicTable::add(Topic* topic, Client* client)
|
||||
{
|
||||
Topic* newTopic = topic->duplicate();
|
||||
elm = new AggregateTopicElement(newTopic, client);
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
@@ -220,11 +220,11 @@ void AggregateTopicTable::erase(Topic* topic, Client* client)
|
||||
_mutex.lock();
|
||||
elm = getAggregateTopicElement(topic);
|
||||
|
||||
if ( elm != nullptr )
|
||||
if (elm != nullptr)
|
||||
{
|
||||
elm->eraseClient(client);
|
||||
}
|
||||
if ( elm->_head == nullptr )
|
||||
if (elm->_head == nullptr)
|
||||
{
|
||||
erase(elm);
|
||||
}
|
||||
@@ -234,12 +234,12 @@ void AggregateTopicTable::erase(Topic* topic, Client* client)
|
||||
|
||||
void AggregateTopicTable::erase(AggregateTopicElement* elmTopic)
|
||||
{
|
||||
if ( elmTopic != nullptr )
|
||||
if (elmTopic != nullptr)
|
||||
{
|
||||
if ( elmTopic->_prev == nullptr ) // head element
|
||||
if (elmTopic->_prev == nullptr) // head element
|
||||
{
|
||||
_head = elmTopic->_next;
|
||||
if ( elmTopic->_next == nullptr ) // head & only one
|
||||
if (elmTopic->_next == nullptr) // head & only one
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
@@ -248,7 +248,7 @@ void AggregateTopicTable::erase(AggregateTopicElement* elmTopic)
|
||||
elmTopic->_next->_prev = nullptr; // head & midle
|
||||
}
|
||||
}
|
||||
else if ( elmTopic->_next != nullptr ) // middle
|
||||
else if (elmTopic->_next != nullptr) // middle
|
||||
{
|
||||
elmTopic->_prev->_next = elmTopic->_next;
|
||||
}
|
||||
@@ -265,9 +265,9 @@ AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topi
|
||||
{
|
||||
AggregateTopicElement* elm = _head;
|
||||
|
||||
while( elm != nullptr )
|
||||
while (elm != nullptr)
|
||||
{
|
||||
if ( elm->_topic->isMatch(topic->_topicName) )
|
||||
if (elm->_topic->isMatch(topic->_topicName))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -279,7 +279,7 @@ AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topi
|
||||
ClientTopicElement* AggregateTopicTable::getClientElement(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* elm = getAggregateTopicElement(topic);
|
||||
if ( elm != nullptr )
|
||||
if (elm != nullptr)
|
||||
{
|
||||
return elm->_head;
|
||||
}
|
||||
@@ -294,18 +294,18 @@ void AggregateTopicTable::print(void)
|
||||
AggregateTopicElement* elm = _head;
|
||||
|
||||
printf("Beginning of AggregateTopicTable\n");
|
||||
while( elm != nullptr )
|
||||
while (elm != nullptr)
|
||||
{
|
||||
printf("%s\n", elm->_topic->getTopicName()->c_str());
|
||||
|
||||
ClientTopicElement* clElm = elm->getFirstClientTopicElement();
|
||||
Client* client = clElm->getClient();
|
||||
|
||||
while ( client != nullptr )
|
||||
while (client != nullptr)
|
||||
{
|
||||
printf(" %s\n", client->getClientId());
|
||||
clElm = clElm->getNextClientElement();
|
||||
if ( clElm != nullptr )
|
||||
if (clElm != nullptr)
|
||||
{
|
||||
client = clElm->getClient();
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ public:
|
||||
private:
|
||||
void erase(AggregateTopicElement* elmTopic);
|
||||
Mutex _mutex;
|
||||
AggregateTopicElement* _head {nullptr};
|
||||
AggregateTopicElement* _tail {nullptr};
|
||||
int _cnt {0};
|
||||
int _maxSize {MAX_MESSAGEID_TABLE_SIZE};
|
||||
AggregateTopicElement* _head { nullptr };
|
||||
AggregateTopicElement* _tail { nullptr };
|
||||
int _cnt { 0 };
|
||||
int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -68,17 +68,18 @@ public:
|
||||
|
||||
ClientTopicElement* add(Client* client);
|
||||
ClientTopicElement* getFirstClientTopicElement(void);
|
||||
ClientTopicElement* getNextClientTopicElement(ClientTopicElement* elmClient);
|
||||
ClientTopicElement* getNextClientTopicElement(
|
||||
ClientTopicElement* elmClient);
|
||||
void eraseClient(Client* client);
|
||||
ClientTopicElement* find(Client* client);
|
||||
|
||||
private:
|
||||
Mutex _mutex;
|
||||
Topic* _topic {nullptr};
|
||||
AggregateTopicElement* _next {nullptr};
|
||||
AggregateTopicElement* _prev {nullptr};
|
||||
ClientTopicElement* _head {nullptr};
|
||||
ClientTopicElement* _tail {nullptr};
|
||||
Topic* _topic { nullptr };
|
||||
AggregateTopicElement* _next { nullptr };
|
||||
AggregateTopicElement* _prev { nullptr };
|
||||
ClientTopicElement* _head { nullptr };
|
||||
ClientTopicElement* _tail { nullptr };
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
@@ -96,13 +97,11 @@ public:
|
||||
Client* getClient(void);
|
||||
|
||||
private:
|
||||
Client* _client {nullptr};
|
||||
ClientTopicElement* _next {nullptr};
|
||||
ClientTopicElement* _prev {nullptr};
|
||||
Client* _client { nullptr };
|
||||
ClientTopicElement* _next { nullptr };
|
||||
ClientTopicElement* _prev { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
Aggregater::Aggregater(Gateway* gw) : Adapter(gw)
|
||||
Aggregater::Aggregater(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
}
|
||||
@@ -63,13 +64,12 @@ Client* Aggregater::convertClient(uint16_t msgId, uint16_t* clientMsgId)
|
||||
return _msgIdTable.getClientMsgId(msgId, clientMsgId);
|
||||
}
|
||||
|
||||
|
||||
uint16_t Aggregater::addMessageIdTable(Client* client, uint16_t msgId)
|
||||
{
|
||||
/* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/
|
||||
|
||||
MessageIdElement* elm = _msgIdTable.add(this, client, msgId);
|
||||
if ( elm == nullptr )
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -89,7 +89,6 @@ AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* clien
|
||||
return _topicTable.add(topic, client);
|
||||
}
|
||||
|
||||
|
||||
void Aggregater::removeAggregateTopic(Topic* topic, Client* client)
|
||||
{
|
||||
_topicTable.erase(topic, client);
|
||||
@@ -103,7 +102,7 @@ AggregateTopicElement* Aggregater::findTopic(Topic* topic)
|
||||
ClientTopicElement* Aggregater::getClientElement(Topic* topic)
|
||||
{
|
||||
AggregateTopicElement* elm = findTopic(topic);
|
||||
if ( elm != nullptr )
|
||||
if (elm != nullptr)
|
||||
{
|
||||
return elm->getFirstClientTopicElement();
|
||||
}
|
||||
@@ -123,26 +122,26 @@ bool Aggregater::testMessageIdTable(void)
|
||||
Client* client = new Client();
|
||||
uint16_t msgId = 0;
|
||||
|
||||
printf("msgId=%d\n", addMessageIdTable(client,1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client,4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 1));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 2));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 3));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
printf("msgId=%d\n", addMessageIdTable(client, 4));
|
||||
|
||||
convertClient(1,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(2,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(5,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(4,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(3,&msgId);
|
||||
printf("msgId=%d\n",msgId);
|
||||
convertClient(1, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(2, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(5, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(4, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
convertClient(3, &msgId);
|
||||
printf("msgId=%d\n", msgId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class Topics;
|
||||
/*=====================================
|
||||
Class Aggregater
|
||||
=====================================*/
|
||||
class Aggregater : public Adapter
|
||||
class Aggregater: public Adapter
|
||||
{
|
||||
friend class MessageIdTable;
|
||||
public:
|
||||
@@ -65,18 +65,14 @@ public:
|
||||
|
||||
private:
|
||||
uint16_t msgId(void);
|
||||
Gateway* _gateway {nullptr};
|
||||
Gateway* _gateway { nullptr };
|
||||
MessageIdTable _msgIdTable;
|
||||
AggregateTopicTable _topicTable;
|
||||
|
||||
bool _isActive {false};
|
||||
bool _isSecure {false};
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "MQTTSNGWBrokerRecvTask.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWClientList.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -30,13 +31,13 @@ char* currentDateTime(void);
|
||||
BrokerRecvTask::BrokerRecvTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gateway->attach((Thread*) this);
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerRecvTask");
|
||||
}
|
||||
|
||||
BrokerRecvTask::~BrokerRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +65,7 @@ void BrokerRecvTask::run(void)
|
||||
_light->blueLight(false);
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s BrokerRecvTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
return;
|
||||
}
|
||||
timeout.tv_sec = 0;
|
||||
@@ -77,7 +78,7 @@ void BrokerRecvTask::run(void)
|
||||
/* Prepare sockets list to read */
|
||||
Client* client = _gateway->getClientList()->getClient(0);
|
||||
|
||||
while ( client )
|
||||
while (client)
|
||||
{
|
||||
if (client->getNetwork()->isValid())
|
||||
{
|
||||
@@ -100,11 +101,12 @@ void BrokerRecvTask::run(void)
|
||||
{
|
||||
/* Check sockets is ready to read */
|
||||
int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
|
||||
|
||||
if (activity > 0)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(0);
|
||||
|
||||
while ( client )
|
||||
while (client)
|
||||
{
|
||||
_light->blueLight(false);
|
||||
if (client->getNetwork()->isValid())
|
||||
@@ -117,9 +119,9 @@ void BrokerRecvTask::run(void)
|
||||
/* read sockets */
|
||||
_light->blueLight(true);
|
||||
rc = packet->recv(client->getNetwork());
|
||||
if ( rc > 0 )
|
||||
if (rc > 0)
|
||||
{
|
||||
if ( log(client, packet) == -1 )
|
||||
if (log(client, packet) == -1)
|
||||
{
|
||||
delete packet;
|
||||
goto nextClient;
|
||||
@@ -132,49 +134,45 @@ void BrokerRecvTask::run(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( rc == 0 ) // Disconnected
|
||||
if (rc == 0) // Disconnected
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
client->getNetwork()->close();
|
||||
delete packet;
|
||||
|
||||
/* delete client when the client is not authorized & session is clean */
|
||||
_gateway->getClientList()->erase(client);
|
||||
|
||||
if ( client )
|
||||
{
|
||||
client = client->getNextClient();
|
||||
}
|
||||
continue;
|
||||
client->disconnected();
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n", ERRMSG_HEADER, errno, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n",
|
||||
ERRMSG_HEADER, errno, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else if ( rc == -2 )
|
||||
else if (rc == -2)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n", ERRMSG_HEADER, client->getClientId(),ERRMSG_FOOTER);
|
||||
WRITELOG(
|
||||
"%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else if ( rc == -3 )
|
||||
else if (rc == -3)
|
||||
{
|
||||
WRITELOG("%s BrokerRecvTask can't get memories for the packet %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
|
||||
delete packet;
|
||||
|
||||
if ( (rc == -1 || rc == -2) && ( client->isActive() || client->isSleep() || client->isAwake() ))
|
||||
if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
|
||||
{
|
||||
/* disconnect the client */
|
||||
packet = new MQTTGWPacket();
|
||||
packet->setHeader(DISCONNECT);
|
||||
ev = new Event();
|
||||
ev->setBrokerRecvEvent(client, packet);
|
||||
_gateway->getPacketEventQue()->post(ev);
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextClient:
|
||||
client = client->getNextClient();
|
||||
nextClient: client = client->getNextClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,7 +184,7 @@ void BrokerRecvTask::run(void)
|
||||
*/
|
||||
int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5) * 3];
|
||||
char msgId[6];
|
||||
int rc = 0;
|
||||
|
||||
@@ -196,17 +194,20 @@ int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBACK:
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBACK:
|
||||
case UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGRESP:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace MQTTSNGW
|
||||
class BrokerRecvTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
;
|
||||
|
||||
public:
|
||||
BrokerRecvTask(Gateway* gateway);
|
||||
~BrokerRecvTask();
|
||||
@@ -44,5 +44,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWBROKERRECVTASK_H_ */
|
||||
|
||||
@@ -34,14 +34,14 @@ char* currentDateTime();
|
||||
BrokerSendTask::BrokerSendTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gateway->attach((Thread*) this);
|
||||
_gwparams = nullptr;
|
||||
_light = nullptr;
|
||||
setTaskName("BrokerSendTask");
|
||||
}
|
||||
|
||||
BrokerSendTask::~BrokerSendTask()
|
||||
{
|
||||
// WRITELOG("BrokerSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,14 +68,14 @@ void BrokerSendTask::run()
|
||||
{
|
||||
ev = _gateway->getBrokerSendQue()->wait();
|
||||
|
||||
if ( ev->getEventType() == EtStop )
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("\n%s BrokerSendTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ev->getEventType() == EtBrokerSend)
|
||||
if (ev->getEventType() == EtBrokerSend)
|
||||
{
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTGWPacket();
|
||||
@@ -83,26 +83,27 @@ void BrokerSendTask::run()
|
||||
/* Check Client is managed by Adapters */
|
||||
client = adpMgr->getClient(client);
|
||||
|
||||
if ( packet->getType() == CONNECT && client->getNetwork()->isValid() )
|
||||
if (packet->getType() == CONNECT && client->getNetwork()->isValid())
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
|
||||
if ( !client->getNetwork()->isValid() )
|
||||
if (!client->getNetwork()->isValid())
|
||||
{
|
||||
/* connect to the broker and send a packet */
|
||||
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->portSecure, (const char*)_gwparams->rootCApath,
|
||||
(const char*)_gwparams->rootCAfile, (const char*)_gwparams->certKey, (const char*)_gwparams->privateKey);
|
||||
rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->portSecure,
|
||||
(const char*) _gwparams->rootCApath, (const char*) _gwparams->rootCAfile,
|
||||
(const char*) _gwparams->certKey, (const char*) _gwparams->privateKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->port);
|
||||
rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->port);
|
||||
}
|
||||
|
||||
if ( !rc )
|
||||
if (!rc)
|
||||
{
|
||||
/* disconnect the broker and the client */
|
||||
WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n",
|
||||
@@ -115,13 +116,13 @@ void BrokerSendTask::run()
|
||||
|
||||
/* send a packet */
|
||||
_light->blueLight(true);
|
||||
if ( (rc = packet->send(client->getNetwork())) > 0 )
|
||||
if ((rc = packet->send(client->getNetwork())) > 0)
|
||||
{
|
||||
if ( packet->getType() == CONNECT )
|
||||
if (packet->getType() == CONNECT)
|
||||
{
|
||||
client->connectSended();
|
||||
}
|
||||
else if ( packet->getType() == DISCONNECT )
|
||||
else if (packet->getType() == DISCONNECT)
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
client->disconnected();
|
||||
@@ -132,7 +133,7 @@ void BrokerSendTask::run()
|
||||
{
|
||||
WRITELOG("%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
|
||||
if ( errno != EBADF )
|
||||
if ( errno != EBADF)
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
@@ -151,22 +152,23 @@ void BrokerSendTask::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* write message content into stdout or Ringbuffer
|
||||
*/
|
||||
void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5) * 3];
|
||||
char msgId[6];
|
||||
|
||||
switch (packet->getType())
|
||||
{
|
||||
case CONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case SUBSCRIBE:
|
||||
case UNSUBSCRIBE:
|
||||
@@ -174,13 +176,16 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
case PUBREC:
|
||||
case PUBREL:
|
||||
case PUBCOMP:
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||
client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case PINGREQ:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
case DISCONNECT:
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -27,9 +27,9 @@ class Adapter;
|
||||
/*=====================================
|
||||
Class BrokerSendTask
|
||||
=====================================*/
|
||||
class BrokerSendTask : public Thread
|
||||
class BrokerSendTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
BrokerSendTask(Gateway* gateway);
|
||||
|
||||
@@ -28,17 +28,17 @@
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
static const char* theClientStatus[] = { "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake", "Lost" };
|
||||
static const char* theClientStatus[] = { "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake",
|
||||
"Lost" };
|
||||
|
||||
Client::Client(bool secure)
|
||||
{
|
||||
_packetId = 0;
|
||||
_snMsgId = 0;
|
||||
_status = Cstat_Disconnected;
|
||||
_status = Cstat_Free;
|
||||
_keepAliveMsec = 0;
|
||||
_topics = new Topics();
|
||||
_clientId = nullptr;
|
||||
@@ -58,27 +58,27 @@ Client::Client(bool secure)
|
||||
_hasPredefTopic = false;
|
||||
_holdPingRequest = false;
|
||||
_forwarder = nullptr;
|
||||
_clientType = Ctype_Regular;
|
||||
_clientType = Ctype_Normal;
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
if ( _topics )
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
|
||||
if ( _clientId )
|
||||
if (_clientId)
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
|
||||
if ( _willTopic )
|
||||
if (_willTopic)
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
|
||||
if ( _willMsg )
|
||||
if (_willMsg)
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ void Client::deleteFirstClientSleepPacket()
|
||||
int Client::setClientSleepPacket(MQTTGWPacket* packet)
|
||||
{
|
||||
int rc = _clientSleepPacketQue.post(packet);
|
||||
if ( rc )
|
||||
if (rc)
|
||||
{
|
||||
WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void Client::deleteFirstProxyPacket()
|
||||
int Client::setProxyPacket(MQTTSNPacket* packet)
|
||||
{
|
||||
int rc = _proxyPacketQue.post(packet);
|
||||
if ( rc )
|
||||
if (rc)
|
||||
{
|
||||
WRITELOG("%s %s is Disconnected. the packet was saved.\n", currentDateTime(), _clientId);
|
||||
}
|
||||
@@ -177,13 +177,14 @@ void Client::clearWaitedSubTopicId(void)
|
||||
_waitedSubTopicIdMap.clear();
|
||||
}
|
||||
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
void Client::setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedPubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
|
||||
void Client::setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, type);
|
||||
_waitedSubTopicIdMap.add(msgId, topicId, topic);
|
||||
}
|
||||
|
||||
bool Client::checkTimeover(void)
|
||||
@@ -240,7 +241,7 @@ void Client::updateStatus(MQTTSNPacket* packet)
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBREC:
|
||||
if ( _clientType != Ctype_Proxy )
|
||||
if (_clientType != Ctype_Proxy)
|
||||
{
|
||||
_keepAliveTimer.start(_keepAliveMsec * 1.5);
|
||||
}
|
||||
@@ -280,8 +281,7 @@ void Client::updateStatus(MQTTSNPacket* packet)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
}DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
|
||||
}
|
||||
|
||||
void Client::updateStatus(ClientStatus stat)
|
||||
@@ -317,9 +317,14 @@ void Client::tryConnect(void)
|
||||
_status = Cstat_TryConnecting;
|
||||
}
|
||||
|
||||
bool Client::isCleanSession(void)
|
||||
{
|
||||
return _sessionStatus;
|
||||
}
|
||||
|
||||
bool Client::isConnectSendable(void)
|
||||
{
|
||||
if ( _status == Cstat_Lost || _status == Cstat_TryConnecting )
|
||||
if (_status == Cstat_Lost || _status == Cstat_TryConnecting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -332,7 +337,7 @@ bool Client::isConnectSendable(void)
|
||||
uint16_t Client::getNextPacketId(void)
|
||||
{
|
||||
_packetId++;
|
||||
if ( _packetId == 0xffff )
|
||||
if (_packetId == 0xffff)
|
||||
{
|
||||
_packetId = 1;
|
||||
}
|
||||
@@ -441,49 +446,49 @@ Client* Client::getNextClient(void)
|
||||
|
||||
void Client::setClientId(MQTTSNString id)
|
||||
{
|
||||
if ( _clientId )
|
||||
if (_clientId)
|
||||
{
|
||||
free(_clientId);
|
||||
}
|
||||
|
||||
if ( id.cstring )
|
||||
if (id.cstring)
|
||||
{
|
||||
_clientId = (char*)calloc(strlen(id.cstring) + 1, 1);
|
||||
_clientId = (char*) calloc(strlen(id.cstring) + 1, 1);
|
||||
memcpy(_clientId, id.cstring, strlen(id.cstring));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save clientId into (char*)_clientId NULL terminated */
|
||||
_clientId = (char*)calloc(MQTTSNstrlen(id) + 1, 1);
|
||||
unsigned char* ptr = (unsigned char*)_clientId;
|
||||
writeMQTTSNString((unsigned char**)&ptr, id);
|
||||
_clientId = (char*) calloc(MQTTSNstrlen(id) + 1, 1);
|
||||
unsigned char* ptr = (unsigned char*) _clientId;
|
||||
writeMQTTSNString((unsigned char**) &ptr, id);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setWillTopic(MQTTSNString willTopic)
|
||||
{
|
||||
if ( _willTopic )
|
||||
if (_willTopic)
|
||||
{
|
||||
free(_willTopic);
|
||||
}
|
||||
|
||||
_willTopic = (char*)calloc(MQTTSNstrlen(willTopic) + 1, 1);
|
||||
_willTopic = (char*) calloc(MQTTSNstrlen(willTopic) + 1, 1);
|
||||
/* save willTopic into (char*)_willTopic with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*)_willTopic;
|
||||
writeMQTTSNString((unsigned char**)&ptr, willTopic);
|
||||
unsigned char* ptr = (unsigned char*) _willTopic;
|
||||
writeMQTTSNString((unsigned char**) &ptr, willTopic);
|
||||
}
|
||||
|
||||
void Client::setWillMsg(MQTTSNString willMsg)
|
||||
{
|
||||
if ( _willMsg)
|
||||
if (_willMsg)
|
||||
{
|
||||
free(_willMsg);
|
||||
}
|
||||
|
||||
_willMsg = (char*)calloc(MQTTSNstrlen(willMsg) + 1, 1);
|
||||
_willMsg = (char*) calloc(MQTTSNstrlen(willMsg) + 1, 1);
|
||||
/* save willMsg into (char*)_willMsg with NULL termination */
|
||||
unsigned char* ptr = (unsigned char*)_willMsg;
|
||||
writeMQTTSNString((unsigned char**)&ptr, willMsg);
|
||||
unsigned char* ptr = (unsigned char*) _willMsg;
|
||||
writeMQTTSNString((unsigned char**) &ptr, willMsg);
|
||||
}
|
||||
|
||||
char* Client::getClientId(void)
|
||||
@@ -528,7 +533,7 @@ bool Client::isAggregater(void)
|
||||
|
||||
void Client::setAdapterType(AdapterType type)
|
||||
{
|
||||
switch ( type )
|
||||
switch (type)
|
||||
{
|
||||
case Atype_QoSm1Proxy:
|
||||
_clientType = Ctype_Proxy;
|
||||
@@ -537,7 +542,7 @@ void Client::setAdapterType(AdapterType type)
|
||||
_clientType = Ctype_Aggregater;
|
||||
break;
|
||||
default:
|
||||
throw Exception("Client::setAdapterType(): Invalid Type.");
|
||||
throw EXCEPTION("Client::setAdapterType(): Invalid Type.", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -577,8 +582,6 @@ bool Client::isHoldPingReqest(void)
|
||||
return _holdPingRequest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
@@ -691,4 +694,3 @@ uint8_t WaitREGACKPacketList::getCount(void)
|
||||
return _cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
_que = new Que<T>;
|
||||
}
|
||||
|
||||
|
||||
~PacketQue()
|
||||
{
|
||||
clear();
|
||||
@@ -72,8 +71,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
post(T* packet)
|
||||
int post(T* packet)
|
||||
{
|
||||
int rc;
|
||||
_mutex.lock();
|
||||
@@ -113,8 +111,6 @@ private:
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class WaitREGACKPacket
|
||||
=====================================*/
|
||||
@@ -151,26 +147,37 @@ private:
|
||||
waitREGACKPacket* _end;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Client
|
||||
=====================================*/
|
||||
typedef enum
|
||||
{
|
||||
Cstat_Disconnected = 0, Cstat_TryConnecting, Cstat_Connecting, Cstat_Active, Cstat_Asleep, Cstat_Awake, Cstat_Lost
|
||||
Cstat_Free = 0,
|
||||
Cstat_Disconnected,
|
||||
Cstat_TryConnecting,
|
||||
Cstat_Connecting,
|
||||
Cstat_Active,
|
||||
Cstat_Asleep,
|
||||
Cstat_Awake,
|
||||
Cstat_Lost
|
||||
} ClientStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Ctype_Regular = 0, Ctype_Forwarded, Ctype_QoS_1, Ctype_Aggregated, Ctype_Proxy, Ctype_Aggregater
|
||||
}ClientType;
|
||||
Ctype_Normal = 0,
|
||||
Ctype_Forwarded,
|
||||
Ctype_QoS_1,
|
||||
Ctype_Aggregated,
|
||||
Ctype_Proxy,
|
||||
Ctype_Aggregater
|
||||
} ClientType;
|
||||
|
||||
class Forwarder;
|
||||
|
||||
class Client
|
||||
{
|
||||
friend class ClientList;
|
||||
friend class ClientsPool;
|
||||
public:
|
||||
Client(bool secure = false);
|
||||
Client(uint8_t maxInflightMessages, bool secure);
|
||||
@@ -193,8 +200,8 @@ public:
|
||||
|
||||
int setClientSleepPacket(MQTTGWPacket*);
|
||||
int setProxyPacket(MQTTSNPacket* packet);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
void setWaitedPubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
|
||||
bool checkTimeover(void);
|
||||
void updateStatus(MQTTSNPacket*);
|
||||
@@ -249,6 +256,7 @@ public:
|
||||
bool isSecureNetwork(void);
|
||||
bool isSensorNetStable(void);
|
||||
bool isWaitWillMsg(void);
|
||||
bool isCleanSession(void);
|
||||
|
||||
void holdPingRequest(void);
|
||||
void resetPingRequest(void);
|
||||
@@ -299,7 +307,5 @@ private:
|
||||
Client* _prevClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWCLIENT_H_ */
|
||||
|
||||
@@ -20,18 +20,20 @@
|
||||
#include <string>
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
extern Gateway* theGateway;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
const char* common_topic = "*";
|
||||
|
||||
ClientList::ClientList()
|
||||
ClientList::ClientList(Gateway* gw)
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_authorize = false;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
_clientsPool = new ClientsPool();
|
||||
_gateway = gw;
|
||||
}
|
||||
|
||||
ClientList::~ClientList()
|
||||
@@ -46,15 +48,23 @@ ClientList::~ClientList()
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
|
||||
if (_clientsPool)
|
||||
{
|
||||
delete _clientsPool;
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void ClientList::initialize(bool aggregate)
|
||||
{
|
||||
if (theGateway->getGWParams()->clientAuthentication )
|
||||
_maxClients = _gateway->getGWParams()->maxClients;
|
||||
_clientsPool->allocate(_gateway->getGWParams()->maxClients);
|
||||
|
||||
if (_gateway->getGWParams()->clientAuthentication)
|
||||
{
|
||||
int type = TRANSPEARENT_TYPE;
|
||||
if ( aggregate )
|
||||
if (aggregate)
|
||||
{
|
||||
type = AGGREGATER_TYPE;
|
||||
}
|
||||
@@ -62,7 +72,7 @@ void ClientList::initialize(bool aggregate)
|
||||
_authorize = true;
|
||||
}
|
||||
|
||||
if ( theGateway->getGWParams()->predefinedTopic )
|
||||
if (_gateway->getGWParams()->predefinedTopic)
|
||||
{
|
||||
setPredefinedTopics(aggregate);
|
||||
}
|
||||
@@ -70,17 +80,17 @@ void ClientList::initialize(bool aggregate)
|
||||
|
||||
void ClientList::setClientList(int type)
|
||||
{
|
||||
if (!createList(theGateway->getGWParams()->clientListName, type))
|
||||
if (!createList(_gateway->getGWParams()->clientListName, type))
|
||||
{
|
||||
throw Exception("ClientList::setClientList No client list defined by config file.");
|
||||
throw EXCEPTION("ClientList::setClientList Client list not found!", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientList::setPredefinedTopics(bool aggrecate)
|
||||
{
|
||||
if ( !readPredefinedList(theGateway->getGWParams()->predefinedTopicFileName, aggrecate) )
|
||||
if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName, aggrecate))
|
||||
{
|
||||
throw Exception("ClientList::setPredefinedTopics No predefindTopi list defined by config file.");
|
||||
throw EXCEPTION("ClientList::setPredefinedTopics PredefindTopic list not found!", 0);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -148,15 +158,15 @@ bool ClientList::createList(const char* fileName, int type)
|
||||
forwarder = (data.find("forwarder") != string::npos);
|
||||
secure = (data.find("secureConnection") != string::npos);
|
||||
stable = !(data.find("unstableLine") != string::npos);
|
||||
if ( (qos_1 && type == QOSM1PROXY_TYPE) || (!qos_1 && type == AGGREGATER_TYPE) )
|
||||
if ((qos_1 && type == QOSM1PROXY_TYPE) || (!qos_1 && type == AGGREGATER_TYPE))
|
||||
{
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
}
|
||||
else if ( forwarder && type == FORWARDER_TYPE)
|
||||
else if (forwarder && type == FORWARDER_TYPE)
|
||||
{
|
||||
theGateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
_gateway->getAdapterManager()->getForwarderList()->addForwarder(&netAddr, &clientId);
|
||||
}
|
||||
else if (type == TRANSPEARENT_TYPE )
|
||||
else if (type == TRANSPEARENT_TYPE)
|
||||
{
|
||||
createClient(&netAddr, &clientId, stable, secure, type);
|
||||
}
|
||||
@@ -179,7 +189,8 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
FILE* fp;
|
||||
char buf[MAX_CLIENTID_LENGTH + 256];
|
||||
size_t pos0, pos1;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;;
|
||||
MQTTSNString clientId = MQTTSNString_initializer;
|
||||
;
|
||||
bool rc = false;
|
||||
|
||||
if ((fp = fopen(fileName, "r")) != 0)
|
||||
@@ -201,12 +212,12 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
}
|
||||
|
||||
pos0 = data.find_first_of(",");
|
||||
pos1 = data.find(",", pos0 + 1) ;
|
||||
pos1 = data.find(",", pos0 + 1);
|
||||
string id = data.substr(0, pos0);
|
||||
clientId.cstring = strdup(id.c_str());
|
||||
string topicName = data.substr(pos0 + 1, pos1 - pos0 -1);
|
||||
string topicName = data.substr(pos0 + 1, pos1 - pos0 - 1);
|
||||
uint16_t topicID = stoul(data.substr(pos1 + 1));
|
||||
createPredefinedTopic( &clientId, topicName, topicID, aggregate);
|
||||
createPredefinedTopic(&clientId, topicName, topicID, aggregate);
|
||||
free(clientId.cstring);
|
||||
}
|
||||
fclose(fp);
|
||||
@@ -222,7 +233,7 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
|
||||
|
||||
void ClientList::erase(Client*& client)
|
||||
{
|
||||
if ( !_authorize && client->erasable())
|
||||
if (!_authorize && client->erasable())
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* prev = client->_prevClient;
|
||||
@@ -247,7 +258,7 @@ void ClientList::erase(Client*& client)
|
||||
}
|
||||
_clientCnt--;
|
||||
Forwarder* fwd = client->getForwarder();
|
||||
if ( fwd )
|
||||
if (fwd)
|
||||
{
|
||||
fwd->eraseClient(client);
|
||||
}
|
||||
@@ -259,14 +270,14 @@ void ClientList::erase(Client*& client)
|
||||
|
||||
Client* ClientList::getClient(SensorNetAddress* addr)
|
||||
{
|
||||
if ( addr )
|
||||
if (addr)
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* client = _firstClient;
|
||||
|
||||
while (client != nullptr)
|
||||
{
|
||||
if (client->getSensorNetAddress()->isMatch(addr) )
|
||||
if (client->getSensorNetAddress()->isMatch(addr))
|
||||
{
|
||||
_mutex.unlock();
|
||||
return client;
|
||||
@@ -282,9 +293,9 @@ Client* ClientList::getClient(int index)
|
||||
{
|
||||
Client* client = _firstClient;
|
||||
int p = 0;
|
||||
while ( client != nullptr )
|
||||
while (client != nullptr)
|
||||
{
|
||||
if ( p == index )
|
||||
if (p == index)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
@@ -297,21 +308,20 @@ Client* ClientList::getClient(int index)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Client* ClientList::getClient(MQTTSNString* clientId)
|
||||
{
|
||||
_mutex.lock();
|
||||
Client* client = _firstClient;
|
||||
const char* clID =clientId->cstring;
|
||||
const char* clID = clientId->cstring;
|
||||
|
||||
if (clID == nullptr )
|
||||
if (clID == nullptr)
|
||||
{
|
||||
clID = clientId->lenstring.data;
|
||||
}
|
||||
|
||||
while (client != nullptr)
|
||||
{
|
||||
if (strncmp((const char*)client->getClientId(), clID, MQTTSNstrlen(*clientId)) == 0 )
|
||||
if (strncmp((const char*) client->getClientId(), clID, MQTTSNstrlen(*clientId)) == 0)
|
||||
{
|
||||
_mutex.unlock();
|
||||
return client;
|
||||
@@ -329,28 +339,29 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
|
||||
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type)
|
||||
{
|
||||
Client* client = nullptr;
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return 0; // full of clients
|
||||
}
|
||||
|
||||
client = getClient(addr);
|
||||
if ( client )
|
||||
Client* client = getClient(addr);
|
||||
if (client)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
/* creat a new client */
|
||||
client = new Client(secure);
|
||||
if ( addr )
|
||||
/* acquire a free client */
|
||||
client = _clientsPool->getClient();
|
||||
|
||||
if (!client)
|
||||
{
|
||||
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
|
||||
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
client->disconnected();
|
||||
if (addr)
|
||||
{
|
||||
client->setClientAddress(addr);
|
||||
}
|
||||
client->setSensorNetType(unstableLine);
|
||||
if ( MQTTSNstrlen(*clientId) )
|
||||
if (MQTTSNstrlen(*clientId))
|
||||
{
|
||||
client->setClientId(*clientId);
|
||||
}
|
||||
@@ -362,19 +373,20 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
free(dummyId.cstring);
|
||||
}
|
||||
|
||||
if ( type == AGGREGATER_TYPE )
|
||||
if (type == AGGREGATER_TYPE)
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
else if ( type == QOSM1PROXY_TYPE )
|
||||
else if (type == QOSM1PROXY_TYPE)
|
||||
{
|
||||
client->setQoSm1();
|
||||
}
|
||||
client->getNetwork()->setSecure(secure);
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
if (_firstClient == nullptr)
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
@@ -390,63 +402,37 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
return client;
|
||||
}
|
||||
|
||||
Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
|
||||
Client* ClientList::createPredefinedTopic(MQTTSNString* clientId, string topicName, uint16_t topicId, bool aggregate)
|
||||
{
|
||||
if ( topicId == 0 )
|
||||
if (topicId == 0)
|
||||
{
|
||||
WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( strcmp(clientId->cstring, common_topic) == 0 )
|
||||
if (strcmp(clientId->cstring, common_topic) == 0)
|
||||
{
|
||||
theGateway->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Client* client = getClient(clientId);
|
||||
Client *client = getClient(clientId);
|
||||
|
||||
if ( _authorize && client == nullptr )
|
||||
if (_authorize && client == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return nullptr; // full of clients
|
||||
}
|
||||
client = createClient(NULL, clientId, aggregate);
|
||||
|
||||
if ( client == nullptr )
|
||||
if (client == nullptr)
|
||||
{
|
||||
/* creat a new client */
|
||||
client = new Client();
|
||||
client->setClientId(*clientId);
|
||||
if ( aggregate )
|
||||
{
|
||||
client->setAggregated();
|
||||
}
|
||||
_mutex.lock();
|
||||
|
||||
/* add the list */
|
||||
if ( _firstClient == nullptr )
|
||||
{
|
||||
_firstClient = client;
|
||||
_endClient = client;
|
||||
}
|
||||
else
|
||||
{
|
||||
_endClient->_nextClient = client;
|
||||
client->_prevClient = _endClient;
|
||||
_endClient = client;
|
||||
}
|
||||
_clientCnt++;
|
||||
_mutex.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// create Topic & Add it
|
||||
client->getTopics()->add((const char*)topicName.c_str(), topicId);
|
||||
client->getTopics()->add((const char*) topicName.c_str(), topicId);
|
||||
client->_hasPredefTopic = true;
|
||||
return client;
|
||||
}
|
||||
@@ -462,4 +448,70 @@ bool ClientList::isAuthorized()
|
||||
return _authorize;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Class ClientsPool
|
||||
******************************/
|
||||
|
||||
ClientsPool::ClientsPool()
|
||||
{
|
||||
_clientCnt = 0;
|
||||
_firstClient = nullptr;
|
||||
_endClient = nullptr;
|
||||
}
|
||||
|
||||
ClientsPool::~ClientsPool()
|
||||
{
|
||||
Client* cl = _firstClient;
|
||||
Client* ncl;
|
||||
|
||||
while (cl != nullptr)
|
||||
{
|
||||
ncl = cl->_nextClient;
|
||||
delete cl;
|
||||
cl = ncl;
|
||||
};
|
||||
}
|
||||
|
||||
void ClientsPool::allocate(int maxClients)
|
||||
{
|
||||
Client* cl = nullptr;
|
||||
|
||||
_firstClient = new Client();
|
||||
|
||||
for (int i = 0; i < maxClients; i++)
|
||||
{
|
||||
if ((cl = new Client()) == nullptr)
|
||||
{
|
||||
throw Exception("ClientsPool::Can't allocate max number of clients\n", 0);
|
||||
}
|
||||
cl->_nextClient = _firstClient;
|
||||
_firstClient = cl;
|
||||
_clientCnt++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Client* ClientsPool::getClient(void)
|
||||
{
|
||||
Client *cl = nullptr;
|
||||
|
||||
while (_firstClient != nullptr)
|
||||
{
|
||||
cl = _firstClient;
|
||||
_firstClient = cl->_nextClient;
|
||||
cl->_nextClient = nullptr;
|
||||
_clientCnt--;
|
||||
break;
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
void ClientsPool::setClient(Client* client)
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
client->_nextClient = _firstClient;
|
||||
_firstClient = client;
|
||||
_clientCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,21 +30,41 @@ namespace MQTTSNGW
|
||||
|
||||
class Client;
|
||||
|
||||
/*=====================================
|
||||
Class ClientsPool
|
||||
=====================================*/
|
||||
class ClientsPool
|
||||
{
|
||||
public:
|
||||
ClientsPool();
|
||||
~ClientsPool();
|
||||
void allocate(int maxClients);
|
||||
Client* getClient(void);
|
||||
void setClient(Client* client);
|
||||
|
||||
private:
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
int _clientCnt;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class ClientList
|
||||
=====================================*/
|
||||
class ClientList
|
||||
{
|
||||
public:
|
||||
ClientList();
|
||||
ClientList(Gateway* gw);
|
||||
~ClientList();
|
||||
|
||||
void initialize(bool aggregate);
|
||||
void setClientList(int type);
|
||||
void setPredefinedTopics(bool aggregate);
|
||||
void erase(Client*&);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
int type);
|
||||
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
bool unstableLine, bool secure, int type);
|
||||
bool createList(const char* fileName, int type);
|
||||
Client* getClient(SensorNetAddress* addr);
|
||||
Client* getClient(MQTTSNString* clientId);
|
||||
@@ -55,18 +75,18 @@ public:
|
||||
|
||||
private:
|
||||
bool readPredefinedList(const char* fileName, bool _aggregate);
|
||||
Gateway* _gateway {nullptr};
|
||||
Client* createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t toipcId, bool _aggregate);
|
||||
ClientsPool* _clientsPool;
|
||||
Gateway* _gateway;
|
||||
Client* createPredefinedTopic(MQTTSNString* clientId, string topicName,
|
||||
uint16_t toipcId, bool _aggregate);
|
||||
Client* _firstClient;
|
||||
Client* _endClient;
|
||||
Mutex _mutex;
|
||||
uint16_t _clientCnt;
|
||||
bool _authorize {false};
|
||||
uint16_t _maxClients;
|
||||
bool _authorize { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include <cstring>
|
||||
|
||||
//#include "MQTTSNGWForwarder.h"
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
@@ -30,29 +28,22 @@ char* currentDateTime(void);
|
||||
ClientRecvTask::ClientRecvTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientRecvTask");
|
||||
}
|
||||
|
||||
ClientRecvTask::~ClientRecvTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SensorNetwork
|
||||
*/
|
||||
void ClientRecvTask::initialize(int argc, char** argv)
|
||||
{
|
||||
if ( _sensorNetwork->initialize() < 0 )
|
||||
{
|
||||
throw Exception(" Can't open the sensor network.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a packet from clients via sensor netwwork
|
||||
* and generate a event to execute the packet handling procedure
|
||||
* and creats a event to execute the packet handling procedure
|
||||
* of MQTTSNPacketHandlingTask.
|
||||
*/
|
||||
void ClientRecvTask::run()
|
||||
@@ -63,6 +54,7 @@ void ClientRecvTask::run()
|
||||
int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
|
||||
ClientList* clientList = _gateway->getClientList();
|
||||
EventQue* packetEventQue = _gateway->getPacketEventQue();
|
||||
EventQue* clientsendQue = _gateway->getClientSendQue();
|
||||
|
||||
char buf[128];
|
||||
|
||||
@@ -77,24 +69,24 @@ void ClientRecvTask::run()
|
||||
|
||||
if (CHK_SIGINT)
|
||||
{
|
||||
WRITELOG("\n%s ClientRecvTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete packet;
|
||||
return;
|
||||
}
|
||||
|
||||
if (packetLen < 2 )
|
||||
if (packetLen < 2)
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO )
|
||||
if (packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO)
|
||||
{
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( packet->getType() == MQTTSN_SEARCHGW )
|
||||
if (packet->getType() == MQTTSN_SEARCHGW)
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(0, packet, 0);
|
||||
@@ -104,23 +96,22 @@ void ClientRecvTask::run()
|
||||
continue;
|
||||
}
|
||||
|
||||
SensorNetAddress senderAddr = *_gateway->getSensorNetwork()->getSenderAddress();
|
||||
|
||||
SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress();
|
||||
|
||||
if ( packet->getType() == MQTTSN_ENCAPSULATED )
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr);
|
||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(&senderAddr);
|
||||
|
||||
if ( fwd != nullptr )
|
||||
if (fwd != nullptr)
|
||||
{
|
||||
MQTTSNString fwdName = MQTTSNString_initializer;
|
||||
fwdName.cstring = const_cast<char *>( fwd->getName() );
|
||||
fwdName.cstring = const_cast<char *>(fwd->getName());
|
||||
log(0, packet, &fwdName);
|
||||
|
||||
/* get the packet from the encapsulation message */
|
||||
MQTTSNGWEncapsulatedPacket encap;
|
||||
encap.desirialize(packet->getPacketData(), packet->getPacketLength());
|
||||
nodeId.setId( encap.getWirelessNodeId() );
|
||||
nodeId.setId(encap.getWirelessNodeId());
|
||||
client = fwd->getClient(&nodeId);
|
||||
packet = encap.getMQTTSNPacket();
|
||||
}
|
||||
@@ -129,38 +120,56 @@ void ClientRecvTask::run()
|
||||
{
|
||||
/* Check the client belonging to QoS-1Proxy ? */
|
||||
|
||||
if ( qosm1Proxy->isActive() )
|
||||
if (qosm1Proxy->isActive())
|
||||
{
|
||||
const char* clientName = qosm1Proxy->getClientId(senderAddr);
|
||||
const char *clientName = qosm1Proxy->getClientId(&senderAddr);
|
||||
|
||||
if ( clientName != nullptr )
|
||||
if (clientName != nullptr)
|
||||
{
|
||||
client = qosm1Proxy->getClient();
|
||||
|
||||
if ( !packet->isQoSMinusPUBLISH() )
|
||||
if (!packet->isQoSMinusPUBLISH())
|
||||
{
|
||||
log(clientName, packet);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n", ERRMSG_HEADER, clientName, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n",
|
||||
ERRMSG_HEADER, clientName, senderAddr.sprint(buf), ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( client == nullptr )
|
||||
if (client == nullptr)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient(senderAddr);
|
||||
client = _gateway->getClientList()->getClient(&senderAddr);
|
||||
}
|
||||
}
|
||||
|
||||
if ( client != nullptr )
|
||||
if (client != nullptr)
|
||||
{
|
||||
/* write log and post Event */
|
||||
log(client, packet, 0);
|
||||
|
||||
if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
|
||||
/* send DISCONNECT to the client, if it is not connected */
|
||||
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||
snPacket->setDISCONNECT(0);
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client,packet);
|
||||
ev->setClientSendEvent(client, snPacket);
|
||||
clientsendQue->post(ev);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = new Event();
|
||||
ev->setClientRecvEvent(client, packet);
|
||||
packetEventQue->post(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new client */
|
||||
@@ -168,19 +177,21 @@ void ClientRecvTask::run()
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
memset(&data, 0, sizeof(MQTTSNPacket_connectData));
|
||||
if ( !packet->getCONNECT(&data) )
|
||||
if (!packet->getCONNECT(&data))
|
||||
{
|
||||
log(0, packet, &data.clientID);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
client = clientList->getClient(&data.clientID);
|
||||
|
||||
if ( fwd != nullptr )
|
||||
if (fwd != nullptr)
|
||||
{
|
||||
if ( client == nullptr )
|
||||
if (client == nullptr)
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(0, &data.clientID, clientType);
|
||||
@@ -190,26 +201,28 @@ void ClientRecvTask::run()
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( client )
|
||||
if (client)
|
||||
{
|
||||
/* Authentication is not required */
|
||||
if ( _gateway->getGWParams()->clientAuthentication == false)
|
||||
if (_gateway->getGWParams()->clientAuthentication == false)
|
||||
{
|
||||
client->setClientAddress(senderAddr);
|
||||
client->setClientAddress(&senderAddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a new client */
|
||||
client = clientList->createClient(senderAddr, &data.clientID, clientType);
|
||||
client = clientList->createClient(&senderAddr, &data.clientID, clientType);
|
||||
}
|
||||
}
|
||||
|
||||
log(client, packet, &data.clientID);
|
||||
|
||||
if ( client == nullptr )
|
||||
if (client == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
delete packet;
|
||||
continue;
|
||||
}
|
||||
@@ -222,13 +235,18 @@ void ClientRecvTask::run()
|
||||
else
|
||||
{
|
||||
log(client, packet, 0);
|
||||
if ( packet->getType() == MQTTSN_ENCAPSULATED )
|
||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n", ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG(
|
||||
"%s MQTTSNGWClientRecvTask Forwarder(%s) is not declared by ClientList file. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
|
||||
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||
ERRMSG_FOOTER);
|
||||
}
|
||||
delete packet;
|
||||
}
|
||||
@@ -241,21 +259,21 @@ void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id)
|
||||
const char* clientId;
|
||||
char cstr[MAX_CLIENTID_LENGTH + 1];
|
||||
|
||||
if ( id )
|
||||
if (id)
|
||||
{
|
||||
if ( id->cstring )
|
||||
if (id->cstring)
|
||||
{
|
||||
strncpy(cstr, id->cstring, strlen(id->cstring) );
|
||||
strncpy(cstr, id->cstring, strlen(id->cstring));
|
||||
clientId = cstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((void*)cstr, 0, id->lenstring.len + 1);
|
||||
strncpy(cstr, id->lenstring.data, id->lenstring.len );
|
||||
memset((void*) cstr, 0, id->lenstring.len + 1);
|
||||
strncpy(cstr, id->lenstring.data, id->lenstring.len);
|
||||
clientId = cstr;
|
||||
}
|
||||
}
|
||||
else if ( client )
|
||||
else if (client)
|
||||
{
|
||||
clientId = client->getClientId();
|
||||
}
|
||||
@@ -275,11 +293,13 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_SEARCHGW:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, CLIENT, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNECT:
|
||||
case MQTTSN_PINGREQ:
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_G_G_NL, currentDateTime(), packet->getName(),
|
||||
LEFTARROW, clientId, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_DISCONNECT:
|
||||
case MQTTSN_WILLTOPICUPD:
|
||||
@@ -292,14 +312,16 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G_NL, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_G_MSGID_G_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_ENCAPSULATED:
|
||||
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
|
||||
|
||||
@@ -26,9 +26,9 @@ class AdapterManager;
|
||||
/*=====================================
|
||||
Class ClientRecvTask
|
||||
=====================================*/
|
||||
class ClientRecvTask:public Thread
|
||||
class ClientRecvTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
ClientRecvTask(Gateway*);
|
||||
|
||||
@@ -29,13 +29,13 @@ char* currentDateTime(void);
|
||||
ClientSendTask::ClientSendTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gateway->attach((Thread*) this);
|
||||
_sensorNetwork = _gateway->getSensorNetwork();
|
||||
setTaskName("ClientSendTask");
|
||||
}
|
||||
|
||||
ClientSendTask::~ClientSendTask()
|
||||
{
|
||||
// WRITELOG("ClientSendTask is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
void ClientSendTask::run()
|
||||
@@ -49,9 +49,9 @@ void ClientSendTask::run()
|
||||
{
|
||||
Event* ev = _gateway->getClientSendQue()->wait();
|
||||
|
||||
if (ev->getEventType() == EtStop || _gateway->IsStopping() )
|
||||
if (ev->getEventType() == EtStop || _gateway->IsStopping())
|
||||
{
|
||||
WRITELOG("\n%s ClientSendTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
break;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ void ClientSendTask::run()
|
||||
packet = ev->getMQTTSNPacket();
|
||||
log(client, packet);
|
||||
|
||||
if ( packet->broadcast(_sensorNetwork) < 0 )
|
||||
if (packet->broadcast(_sensorNetwork) < 0)
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't multicast a packet Error=%d%s\n",
|
||||
ERRMSG_HEADER, errno, ERRMSG_FOOTER);
|
||||
@@ -82,10 +82,11 @@ void ClientSendTask::run()
|
||||
rc = packet->unicast(_sensorNetwork, ev->getSensorNetAddress());
|
||||
}
|
||||
|
||||
if ( rc < 0 )
|
||||
if (rc < 0)
|
||||
{
|
||||
WRITELOG("%s ClientSendTask can't send a packet to the client %s. Error=%d%s\n",
|
||||
ERRMSG_HEADER, (client ? (const char*)client->getClientId() : UNKNOWNCL ), errno, ERRMSG_FOOTER);
|
||||
ERRMSG_HEADER, (client ? (const char*) client->getClientId() : UNKNOWNCL),
|
||||
errno, ERRMSG_FOOTER);
|
||||
}
|
||||
}
|
||||
delete ev;
|
||||
@@ -96,13 +97,14 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
|
||||
char msgId[6];
|
||||
const char* clientId = client ? (const char*)client->getClientId() : UNKNOWNCL ;
|
||||
const char* clientId = client ? (const char*) client->getClientId() : UNKNOWNCL;
|
||||
|
||||
switch (packet->getType())
|
||||
{
|
||||
case MQTTSN_ADVERTISE:
|
||||
case MQTTSN_GWINFO:
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, CLIENTS, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW,
|
||||
CLIENTS, packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_CONNACK:
|
||||
case MQTTSN_DISCONNECT:
|
||||
@@ -115,7 +117,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
break;
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_PUBLISH:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
case MQTTSN_REGACK:
|
||||
case MQTTSN_PUBACK:
|
||||
@@ -124,7 +127,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_SUBACK:
|
||||
case MQTTSN_UNSUBACK:
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||
packet->print(pbuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -28,7 +28,7 @@ class AdapterManager;
|
||||
=====================================*/
|
||||
class ClientSendTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend AdapterManager;
|
||||
public:
|
||||
ClientSendTask(Gateway* gateway);
|
||||
|
||||
@@ -69,13 +69,13 @@ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
|
||||
void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTSNPacket_connectData data;
|
||||
if ( packet->getCONNECT(&data) == 0 )
|
||||
if (packet->getCONNECT(&data) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* return CONNACK when the client is sleeping */
|
||||
if ( client->isSleep() || client->isAwake() )
|
||||
if (client->isSleep() || client->isAwake())
|
||||
{
|
||||
MQTTSNPacket* packet = new MQTTSNPacket();
|
||||
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
|
||||
@@ -90,7 +90,7 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
//* clear ConnectData of Client */
|
||||
Connect* connectData = client->getConnectData();
|
||||
memset(connectData, 0, sizeof(Connect));
|
||||
if ( !client->isAdapter() )
|
||||
if (!client->isAdapter())
|
||||
{
|
||||
client->disconnected();
|
||||
}
|
||||
@@ -125,7 +125,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
/* renew the TopicList */
|
||||
if (topics)
|
||||
{
|
||||
topics->eraseNormal();;
|
||||
topics->eraseNormal();
|
||||
;
|
||||
}
|
||||
client->setSessionStatus(true);
|
||||
}
|
||||
@@ -146,7 +147,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
||||
/* CONNECT message was not qued in.
|
||||
* create CONNECT message & send it to the broker */
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
mqMsg->setCONNECT(client->getConnectData(), (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, mqMsg);
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
@@ -162,7 +164,7 @@ void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* pack
|
||||
uint8_t willRetain;
|
||||
MQTTSNString willTopic = MQTTSNString_initializer;
|
||||
|
||||
if ( packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0 )
|
||||
if (packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -188,7 +190,7 @@ void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* pack
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( !client->isWaitWillMsg() )
|
||||
if (!client->isWaitWillMsg())
|
||||
{
|
||||
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
|
||||
return;
|
||||
@@ -197,10 +199,10 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet
|
||||
MQTTSNString willmsg = MQTTSNString_initializer;
|
||||
Connect* connectData = client->getConnectData();
|
||||
|
||||
if( client->isConnectSendable() )
|
||||
if (client->isConnectSendable())
|
||||
{
|
||||
/* save WillMsg in the client */
|
||||
if ( packet->getWILLMSG(&willmsg) == 0 )
|
||||
if (packet->getWILLMSG(&willmsg) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -209,7 +211,8 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet
|
||||
/* create CONNECT message */
|
||||
MQTTGWPacket* mqttPacket = new MQTTGWPacket();
|
||||
connectData->willMsg = client->getWillMsg();
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*)_gateway->getGWParams()->loginId, (unsigned char*)_gateway->getGWParams()->password);
|
||||
mqttPacket->setCONNECT(connectData, (unsigned char*) _gateway->getGWParams()->loginId,
|
||||
(unsigned char*) _gateway->getGWParams()->password);
|
||||
|
||||
/* Send CONNECT to the broker */
|
||||
Event* evt = new Event();
|
||||
@@ -226,9 +229,9 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* pac
|
||||
{
|
||||
uint16_t duration = 0;
|
||||
|
||||
if ( packet->getDISCONNECT(&duration) != 0 )
|
||||
if (packet->getDISCONNECT(&duration) != 0)
|
||||
{
|
||||
if ( duration == 0 )
|
||||
if (duration == 0)
|
||||
{
|
||||
MQTTGWPacket* mqMsg = new MQTTGWPacket();
|
||||
mqMsg->setHeader(DISCONNECT);
|
||||
@@ -276,7 +279,7 @@ void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* pac
|
||||
*/
|
||||
void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() )
|
||||
if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
|
||||
{
|
||||
sendStoredPublish(client);
|
||||
client->holdPingRequest();
|
||||
@@ -297,7 +300,7 @@ void MQTTSNConnectionHandler::sendStoredPublish(Client* client)
|
||||
{
|
||||
MQTTGWPacket* msg = nullptr;
|
||||
|
||||
while ( ( msg = client->getClientSleepPacket() ) != nullptr )
|
||||
while ((msg = client->getClientSleepPacket()) != nullptr)
|
||||
{
|
||||
// ToDo: This version can't re-send PUBLISH when PUBACK is not returned.
|
||||
client->deleteFirstClientSleepPacket(); // pop the que to delete element.
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace MQTTSNGW
|
||||
/*=================================
|
||||
* MQTT-SN Parametrs
|
||||
==================================*/
|
||||
#define MAX_CLIENTS (100) // Number of Clients can be handled.
|
||||
#define MAX_CLIENTS (100) // Default number of Clients can be handled.
|
||||
#define MAX_CLIENTID_LENGTH (64) // Max length of clientID
|
||||
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
|
||||
#define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size
|
||||
@@ -60,14 +60,19 @@ typedef unsigned int uint32_t;
|
||||
/*=================================
|
||||
* Log controls
|
||||
==================================*/
|
||||
//#define DEBUG // print out log for debug
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
|
||||
#ifdef DEBUG
|
||||
//#define DEBUG_MQTTSN // print out log for debug
|
||||
//#define DEBUG_NW // print out SensorNetwork log
|
||||
#ifdef DEBUG_MQTTSN
|
||||
#define DEBUGLOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUGLOG(...)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NW
|
||||
#define D_NWSTACK(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define D_NWSTACK(...)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* MQTTSNGWDEFINES_H_ */
|
||||
|
||||
@@ -21,17 +21,15 @@
|
||||
using namespace MQTTSNGW;
|
||||
using namespace std;
|
||||
|
||||
WirelessNodeId::WirelessNodeId()
|
||||
:
|
||||
_len{0},
|
||||
_nodeId{0}
|
||||
WirelessNodeId::WirelessNodeId() :
|
||||
_len { 0 }, _nodeId { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WirelessNodeId::~WirelessNodeId()
|
||||
{
|
||||
if ( _nodeId )
|
||||
if (_nodeId)
|
||||
{
|
||||
free(_nodeId);
|
||||
}
|
||||
@@ -39,12 +37,12 @@ WirelessNodeId::~WirelessNodeId()
|
||||
|
||||
void WirelessNodeId::setId(uint8_t* id, uint8_t len)
|
||||
{
|
||||
if ( _nodeId )
|
||||
if (_nodeId)
|
||||
{
|
||||
free(_nodeId);
|
||||
}
|
||||
uint8_t* buf = (uint8_t*)malloc(len);
|
||||
if ( buf )
|
||||
uint8_t* buf = (uint8_t*) malloc(len);
|
||||
if (buf)
|
||||
{
|
||||
memcpy(buf, id, len);
|
||||
_len = len;
|
||||
@@ -64,7 +62,7 @@ void WirelessNodeId::setId(WirelessNodeId* id)
|
||||
|
||||
bool WirelessNodeId::operator ==(WirelessNodeId& id)
|
||||
{
|
||||
if ( _len == id._len )
|
||||
if (_len == id._len)
|
||||
{
|
||||
return memcmp(_nodeId, id._nodeId, _len) == 0;
|
||||
}
|
||||
@@ -77,16 +75,14 @@ bool WirelessNodeId::operator ==(WirelessNodeId& id)
|
||||
/*
|
||||
* Class MQTTSNGWEncapsulatedPacket
|
||||
*/
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket()
|
||||
: _mqttsn{0},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() :
|
||||
_mqttsn { 0 }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet)
|
||||
: _mqttsn{packet},
|
||||
_ctrl{0}
|
||||
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) :
|
||||
_mqttsn { packet }, _ctrl { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
@@ -109,8 +105,8 @@ int MQTTSNGWEncapsulatedPacket::serialize(uint8_t* buf)
|
||||
buf[0] = _id._len + 3;
|
||||
buf[1] = MQTTSN_ENCAPSULATED;
|
||||
buf[2] = _ctrl;
|
||||
memcpy( buf + 3, _id._nodeId, _id._len);
|
||||
if ( _mqttsn )
|
||||
memcpy(buf + 3, _id._nodeId, _id._len);
|
||||
if (_mqttsn)
|
||||
{
|
||||
len = _mqttsn->getPacketLength();
|
||||
memcpy(buf + buf[0], _mqttsn->getPacketData(), len);
|
||||
@@ -120,7 +116,7 @@ int MQTTSNGWEncapsulatedPacket::serialize(uint8_t* buf)
|
||||
|
||||
int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, unsigned short len)
|
||||
{
|
||||
if ( _mqttsn )
|
||||
if (_mqttsn)
|
||||
{
|
||||
delete _mqttsn;
|
||||
_mqttsn = nullptr;
|
||||
|
||||
@@ -60,6 +60,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */
|
||||
|
||||
@@ -32,10 +32,10 @@ ForwarderList::ForwarderList()
|
||||
|
||||
ForwarderList::~ForwarderList()
|
||||
{
|
||||
if ( _head )
|
||||
if (_head)
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
Forwarder* next = p->_next;
|
||||
delete p;
|
||||
@@ -44,20 +44,18 @@ ForwarderList::~ForwarderList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ForwarderList::initialize(Gateway* gw)
|
||||
{
|
||||
/* Create Fowarders from clients.conf */
|
||||
gw->getClientList()->setClientList(FORWARDER_TYPE);
|
||||
}
|
||||
|
||||
|
||||
Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_sensorNetAddr.isMatch(addr) )
|
||||
if (p->_sensorNetAddr.isMatch(addr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -69,16 +67,16 @@ Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
|
||||
Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
{
|
||||
Forwarder* fdr = new Forwarder(addr, forwarderId);
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = fdr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Forwarder* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_next == nullptr )
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
p->_next = fdr;
|
||||
break;
|
||||
@@ -112,10 +110,10 @@ Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
|
||||
|
||||
Forwarder::~Forwarder(void)
|
||||
{
|
||||
if ( _headClient )
|
||||
if (_headClient)
|
||||
{
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
ForwarderElement* next = p->_next;
|
||||
delete p;
|
||||
@@ -136,11 +134,11 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
|
||||
|
||||
client->setForwarder(this);
|
||||
|
||||
if ( p != nullptr )
|
||||
if (p != nullptr)
|
||||
{
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
client->setForwarder(this);
|
||||
p->setWirelessNodeId(id);
|
||||
@@ -156,7 +154,7 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
|
||||
fclient->setClient(client);
|
||||
fclient->setWirelessNodeId(id);
|
||||
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = fclient;
|
||||
}
|
||||
@@ -171,9 +169,9 @@ Client* Forwarder::getClient(WirelessNodeId* id)
|
||||
Client* cl = nullptr;
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( *(p->_wirelessNodeId) == *id )
|
||||
if (*(p->_wirelessNodeId) == *id)
|
||||
{
|
||||
cl = p->_client;
|
||||
break;
|
||||
@@ -197,9 +195,9 @@ WirelessNodeId* Forwarder::getWirelessNodeId(Client* client)
|
||||
WirelessNodeId* nodeId = nullptr;
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
nodeId = p->_wirelessNodeId;
|
||||
break;
|
||||
@@ -219,11 +217,11 @@ void Forwarder::eraseClient(Client* client)
|
||||
_mutex.lock();
|
||||
ForwarderElement* p = _headClient;
|
||||
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_client == client )
|
||||
if (p->_client == client)
|
||||
{
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = p->_next;
|
||||
}
|
||||
@@ -251,10 +249,8 @@ SensorNetAddress* Forwarder::getSensorNetAddr(void)
|
||||
* Class ForwardedClient
|
||||
*/
|
||||
|
||||
ForwarderElement::ForwarderElement()
|
||||
: _client{0}
|
||||
, _wirelessNodeId{0}
|
||||
, _next{0}
|
||||
ForwarderElement::ForwarderElement() :
|
||||
_client { 0 }, _wirelessNodeId { 0 }, _next { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -273,7 +269,7 @@ void ForwarderElement::setClient(Client* client)
|
||||
|
||||
void ForwarderElement::setWirelessNodeId(WirelessNodeId* id)
|
||||
{
|
||||
if ( _wirelessNodeId == nullptr )
|
||||
if (_wirelessNodeId == nullptr)
|
||||
{
|
||||
_wirelessNodeId = new WirelessNodeId();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||
#include "SensorNetwork.h"
|
||||
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class Gateway;
|
||||
@@ -70,8 +69,8 @@ public:
|
||||
private:
|
||||
string _forwarderName;
|
||||
SensorNetAddress _sensorNetAddr;
|
||||
ForwarderElement* _headClient{nullptr};
|
||||
Forwarder* _next {nullptr};
|
||||
ForwarderElement* _headClient { nullptr };
|
||||
Forwarder* _next { nullptr };
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
@@ -94,6 +93,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */
|
||||
|
||||
@@ -35,7 +35,7 @@ void Logmonitor::run()
|
||||
while (true)
|
||||
{
|
||||
const char* data = getLog();
|
||||
if ( *data == 0 )
|
||||
if (*data == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ MessageIdTable::MessageIdTable()
|
||||
MessageIdTable::~MessageIdTable()
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _head != nullptr )
|
||||
if (_head != nullptr)
|
||||
{
|
||||
MessageIdElement* p = _tail;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
MessageIdElement* pPrev = p;
|
||||
delete p;
|
||||
@@ -47,18 +47,18 @@ MessageIdTable::~MessageIdTable()
|
||||
|
||||
MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
if ( _cnt > _maxSize )
|
||||
if (_cnt > _maxSize)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId);
|
||||
if ( elm == nullptr )
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
_mutex.lock();
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
_head = elm;
|
||||
@@ -68,7 +68,7 @@ MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, ui
|
||||
else
|
||||
{
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if ( p == nullptr )
|
||||
if (p == nullptr)
|
||||
{
|
||||
elm->_msgId = aggregater->msgId();
|
||||
p = _tail;
|
||||
@@ -90,9 +90,9 @@ MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, ui
|
||||
MessageIdElement* MessageIdTable::find(uint16_t msgId)
|
||||
{
|
||||
MessageIdElement* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_msgId == msgId)
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -104,9 +104,9 @@ MessageIdElement* MessageIdTable::find(uint16_t msgId)
|
||||
MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
MessageIdElement* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_clientMsgId == clientMsgId && p->_client == client)
|
||||
if (p->_clientMsgId == clientMsgId && p->_client == client)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -115,14 +115,13 @@ MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId)
|
||||
{
|
||||
Client* clt = nullptr;
|
||||
*clientMsgId = 0;
|
||||
_mutex.lock();
|
||||
MessageIdElement* p = find(msgId);
|
||||
if ( p != nullptr )
|
||||
if (p != nullptr)
|
||||
{
|
||||
clt = p->_client;
|
||||
*clientMsgId = p->_clientMsgId;
|
||||
@@ -142,15 +141,15 @@ void MessageIdTable::erase(uint16_t msgId)
|
||||
|
||||
void MessageIdTable::clear(MessageIdElement* elm)
|
||||
{
|
||||
if ( elm == nullptr )
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( elm->_prev == nullptr )
|
||||
if (elm->_prev == nullptr)
|
||||
{
|
||||
_head = elm->_next;
|
||||
if ( _head == nullptr)
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
@@ -165,7 +164,7 @@ void MessageIdTable::clear(MessageIdElement* elm)
|
||||
else
|
||||
{
|
||||
elm->_prev->_next = elm->_next;
|
||||
if ( elm->_next == nullptr )
|
||||
if (elm->_next == nullptr)
|
||||
{
|
||||
_tail = elm->_prev;
|
||||
}
|
||||
@@ -179,12 +178,11 @@ void MessageIdTable::clear(MessageIdElement* elm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
{
|
||||
uint16_t msgId = 0;
|
||||
MessageIdElement* p = find(client, clientMsgId);
|
||||
if ( p != nullptr )
|
||||
if (p != nullptr)
|
||||
{
|
||||
msgId = p->_msgId;
|
||||
}
|
||||
@@ -194,18 +192,14 @@ uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
||||
/*===============================
|
||||
* Class MessageIdElement
|
||||
===============================*/
|
||||
MessageIdElement::MessageIdElement(void)
|
||||
: _msgId{0}
|
||||
, _clientMsgId {0}
|
||||
, _client {nullptr}
|
||||
, _next {nullptr}
|
||||
, _prev {nullptr}
|
||||
MessageIdElement::MessageIdElement(void) :
|
||||
_msgId { 0 }, _clientMsgId { 0 }, _client { nullptr }, _next { nullptr }, _prev { nullptr }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId)
|
||||
: MessageIdElement()
|
||||
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) :
|
||||
MessageIdElement()
|
||||
{
|
||||
_msgId = msgId;
|
||||
_client = client;
|
||||
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
MessageIdTable();
|
||||
~MessageIdTable();
|
||||
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client, uint16_t clientMsgId);
|
||||
MessageIdElement* add(Aggregater* aggregater, Client* client,
|
||||
uint16_t clientMsgId);
|
||||
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||
void erase(uint16_t msgId);
|
||||
@@ -45,10 +46,10 @@ public:
|
||||
private:
|
||||
MessageIdElement* find(uint16_t msgId);
|
||||
MessageIdElement* find(Client* client, uint16_t clientMsgId);
|
||||
MessageIdElement* _head {nullptr};
|
||||
MessageIdElement* _tail {nullptr};
|
||||
int _cnt {0};
|
||||
int _maxSize {MAX_MESSAGEID_TABLE_SIZE};
|
||||
MessageIdElement* _head { nullptr };
|
||||
MessageIdElement* _tail{ nullptr };
|
||||
int _cnt { 0 };
|
||||
int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
@@ -72,7 +73,6 @@ private:
|
||||
MessageIdElement* _prev;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */
|
||||
|
||||
@@ -35,7 +35,7 @@ MQTTSNPacket::MQTTSNPacket(void)
|
||||
|
||||
MQTTSNPacket::MQTTSNPacket(MQTTSNPacket& packet)
|
||||
{
|
||||
_buf = (unsigned char*)malloc(packet._bufLen);
|
||||
_buf = (unsigned char*) malloc(packet._bufLen);
|
||||
if (_buf)
|
||||
{
|
||||
_bufLen = packet._bufLen;
|
||||
@@ -74,13 +74,13 @@ int MQTTSNPacket::serialize(uint8_t* buf)
|
||||
|
||||
int MQTTSNPacket::desirialize(unsigned char* buf, unsigned short len)
|
||||
{
|
||||
if ( _buf )
|
||||
if (_buf)
|
||||
{
|
||||
free(_buf);
|
||||
}
|
||||
|
||||
_buf = (unsigned char*)calloc(len, sizeof(unsigned char));
|
||||
if ( _buf )
|
||||
_buf = (unsigned char*) calloc(len, sizeof(unsigned char));
|
||||
if (_buf)
|
||||
{
|
||||
memcpy(_buf, buf, len);
|
||||
_bufLen = len;
|
||||
@@ -100,17 +100,13 @@ int MQTTSNPacket::recv(SensorNetwork* network)
|
||||
{
|
||||
len = desirialize(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getType(void)
|
||||
{
|
||||
if ( _bufLen == 0 )
|
||||
if (_bufLen == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -121,13 +117,13 @@ int MQTTSNPacket::getType(void)
|
||||
|
||||
bool MQTTSNPacket::isQoSMinusPUBLISH(void)
|
||||
{
|
||||
if ( _bufLen == 0 )
|
||||
if (_bufLen == 0)
|
||||
{
|
||||
return false;;
|
||||
}
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return ( (_buf[p] == MQTTSN_PUBLISH) && ((_buf[p + 1] & 0x60 ) == 0x60 ));
|
||||
return ((_buf[p] == MQTTSN_PUBLISH) && ((_buf[p + 1] & 0x60) == 0x60));
|
||||
}
|
||||
|
||||
unsigned char* MQTTSNPacket::getPacketData(void)
|
||||
@@ -149,8 +145,7 @@ int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration)
|
||||
{
|
||||
unsigned char buf[5];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid,
|
||||
(unsigned short) duration);
|
||||
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, (unsigned short) duration);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -167,14 +162,14 @@ int MQTTSNPacket::setConnect(void)
|
||||
unsigned char buf[40];
|
||||
int buflen = sizeof(buf);
|
||||
MQTTSNPacket_connectData data;
|
||||
data.clientID.cstring = (char*)"client01";
|
||||
data.clientID.cstring = (char*) "client01";
|
||||
int len = MQTTSNSerialize_connect(buf, buflen, &data);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
bool MQTTSNPacket::isAccepted(void)
|
||||
{
|
||||
return ( getType() == MQTTSN_CONNACK) && (_buf[2] == MQTTSN_RC_ACCEPTED);
|
||||
return (getType() == MQTTSN_CONNACK) && (_buf[2] == MQTTSN_RC_ACCEPTED);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setCONNACK(uint8_t returnCode)
|
||||
@@ -205,8 +200,7 @@ int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* to
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
topicName);
|
||||
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, topicName);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -214,18 +208,17 @@ int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic,
|
||||
uint8_t* payload, uint16_t payloadlen)
|
||||
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
|
||||
uint16_t payloadlen)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained,
|
||||
(unsigned short) msgId, topic, (unsigned char*) payload, (int) payloadlen);
|
||||
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, (unsigned short) msgId,
|
||||
topic, (unsigned char*) payload, (int) payloadlen);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -233,8 +226,7 @@ int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode
|
||||
{
|
||||
unsigned char buf[7];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -266,8 +258,8 @@ int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t r
|
||||
{
|
||||
unsigned char buf[8];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId,
|
||||
(unsigned short) msgId, (unsigned char) returnCode);
|
||||
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, (unsigned short) msgId,
|
||||
(unsigned char) returnCode);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -323,7 +315,7 @@ int MQTTSNPacket::setPINGREQ(MQTTSNString* clientId)
|
||||
{
|
||||
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
|
||||
int buflen = sizeof(buf);
|
||||
int len = MQTTSNSerialize_pingreq( buf, buflen, *clientId);
|
||||
int len = MQTTSNSerialize_pingreq(buf, buflen, *clientId);
|
||||
return desirialize(buf, len);
|
||||
}
|
||||
|
||||
@@ -354,26 +346,26 @@ int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
|
||||
|
||||
int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName)
|
||||
{
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_regack((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSN_topicid* topic,
|
||||
uint8_t** payload, int* payloadlen)
|
||||
{
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId,
|
||||
topic, (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, topic,
|
||||
(unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
|
||||
{
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode,
|
||||
_buf, _bufLen);
|
||||
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
|
||||
_bufLen);
|
||||
}
|
||||
|
||||
int MQTTSNPacket::getACK(uint16_t* msgId)
|
||||
@@ -394,7 +386,7 @@ int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter)
|
||||
|
||||
int MQTTSNPacket::getPINGREQ(void)
|
||||
{
|
||||
if (getType() == MQTTSN_PINGRESP && _bufLen > 2 )
|
||||
if (getType() == MQTTSN_PINGRESP && _bufLen > 2)
|
||||
{
|
||||
return _bufLen - 2;
|
||||
}
|
||||
@@ -405,7 +397,7 @@ int MQTTSNPacket::getDISCONNECT(uint16_t* duration)
|
||||
{
|
||||
int dur = 0;
|
||||
int rc = MQTTSNDeserialize_disconnect(&dur, _buf, _bufLen);
|
||||
*duration = (uint16_t)dur;
|
||||
*duration = (uint16_t) dur;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -439,11 +431,11 @@ char* MQTTSNPacket::getMsgId(char* pbuf)
|
||||
int value = 0;
|
||||
int p = 0;
|
||||
|
||||
switch ( getType() )
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
if ( _buf[p + 1] & 0x80 )
|
||||
if (_buf[p + 1] & 0x80)
|
||||
{
|
||||
sprintf(pbuf, "+%02X%02X", _buf[p + 4], _buf[p + 5]);
|
||||
}
|
||||
@@ -475,7 +467,7 @@ char* MQTTSNPacket::getMsgId(char* pbuf)
|
||||
sprintf(pbuf, " ");
|
||||
break;
|
||||
}
|
||||
if ( strcmp(pbuf, " 0000") == 0 )
|
||||
if (strcmp(pbuf, " 0000") == 0)
|
||||
{
|
||||
sprintf(pbuf, " ");
|
||||
}
|
||||
@@ -489,35 +481,35 @@ int MQTTSNPacket::getMsgId(void)
|
||||
int msgId = 0;
|
||||
char* ptr = 0;
|
||||
|
||||
switch ( getType() )
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*)_buf + p + 4;
|
||||
msgId = readInt((char**)&ptr);
|
||||
ptr = (char*) _buf + p + 4;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
ptr = (char*)_buf + 4;
|
||||
msgId = readInt((char**)&ptr);
|
||||
ptr = (char*) _buf + 4;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_PUBREC:
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
ptr = (char*)_buf + 2;
|
||||
msgId = readInt((char**)&ptr);
|
||||
ptr = (char*) _buf + 2;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
ptr = (char*)_buf + p + 2;
|
||||
msgId = readInt((char**)&ptr);
|
||||
ptr = (char*) _buf + p + 2;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
ptr = (char*)_buf + 5;
|
||||
msgId = readInt((char**)&ptr);
|
||||
ptr = (char*) _buf + 5;
|
||||
msgId = readInt((char**) &ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -531,20 +523,20 @@ void MQTTSNPacket::setMsgId(uint16_t msgId)
|
||||
int p = 0;
|
||||
//unsigned char* ptr = 0;
|
||||
|
||||
switch ( getType() )
|
||||
switch (getType())
|
||||
{
|
||||
case MQTTSN_PUBLISH:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 4] = (unsigned char)(msgId / 256);
|
||||
_buf[p + 5] = (unsigned char)(msgId % 256);
|
||||
_buf[p + 4] = (unsigned char) (msgId / 256);
|
||||
_buf[p + 5] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + p + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_PUBACK:
|
||||
case MQTTSN_REGISTER:
|
||||
case MQTTSN_REGACK:
|
||||
_buf[4] = (unsigned char)(msgId / 256);
|
||||
_buf[5] = (unsigned char)(msgId % 256);
|
||||
_buf[4] = (unsigned char) (msgId / 256);
|
||||
_buf[5] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 4;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
@@ -552,25 +544,25 @@ void MQTTSNPacket::setMsgId(uint16_t msgId)
|
||||
case MQTTSN_PUBREL:
|
||||
case MQTTSN_PUBCOMP:
|
||||
case MQTTSN_UNSUBACK:
|
||||
_buf[2] = (unsigned char)(msgId / 256);
|
||||
_buf[3] = (unsigned char)(msgId % 256);
|
||||
_buf[2] = (unsigned char) (msgId / 256);
|
||||
_buf[3] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
case MQTTSN_SUBSCRIBE:
|
||||
case MQTTSN_UNSUBSCRIBE:
|
||||
p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
_buf[p + 2] = (unsigned char)(msgId / 256);
|
||||
_buf[p + 3] = (unsigned char)(msgId % 256);
|
||||
_buf[p + 2] = (unsigned char) (msgId / 256);
|
||||
_buf[p + 3] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + p + 2;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
break;
|
||||
case MQTTSN_SUBACK:
|
||||
_buf[5] = (unsigned char)(msgId / 256);
|
||||
_buf[6] = (unsigned char)(msgId % 256);
|
||||
_buf[5] = (unsigned char) (msgId / 256);
|
||||
_buf[6] = (unsigned char) (msgId % 256);
|
||||
//ptr = _buf + 5;
|
||||
//writeInt(&ptr, msgId);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -580,5 +572,5 @@ bool MQTTSNPacket::isDuplicate(void)
|
||||
{
|
||||
int value = 0;
|
||||
int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
return ( _buf[p + 1] & 0x80 );
|
||||
return (_buf[p + 1] & 0x80);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
class SensorNetwork;
|
||||
|
||||
class MQTTSNPacket
|
||||
{
|
||||
@@ -53,7 +54,8 @@ public:
|
||||
int setPUBREC(uint16_t msgId);
|
||||
int setPUBREL(uint16_t msgId);
|
||||
int setPUBCOMP(uint16_t msgId);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode);
|
||||
int setSUBACK(int qos, uint16_t topicId, uint16_t msgId,
|
||||
uint8_t returnCode);
|
||||
int setUNSUBACK(uint16_t msgId);
|
||||
int setPINGRESP(void);
|
||||
int setDISCONNECT(uint16_t duration);
|
||||
@@ -66,19 +68,23 @@ public:
|
||||
int getSERCHGW(uint8_t* radius);
|
||||
int getCONNECT(MQTTSNPacket_connectData* option);
|
||||
int getCONNACK(uint8_t* returnCode);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLTOPIC(int* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSG(MQTTSNString* willmsg);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName);
|
||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId,
|
||||
MQTTSNString* topicName);
|
||||
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
||||
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
||||
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||
int getACK(uint16_t* msgId);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId,
|
||||
MQTTSN_topicid* topicFilter);
|
||||
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||
int getPINGREQ(void);
|
||||
int getDISCONNECT(uint16_t* duration);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain,
|
||||
MQTTSNString* willTopic);
|
||||
int getWILLMSGUPD(MQTTSNString* willMsg);
|
||||
|
||||
bool isAccepted(void);
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace MQTTSNGW;
|
||||
|
||||
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
|
||||
char* currentDateTime(void);
|
||||
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
@@ -45,7 +46,7 @@ char* currentDateTime(void);
|
||||
PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
{
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_gateway->attach((Thread*) this);
|
||||
_mqttConnection = new MQTTGWConnectionHandler(_gateway);
|
||||
_mqttPublish = new MQTTGWPublishHandler(_gateway);
|
||||
_mqttSubscribe = new MQTTGWSubscribeHandler(_gateway);
|
||||
@@ -54,6 +55,7 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
||||
|
||||
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
||||
setTaskName("PacketHandleTask");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,32 +63,32 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
||||
*/
|
||||
PacketHandleTask::~PacketHandleTask()
|
||||
{
|
||||
if ( _mqttConnection )
|
||||
if (_mqttConnection)
|
||||
{
|
||||
delete _mqttConnection;
|
||||
}
|
||||
if ( _mqttPublish )
|
||||
if (_mqttPublish)
|
||||
{
|
||||
delete _mqttPublish;
|
||||
}
|
||||
if ( _mqttSubscribe )
|
||||
if (_mqttSubscribe)
|
||||
{
|
||||
delete _mqttSubscribe;
|
||||
}
|
||||
if ( _mqttsnConnection )
|
||||
if (_mqttsnConnection)
|
||||
{
|
||||
delete _mqttsnConnection;
|
||||
}
|
||||
if ( _mqttsnPublish )
|
||||
if (_mqttsnPublish)
|
||||
{
|
||||
delete _mqttsnPublish;
|
||||
}
|
||||
if ( _mqttsnSubscribe )
|
||||
if (_mqttsnSubscribe)
|
||||
{
|
||||
delete _mqttsnSubscribe;
|
||||
}
|
||||
|
||||
if ( _mqttsnAggrConnection )
|
||||
if (_mqttsnAggrConnection)
|
||||
{
|
||||
delete _mqttsnAggrConnection;
|
||||
}
|
||||
@@ -113,7 +115,7 @@ void PacketHandleTask::run()
|
||||
|
||||
if (ev->getEventType() == EtStop)
|
||||
{
|
||||
WRITELOG("\n%s PacketHandleTask stopped.", currentDateTime());
|
||||
WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
|
||||
delete ev;
|
||||
return;
|
||||
}
|
||||
@@ -146,7 +148,7 @@ void PacketHandleTask::run()
|
||||
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the client.\n", snPacket->getName(), snPacket->getMsgId(msgId));
|
||||
|
||||
if ( adpMgr->isAggregatedClient(client) )
|
||||
if (adpMgr->isAggregatedClient(client))
|
||||
{
|
||||
aggregatePacketHandler(client, snPacket); // client is converted to Aggregater by BrokerSendTask
|
||||
}
|
||||
@@ -155,19 +157,17 @@ void PacketHandleTask::run()
|
||||
transparentPacketHandler(client, snPacket);
|
||||
}
|
||||
|
||||
|
||||
/* Reset the Timer for PINGREQ. */
|
||||
client->updateStatus(snPacket);
|
||||
}
|
||||
/*------ Handle Messages form Broker ---------*/
|
||||
else if ( ev->getEventType() == EtBrokerRecv )
|
||||
else if (ev->getEventType() == EtBrokerRecv)
|
||||
{
|
||||
client = ev->getClient();
|
||||
brPacket = ev->getMQTTGWPacket();
|
||||
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
||||
|
||||
|
||||
if ( client->isAggregater() )
|
||||
if (client->isAggregater())
|
||||
{
|
||||
aggregatePacketHandler(client, brPacket);
|
||||
}
|
||||
@@ -180,8 +180,6 @@ void PacketHandleTask::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
@@ -239,7 +237,6 @@ void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
@@ -333,7 +330,6 @@ void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* pac
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
|
||||
{
|
||||
switch (packet->getType())
|
||||
|
||||
@@ -42,9 +42,9 @@ class Timer;
|
||||
/*=====================================
|
||||
Class PacketHandleTask
|
||||
=====================================*/
|
||||
class PacketHandleTask : public Thread
|
||||
class PacketHandleTask: public Thread
|
||||
{
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
MAGIC_WORD_FOR_THREAD;
|
||||
friend class MQTTGWAggregatePublishHandler;
|
||||
friend class MQTTGWAggregateSubscribeHandler;
|
||||
friend class MQTTSNAggregateConnectionHandler;
|
||||
@@ -60,20 +60,19 @@ private:
|
||||
void transparentPacketHandler(Client*client, MQTTSNPacket* packet);
|
||||
void transparentPacketHandler(Client*client, MQTTGWPacket* packet);
|
||||
|
||||
Gateway* _gateway {nullptr};
|
||||
Gateway* _gateway
|
||||
{ nullptr };
|
||||
Timer _advertiseTimer;
|
||||
Timer _sendUnixTimer;
|
||||
MQTTGWConnectionHandler* _mqttConnection {nullptr};
|
||||
MQTTGWPublishHandler* _mqttPublish {nullptr};
|
||||
MQTTGWSubscribeHandler* _mqttSubscribe {nullptr};
|
||||
MQTTSNConnectionHandler* _mqttsnConnection {nullptr};
|
||||
MQTTSNPublishHandler* _mqttsnPublish {nullptr};
|
||||
MQTTSNSubscribeHandler* _mqttsnSubscribe {nullptr};
|
||||
|
||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection {nullptr};
|
||||
MQTTGWConnectionHandler* _mqttConnection { nullptr };
|
||||
MQTTGWPublishHandler* _mqttPublish { nullptr };
|
||||
MQTTGWSubscribeHandler* _mqttSubscribe { nullptr };
|
||||
MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
|
||||
MQTTSNPublishHandler* _mqttsnPublish { nullptr };
|
||||
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
|
||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
* Contributors:
|
||||
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||
**************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <Timer.h>
|
||||
@@ -57,15 +57,17 @@ Process::Process()
|
||||
_configDir = CONFIG_DIRECTORY;
|
||||
_configFile = CONFIG_FILE;
|
||||
_log = 0;
|
||||
_rbsem = NULL;
|
||||
_rb = NULL;
|
||||
}
|
||||
|
||||
Process::~Process()
|
||||
{
|
||||
if (_rb )
|
||||
if (_rb)
|
||||
{
|
||||
delete _rb;
|
||||
}
|
||||
if ( _rbsem )
|
||||
if (_rbsem)
|
||||
{
|
||||
delete _rbsem;
|
||||
}
|
||||
@@ -88,17 +90,17 @@ void Process::initialize(int argc, char** argv)
|
||||
int opt;
|
||||
while ((opt = getopt(_argc, _argv, "f:")) != -1)
|
||||
{
|
||||
if ( opt == 'f' )
|
||||
if (opt == 'f')
|
||||
{
|
||||
string config = string(optarg);
|
||||
size_t pos = 0;
|
||||
if ( (pos = config.find_last_of("/")) == string::npos )
|
||||
if ((pos = config.find_last_of("/")) == string::npos)
|
||||
{
|
||||
_configFile = optarg;
|
||||
}
|
||||
else
|
||||
{
|
||||
_configFile = config.substr(pos + 1, config.size() - pos - 1);;
|
||||
_configFile = config.substr(pos + 1, config.size() - pos - 1);
|
||||
_configDir = config.substr(0, pos + 1);
|
||||
}
|
||||
}
|
||||
@@ -128,7 +130,7 @@ void Process::putLog(const char* format, ...)
|
||||
va_end(arg);
|
||||
if (strlen(_rbdata))
|
||||
{
|
||||
if ( _log > 0 )
|
||||
if (_log > 0)
|
||||
{
|
||||
_rb->put(_rbdata);
|
||||
_rbsem->post();
|
||||
@@ -155,6 +157,8 @@ int Process::getParam(const char* parameter, char* value)
|
||||
{
|
||||
char str[MQTTSNGW_PARAM_MAX];
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
memset(str, 0, sizeof(str));
|
||||
memset(param, 0, sizeof(param));
|
||||
FILE *fp;
|
||||
|
||||
int i = 0, j = 0;
|
||||
@@ -162,27 +166,41 @@ int Process::getParam(const char* parameter, char* value)
|
||||
|
||||
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
||||
{
|
||||
throw Exception("No config file:[" + configPath + "]\n");
|
||||
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
|
||||
}
|
||||
|
||||
int paramlen = strlen(parameter);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return -3;
|
||||
}
|
||||
if (!strncmp(str, parameter, strlen(parameter)))
|
||||
if (str[0] == '#' || str[0] == '\n')
|
||||
{
|
||||
while (str[i++] != '=')
|
||||
{
|
||||
;
|
||||
continue;
|
||||
}
|
||||
while (str[i] != '\n')
|
||||
|
||||
len = strlen(str);
|
||||
for (pos = 0; i < len; pos++)
|
||||
{
|
||||
param[j++] = str[i++];
|
||||
if (str[pos] == '=')
|
||||
{
|
||||
break;
|
||||
}
|
||||
param[j] = '\0';
|
||||
}
|
||||
|
||||
if (pos == paramlen)
|
||||
{
|
||||
if (strncmp(str, parameter, paramlen) == 0)
|
||||
{
|
||||
strcpy(param, str + pos + 1);
|
||||
param[len - pos - 2] = '\0';
|
||||
|
||||
|
||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||
;
|
||||
@@ -201,6 +219,7 @@ int Process::getParam(const char* parameter, char* value)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return -2;
|
||||
}
|
||||
@@ -212,7 +231,7 @@ const char* Process::getLog()
|
||||
while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0)
|
||||
{
|
||||
_rbsem->timedwait(1000);
|
||||
if ( checkSignal() == SIGINT)
|
||||
if (checkSignal() == SIGINT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -277,9 +296,7 @@ void MultiTaskProcess::run(void)
|
||||
_threadList[i]->start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
if (theProcess->checkSignal() == SIGINT)
|
||||
{
|
||||
@@ -287,15 +304,6 @@ void MultiTaskProcess::run(void)
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
catch(Exception* ex)
|
||||
{
|
||||
ex->writeMessage();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskProcess::waitStop(void)
|
||||
@@ -314,6 +322,11 @@ void MultiTaskProcess::threadStopped(void)
|
||||
|
||||
}
|
||||
|
||||
void MultiTaskProcess::abort(void)
|
||||
{
|
||||
signalHandler(SIGINT);
|
||||
}
|
||||
|
||||
void MultiTaskProcess::attach(Thread* thread)
|
||||
{
|
||||
_mutex.lock();
|
||||
@@ -325,7 +338,7 @@ void MultiTaskProcess::attach(Thread* thread)
|
||||
else
|
||||
{
|
||||
_mutex.unlock();
|
||||
throw Exception("Full of Threads");
|
||||
throw Exception("The maximum number of threads has been exceeded.", -1);
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
@@ -335,40 +348,26 @@ int MultiTaskProcess::getParam(const char* parameter, char* value)
|
||||
_mutex.lock();
|
||||
int rc = Process::getParam(parameter, value);
|
||||
_mutex.unlock();
|
||||
if (rc == -1)
|
||||
{
|
||||
throw Exception("No config file.");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class Exception
|
||||
======================================*/
|
||||
Exception::Exception(const string& message)
|
||||
Exception::Exception(const char* message, const int errNo)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = 0;
|
||||
_fileName = 0;
|
||||
_functionName = 0;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_errNo = errNo;
|
||||
_fileName = nullptr;
|
||||
_functionName = nullptr;
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
Exception::Exception(const int exNo, const string& message, const char* file,
|
||||
const char* function, const int line)
|
||||
Exception::Exception(const char* message, const int errNo, const char* file, const char* function, const int line)
|
||||
{
|
||||
_message = message;
|
||||
_exNo = exNo;
|
||||
_fileName = file;
|
||||
_errNo = errNo;
|
||||
_fileName = getFileName(file);
|
||||
;
|
||||
_functionName = function;
|
||||
_line = line;
|
||||
}
|
||||
@@ -380,7 +379,7 @@ Exception::~Exception() throw ()
|
||||
|
||||
const char* Exception::what() const throw ()
|
||||
{
|
||||
return _message.c_str();
|
||||
return _message;
|
||||
}
|
||||
|
||||
const char* Exception::getFileName()
|
||||
@@ -398,20 +397,49 @@ const int Exception::getLineNo()
|
||||
return _line;
|
||||
}
|
||||
|
||||
const int Exception::getExceptionNo()
|
||||
const int Exception::getErrNo()
|
||||
{
|
||||
return _exNo;
|
||||
return _errNo;
|
||||
}
|
||||
|
||||
void Exception::writeMessage()
|
||||
{
|
||||
if (getExceptionNo() == 0 )
|
||||
if (_fileName == nullptr)
|
||||
{
|
||||
WRITELOG("%s %s\n", currentDateTime(), what());
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(),
|
||||
getFileName(), getLineNo(), getFunctionName(), what());
|
||||
WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message, _errNo,
|
||||
strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_errNo == 0)
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()%s\n", currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName,
|
||||
CLR_HDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message,
|
||||
_fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* Exception::getFileName(const char* file)
|
||||
{
|
||||
for (int len = strlen(file); len > 0; len--)
|
||||
{
|
||||
if (*(file + len) == '/')
|
||||
{
|
||||
return file + len + 1;
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace MQTTSNGW
|
||||
#define WRITELOG theProcess->putLog
|
||||
#define CHK_SIGINT (theProcess->checkSignal() == SIGINT)
|
||||
#define UNUSED(x) ((void)(x))
|
||||
#define EXCEPTION(...) Exception(__VA_ARGS__, __FILE__, __func__, __LINE__)
|
||||
|
||||
/*=================================
|
||||
Class Process
|
||||
==================================*/
|
||||
@@ -86,6 +88,7 @@ public:
|
||||
void waitStop(void);
|
||||
void threadStopped(void);
|
||||
void attach(Thread* thread);
|
||||
void abort(void);
|
||||
|
||||
private:
|
||||
Thread* _threadList[MQTTSNGW_MAX_TASK];
|
||||
@@ -100,27 +103,25 @@ private:
|
||||
class Exception: public exception
|
||||
{
|
||||
public:
|
||||
Exception(const string& message);
|
||||
Exception(const int exNo, const string& message);
|
||||
Exception(const int exNo, const string& message,
|
||||
const char* file, const char* func, const int line);
|
||||
Exception(const char* message, const int errNo);
|
||||
Exception(const char* message, const int errNo, const char* file, const char* func, int line);
|
||||
virtual ~Exception() throw ();
|
||||
const char* getFileName();
|
||||
const char* getFunctionName();
|
||||
const int getLineNo();
|
||||
const int getExceptionNo();
|
||||
const int getErrNo();
|
||||
virtual const char* what() const throw ();
|
||||
void writeMessage();
|
||||
|
||||
private:
|
||||
int _exNo;
|
||||
string _message;
|
||||
const char* getFileName(const char* file);
|
||||
int _errNo;
|
||||
const char* _message;
|
||||
const char* _fileName;
|
||||
const char* _functionName;
|
||||
int _line;
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class QueElement
|
||||
====================================*/
|
||||
@@ -175,10 +176,10 @@ public:
|
||||
|
||||
void pop(void)
|
||||
{
|
||||
if ( _head )
|
||||
if (_head)
|
||||
{
|
||||
QueElement<T>* head = _head;
|
||||
if ( _head == _tail )
|
||||
if (_head == _tail)
|
||||
{
|
||||
_head = _tail = nullptr;
|
||||
}
|
||||
@@ -195,7 +196,7 @@ public:
|
||||
T* front(void)
|
||||
{
|
||||
{
|
||||
if ( _head )
|
||||
if (_head)
|
||||
{
|
||||
return _head->_element;
|
||||
}
|
||||
@@ -208,12 +209,12 @@ public:
|
||||
|
||||
int post(T* t)
|
||||
{
|
||||
if ( t && ( _maxSize == 0 || _cnt < _maxSize ))
|
||||
if (t && (_maxSize == 0 || _cnt < _maxSize))
|
||||
{
|
||||
QueElement<T>* elm = new QueElement<T>(t);
|
||||
if ( _head )
|
||||
if (_head)
|
||||
{
|
||||
if ( _tail == _head )
|
||||
if (_tail == _head)
|
||||
{
|
||||
elm->_prev = _tail;
|
||||
_tail = elm;
|
||||
@@ -262,8 +263,9 @@ private:
|
||||
#define TREE23_BI_NODE (2)
|
||||
#define TREE23_TRI_NODE (3)
|
||||
|
||||
template <typename K, typename V>
|
||||
class Tree23Elm{
|
||||
template<typename K, typename V>
|
||||
class Tree23Elm
|
||||
{
|
||||
template<typename T, typename U> friend class Tree23;
|
||||
public:
|
||||
Tree23Elm()
|
||||
@@ -292,9 +294,9 @@ private:
|
||||
V* _val;
|
||||
};
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
class Tree23Node{
|
||||
template<typename K, typename V>
|
||||
class Tree23Node
|
||||
{
|
||||
template<typename S, typename W> friend class Tree23;
|
||||
public:
|
||||
Tree23Node(const int type)
|
||||
@@ -320,7 +322,8 @@ public:
|
||||
_left = _midle = _right = NULL;
|
||||
}
|
||||
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left, Tree23Node<K, V>* right)
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left,
|
||||
Tree23Node<K, V>* right)
|
||||
{
|
||||
_type = type;
|
||||
_telm0 = telm;
|
||||
@@ -330,7 +333,9 @@ public:
|
||||
_right = right;
|
||||
}
|
||||
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1, Tree23Node<K, V>* left, Tree23Node<K, V>* midle, Tree23Node<K, V>* right)
|
||||
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1,
|
||||
Tree23Node<K, V>* left, Tree23Node<K, V>* midle,
|
||||
Tree23Node<K, V>* right)
|
||||
{
|
||||
_type = type;
|
||||
_telm0 = telm0;
|
||||
@@ -354,8 +359,9 @@ private:
|
||||
Tree23Node<K, V>* _right;
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class Tree23{
|
||||
template<typename K, typename V>
|
||||
class Tree23
|
||||
{
|
||||
public:
|
||||
Tree23()
|
||||
{
|
||||
@@ -364,7 +370,7 @@ public:
|
||||
|
||||
~Tree23()
|
||||
{
|
||||
if ( _root )
|
||||
if (_root)
|
||||
{
|
||||
delete _root;
|
||||
}
|
||||
@@ -372,28 +378,28 @@ public:
|
||||
|
||||
void add(K* key, V* val)
|
||||
{
|
||||
_root = add( _root, new Tree23Elm<K, V>(key, val));
|
||||
_root = add(_root, new Tree23Elm<K, V>(key, val));
|
||||
_root->_type = abs(_root->_type);
|
||||
}
|
||||
|
||||
Tree23Node<K, V>* add(Tree23Node<K, V>* n, Tree23Elm<K, V>* elm)
|
||||
{
|
||||
if ( n == 0 )
|
||||
if (n == 0)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, elm);
|
||||
}
|
||||
|
||||
int cmp0 = elm->compare(n->_telm0);
|
||||
int cmp1 = 0;
|
||||
switch ( n->_type )
|
||||
switch (n->_type)
|
||||
{
|
||||
case 2:
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
n->_left = add(n->_left, elm);
|
||||
return addLeft2(n);
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
n->_telm0 = elm;
|
||||
return n;
|
||||
@@ -406,22 +412,22 @@ public:
|
||||
break;
|
||||
case 3:
|
||||
cmp1 = elm->compare(n->_telm1);
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
n->_left = add(n->_left, elm);
|
||||
return addLeft3(n);
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
n->_telm0 = elm;
|
||||
return n;
|
||||
}
|
||||
else if ( cmp1 < 0 )
|
||||
else if (cmp1 < 0)
|
||||
{
|
||||
n->_midle = add(n->_midle, elm);
|
||||
return addMidle3(n);
|
||||
}
|
||||
else if ( cmp1 == 0 )
|
||||
else if (cmp1 == 0)
|
||||
{
|
||||
n->_telm1 = elm;
|
||||
return n;
|
||||
@@ -441,7 +447,7 @@ public:
|
||||
void remove(K* k)
|
||||
{
|
||||
_root = remove(_root, k);
|
||||
if ( _root != NULL && _root->_type == TREE23_DELETE_ACTIVE )
|
||||
if (_root != NULL && _root->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
_root = _root->_midle;
|
||||
}
|
||||
@@ -449,23 +455,23 @@ public:
|
||||
|
||||
Tree23Node<K, V>* remove(Tree23Node<K, V>* node, K* k)
|
||||
{
|
||||
if ( node == NULL )
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int cmp0 = k->compare(node->_telm0->_key);
|
||||
int cmp1 = 0;
|
||||
switch ( node->_type )
|
||||
switch (node->_type)
|
||||
{
|
||||
case 2:
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
node->_left = remove( node->_left, k);
|
||||
node->_left = remove(node->_left, k);
|
||||
return removeLeft2(node);
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
if ( node->_left == NULL)
|
||||
if (node->_left == NULL)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_DELETE_ACTIVE);
|
||||
}
|
||||
@@ -481,14 +487,14 @@ public:
|
||||
}
|
||||
case 3:
|
||||
cmp1 = k->compare(node->_telm1->_key);
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
node->_left = remove(node->_left, k);
|
||||
return removeLeft3(node);
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
if ( node->_left == NULL )
|
||||
if (node->_left == NULL)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1);
|
||||
}
|
||||
@@ -497,14 +503,14 @@ public:
|
||||
node->_telm0 = maxLeft;
|
||||
return removeLeft3(node);
|
||||
}
|
||||
else if ( cmp1 < 0 )
|
||||
else if (cmp1 < 0)
|
||||
{
|
||||
node->_midle = remove(node->_midle, k);
|
||||
return removeMidle3(node);
|
||||
}
|
||||
else if ( cmp1 == 0 )
|
||||
else if (cmp1 == 0)
|
||||
{
|
||||
if ( node->_midle == NULL )
|
||||
if (node->_midle == NULL)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0);
|
||||
}
|
||||
@@ -534,8 +540,9 @@ public:
|
||||
switch (node->_type)
|
||||
{
|
||||
case 2:
|
||||
if ( cmp0 < 0 ) node = node->_left;
|
||||
else if ( cmp0 == 0 )
|
||||
if (cmp0 < 0)
|
||||
node = node->_left;
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -546,19 +553,19 @@ public:
|
||||
break;
|
||||
case 3:
|
||||
cmp1 = key->compare(node->_telm1->_key);
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
node = node->_left;
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( cmp1 < 0 )
|
||||
else if (cmp1 < 0)
|
||||
{
|
||||
node = node->_midle;
|
||||
}
|
||||
else if ( cmp1 == 0 )
|
||||
else if (cmp1 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -574,7 +581,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
V* getVal(K* key)
|
||||
{
|
||||
Tree23Node<K, V>* node = _root;
|
||||
@@ -585,11 +591,11 @@ public:
|
||||
switch (node->_type)
|
||||
{
|
||||
case 2:
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
node = node->_left;
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
return node->_telm0->_val;
|
||||
}
|
||||
@@ -600,19 +606,19 @@ public:
|
||||
break;
|
||||
case 3:
|
||||
cmp1 = key->compare(node->_telm1->_key);
|
||||
if ( cmp0 < 0 )
|
||||
if (cmp0 < 0)
|
||||
{
|
||||
node = node->_left;
|
||||
}
|
||||
else if ( cmp0 == 0 )
|
||||
else if (cmp0 == 0)
|
||||
{
|
||||
return node->_telm0->_val;
|
||||
}
|
||||
else if ( cmp1 < 0 )
|
||||
else if (cmp1 < 0)
|
||||
{
|
||||
node = node->_midle;
|
||||
}
|
||||
else if ( cmp1 == 0 )
|
||||
else if (cmp1 == 0)
|
||||
{
|
||||
return node->_telm1->_val;
|
||||
}
|
||||
@@ -632,9 +638,10 @@ private:
|
||||
Tree23Node<K, V>* addLeft2(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
if ( n != NULL && n->_type == TREE23_INSERT_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, n->_telm0, node->_telm0, n->_left, n->_right, node->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, n->_telm0,
|
||||
node->_telm0, n->_left, n->_right, node->_right);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -642,11 +649,13 @@ private:
|
||||
Tree23Node<K, V>* addLeft3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
if ( n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_type = TREE23_BI_NODE;
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, node->_midle, node->_right);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n, nn);
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||
node->_telm1, node->_midle, node->_right);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n,
|
||||
nn);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -656,7 +665,8 @@ private:
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, n->_telm0, node->_left, n->_left, n->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
n->_telm0, node->_left, n->_left, n->_right);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -664,10 +674,13 @@ private:
|
||||
Tree23Node<K, V>* addRight3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE) {
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_type = TREE23_BI_NODE;
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, node->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn, n);
|
||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||
node->_telm0, node->_left, node->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn,
|
||||
n);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -675,16 +688,17 @@ private:
|
||||
Tree23Node<K, V>* addMidle3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_midle;
|
||||
if ( n != NULL && n->_type == TREE23_INSERT_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||
{
|
||||
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, n->_left);
|
||||
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_right, node->_right);
|
||||
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
node->_left, n->_left);
|
||||
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
n->_right, node->_right);
|
||||
return n;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* removeMax(Tree23Node<K, V>* node, Tree23Elm<K, V>* elm)
|
||||
{
|
||||
if (node->_right == NULL)
|
||||
@@ -719,26 +733,29 @@ private:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* removeLeft2(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
if ( n != NULL && n->_type == TREE23_DELETE_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
Tree23Node<K, V>* r = node->_right;
|
||||
Tree23Node<K, V>* midle;
|
||||
Tree23Node<K, V>* left;
|
||||
Tree23Node<K, V>* right;
|
||||
|
||||
switch ( r->_type )
|
||||
switch (r->_type)
|
||||
{
|
||||
case 2:
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, n->_midle, r->_left, r->_right);
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_DELETE_ACTIVE, midle);
|
||||
case 3:
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left, right);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||
r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left,
|
||||
right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -749,7 +766,7 @@ private:
|
||||
Tree23Node<K, V>* removeRight2(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if ( n != NULL && n->_type == TREE23_DELETE_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
Tree23Node<K, V>* l = node->_left;
|
||||
Tree23Node<K, V>* midle;
|
||||
@@ -759,12 +776,16 @@ private:
|
||||
switch (l->_type)
|
||||
{
|
||||
case 2:
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0, node->_telm0, l->_left, l->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0,
|
||||
node->_telm0, l->_left, l->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(-1, midle);
|
||||
case 3:
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l->_right, n->_midle);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left, l->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left, right);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
l->_right, n->_midle);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left,
|
||||
l->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left,
|
||||
right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -775,21 +796,27 @@ private:
|
||||
Tree23Node<K, V>* removeLeft3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_left;
|
||||
if ( n != NULL && n->_type == TREE23_DELETE_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
Tree23Node<K, V>* m = node->_midle;
|
||||
Tree23Node<K, V>* r = node->_right;
|
||||
Tree23Node<K, V>* left;
|
||||
Tree23Node<K, V>* midle;
|
||||
|
||||
switch (m->_type) {
|
||||
switch (m->_type)
|
||||
{
|
||||
case 2:
|
||||
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm0, n->_midle, m->_left, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left, r);
|
||||
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
m->_telm0, n->_midle, m->_left, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left,
|
||||
r);
|
||||
case 3:
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, m->_left);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1, m->_midle, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, left, midle, r);
|
||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||
n->_midle, m->_left);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1,
|
||||
m->_midle, m->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||
node->_telm1, left, midle, r);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -800,7 +827,7 @@ private:
|
||||
Tree23Node<K, V>* removeMidle3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_midle;
|
||||
if ( n != NULL && n->_type == TREE23_DELETE_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
Tree23Node<K, V>* l = node->_left;
|
||||
Tree23Node<K, V>* r = node->_right;
|
||||
@@ -809,12 +836,17 @@ private:
|
||||
switch (r->_type)
|
||||
{
|
||||
case 2:
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1, r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1,
|
||||
r->_telm0, n->_midle, r->_left, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||
right);
|
||||
case 3:
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, l, midle, right);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
n->_midle, r->_left);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||
r->_midle, r->_right);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
r->_telm0, l, midle, right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -825,7 +857,7 @@ private:
|
||||
Tree23Node<K, V>* removeRight3(Tree23Node<K, V>* node)
|
||||
{
|
||||
Tree23Node<K, V>* n = node->_right;
|
||||
if ( n != NULL && n->_type == TREE23_DELETE_ACTIVE )
|
||||
if (n != NULL && n->_type == TREE23_DELETE_ACTIVE)
|
||||
{
|
||||
Tree23Node<K, V>* l = node->_left;
|
||||
Tree23Node<K, V>* m = node->_midle;
|
||||
@@ -834,12 +866,17 @@ private:
|
||||
switch (m->_type)
|
||||
{
|
||||
case 2:
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, m->_left, m->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||
node->_telm1, m->_left, m->_right, n->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||
right);
|
||||
case 3:
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, m->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0, m->_left, m->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm1, l, midle, right);
|
||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||
m->_right, n->_midle);
|
||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0,
|
||||
m->_left, m->_midle);
|
||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||
m->_telm1, l, midle, right);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -847,14 +884,13 @@ private:
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
Tree23Node<K, V>* _root;
|
||||
};
|
||||
|
||||
/*=====================================
|
||||
Class List
|
||||
=====================================*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class ListElm
|
||||
{
|
||||
template<typename U> friend class List;
|
||||
@@ -873,18 +909,23 @@ public:
|
||||
{
|
||||
return _elm;
|
||||
}
|
||||
~ListElm(){}
|
||||
~ListElm()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
ListElm<T>* getNext(void){return _next;}
|
||||
ListElm<T>* getNext(void)
|
||||
{
|
||||
return _next;
|
||||
}
|
||||
T* _elm;
|
||||
ListElm<T>* _prev;
|
||||
ListElm<T>* _next;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class List{
|
||||
template<typename T>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
List()
|
||||
{
|
||||
@@ -899,11 +940,11 @@ public:
|
||||
int add(T* t)
|
||||
{
|
||||
ListElm<T>* elm = new ListElm<T>(t);
|
||||
if ( elm == nullptr )
|
||||
if (elm == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( _head == nullptr )
|
||||
if (_head == nullptr)
|
||||
{
|
||||
_head = elm;
|
||||
_tail = elm;
|
||||
@@ -920,13 +961,13 @@ public:
|
||||
|
||||
void erase(ListElm<T>* elm)
|
||||
{
|
||||
if ( _head == elm )
|
||||
if (_head == elm)
|
||||
{
|
||||
_head = elm->_next;
|
||||
_size--;
|
||||
delete elm;
|
||||
}
|
||||
else if ( _tail == elm )
|
||||
else if (_tail == elm)
|
||||
{
|
||||
_tail = elm->_prev;
|
||||
elm->_prev->_next = nullptr;
|
||||
@@ -944,7 +985,7 @@ public:
|
||||
void clear(void)
|
||||
{
|
||||
ListElm<T>* p = _head;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
ListElm<T>* q = p->_next;
|
||||
delete p;
|
||||
@@ -970,14 +1011,12 @@ public:
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ListElm<T>* _head;
|
||||
ListElm<T>* _tail;
|
||||
int _size;
|
||||
};
|
||||
|
||||
|
||||
extern Process* theProcess;
|
||||
extern MultiTaskProcess* theMultiTaskProcess;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
int qos;
|
||||
uint8_t retained;
|
||||
uint16_t msgId;
|
||||
uint16_t tid;
|
||||
uint8_t* payload;
|
||||
MQTTSN_topicid topicid;
|
||||
int payloadlen;
|
||||
@@ -48,9 +49,9 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
|
||||
char shortTopic[2];
|
||||
|
||||
if ( !_gateway->getAdapterManager()->getQoSm1Proxy()->isActive() )
|
||||
if (!_gateway->getAdapterManager()->getQoSm1Proxy()->isActive())
|
||||
{
|
||||
if ( client->isQoSm1() )
|
||||
if (client->isQoSm1())
|
||||
{
|
||||
_gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, packet);
|
||||
|
||||
@@ -58,18 +59,19 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
}
|
||||
}
|
||||
|
||||
if ( packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) ==0 )
|
||||
if (packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
pub.msgId = msgId;
|
||||
pub.header.bits.dup = dup;
|
||||
pub.header.bits.qos = ( qos == 3 ? 0 : qos );
|
||||
pub.header.bits.qos = (qos == 3 ? 0 : qos);
|
||||
pub.header.bits.retain = retained;
|
||||
tid = topicid.data.id;
|
||||
|
||||
Topic* topic = nullptr;
|
||||
|
||||
if( topicid.type == MQTTSN_TOPIC_TYPE_SHORT )
|
||||
if (topicid.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
shortTopic[0] = topicid.data.short_name[0];
|
||||
shortTopic[1] = topicid.data.short_name[1];
|
||||
@@ -79,56 +81,58 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
||||
else
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicid);
|
||||
if ( !topic )
|
||||
if (!topic)
|
||||
{
|
||||
topic = _gateway->getTopics()->getTopicById(&topicid);
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
}
|
||||
}
|
||||
|
||||
if( !topic && qos == 3 )
|
||||
if (!topic && qos == 3)
|
||||
{
|
||||
WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( ( qos == 0 || qos == 3 ) && msgId > 0 )
|
||||
if ((qos == 0 || qos == 3) && msgId > 0)
|
||||
{
|
||||
WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( !topic && msgId && qos > 0 && qos < 3 )
|
||||
if (!topic && msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
/* Reply PubAck with INVALID_TOPIC_ID to the client */
|
||||
MQTTSNPacket* pubAck = new MQTTSNPacket();
|
||||
pubAck->setPUBACK( topicid.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
pubAck->setPUBACK(topicid.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
Event* ev1 = new Event();
|
||||
ev1->setClientSendEvent(client, pubAck);
|
||||
_gateway->getClientSendQue()->post(ev1);
|
||||
return nullptr;
|
||||
}
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
pub.topic = (char*)topic->getTopicName()->data();
|
||||
pub.topic = (char*) topic->getTopicName()->data();
|
||||
pub.topiclen = topic->getTopicName()->length();
|
||||
topicid.data.long_.name = pub.topic;
|
||||
topicid.data.long_.len = pub.topiclen;
|
||||
}
|
||||
}
|
||||
/* Save a msgId & a TopicId pare for PUBACK */
|
||||
if( msgId && qos > 0 && qos < 3)
|
||||
if (msgId && qos > 0 && qos < 3)
|
||||
{
|
||||
client->setWaitedPubTopicId(msgId, topicid.data.id, topicid.type);
|
||||
client->setWaitedPubTopicId(msgId, tid, &topicid);
|
||||
}
|
||||
|
||||
pub.payload = (char*)payload;
|
||||
pub.payload = (char*) payload;
|
||||
pub.payloadlen = payloadlen;
|
||||
|
||||
MQTTGWPacket* publish = new MQTTGWPacket();
|
||||
publish->setPUBLISH(&pub);
|
||||
|
||||
if ( _gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated() )
|
||||
if (_gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated())
|
||||
{
|
||||
return publish;
|
||||
}
|
||||
@@ -147,16 +151,16 @@ void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet)
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
|
||||
if ( client->isActive() )
|
||||
if (client->isActive())
|
||||
{
|
||||
if ( packet->getPUBACK(&topicId, &msgId, &rc) == 0 )
|
||||
if (packet->getPUBACK(&topicId, &msgId, &rc) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( rc == MQTTSN_RC_ACCEPTED)
|
||||
if (rc == MQTTSN_RC_ACCEPTED)
|
||||
{
|
||||
if ( !_gateway->getAdapterManager()->getAggregater()->isActive() )
|
||||
if (!_gateway->getAdapterManager()->getAggregater()->isActive())
|
||||
{
|
||||
MQTTGWPacket* pubAck = new MQTTGWPacket();
|
||||
pubAck->setAck(PUBACK, msgId);
|
||||
@@ -165,7 +169,7 @@ void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet)
|
||||
_gateway->getBrokerSendQue()->post(ev1);
|
||||
}
|
||||
}
|
||||
else if ( rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
|
||||
else if (rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
|
||||
{
|
||||
WRITELOG(" PUBACK %d : Invalid Topic ID\n", msgId);
|
||||
}
|
||||
@@ -176,9 +180,9 @@ void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8
|
||||
{
|
||||
uint16_t msgId;
|
||||
|
||||
if ( client->isActive() )
|
||||
if (client->isActive())
|
||||
{
|
||||
if ( packet->getACK(&msgId) == 0 )
|
||||
if (packet->getACK(&msgId) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -194,12 +198,13 @@ void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;;
|
||||
MQTTSNString topicName = MQTTSNString_initializer;
|
||||
;
|
||||
MQTTSN_topicid topicid;
|
||||
|
||||
if ( client->isActive() || client->isAwake())
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
if ( packet->getREGISTER(&id, &msgId, &topicName) == 0 )
|
||||
if (packet->getREGISTER(&id, &msgId, &topicName) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -218,28 +223,30 @@ void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
||||
}
|
||||
}
|
||||
|
||||
void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
void MQTTSNPublishHandler::handleRegAck(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t msgId;
|
||||
uint8_t rc;
|
||||
if ( client->isActive() || client->isAwake())
|
||||
if (client->isActive() || client->isAwake())
|
||||
{
|
||||
if ( packet->getREGACK(&id, &msgId, &rc) == 0 )
|
||||
if (packet->getREGACK(&id, &msgId, &rc) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* get PUBLISH message */
|
||||
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
|
||||
|
||||
if ( regAck != nullptr )
|
||||
if (regAck != nullptr)
|
||||
{
|
||||
client->getWaitREGACKPacketList()->erase(msgId);
|
||||
Event* ev = new Event();
|
||||
ev->setClientSendEvent(client, regAck);
|
||||
_gateway->getClientSendQue()->post(ev);
|
||||
}
|
||||
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0 )
|
||||
|
||||
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0)
|
||||
{
|
||||
/* send PINGREQ to the broker */
|
||||
client->resetPingRequest();
|
||||
@@ -253,18 +260,15 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
int msgId = 0;
|
||||
MQTTGWPacket* publish = handlePublish(client, packet);
|
||||
if ( publish != nullptr )
|
||||
if (publish != nullptr)
|
||||
{
|
||||
if ( publish->getMsgId() > 0 )
|
||||
if (publish->getMsgId() > 0)
|
||||
{
|
||||
if ( packet->isDuplicate() )
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
@@ -282,11 +286,11 @@ void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket*
|
||||
|
||||
void MQTTSNPublishHandler::handleAggregateAck(Client* client, MQTTSNPacket* packet, int type)
|
||||
{
|
||||
if ( type == MQTTSN_PUBREC )
|
||||
if (type == MQTTSN_PUBREC)
|
||||
{
|
||||
uint16_t msgId;
|
||||
|
||||
if ( packet->getACK(&msgId) == 0 )
|
||||
if (packet->getACK(&msgId) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
void handlePuback(Client* client, MQTTSNPacket* packet);
|
||||
void handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType);
|
||||
void handleRegister(Client* client, MQTTSNPacket* packet);
|
||||
void handleRegAck( Client* client, MQTTSNPacket* packet);
|
||||
void handleRegAck(Client* client, MQTTSNPacket* packet);
|
||||
|
||||
void handleAggregatePublish(Client* client, MQTTSNPacket* packet);
|
||||
void handleAggregateAck(Client* client, MQTTSNPacket* packet, int type);
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
/*=====================================
|
||||
Class QoSm1Proxy
|
||||
=====================================*/
|
||||
QoSm1Proxy:: QoSm1Proxy(Gateway* gw) : Adapter(gw)
|
||||
QoSm1Proxy::QoSm1Proxy(Gateway* gw) :
|
||||
Adapter(gw)
|
||||
{
|
||||
_gateway = gw;
|
||||
}
|
||||
@@ -37,10 +37,9 @@ QoSm1Proxy::~QoSm1Proxy(void)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QoSm1Proxy::initialize(char* gwName)
|
||||
{
|
||||
if ( _gateway->hasSecureConnection() )
|
||||
if (_gateway->hasSecureConnection())
|
||||
{
|
||||
_isSecure = true;
|
||||
}
|
||||
@@ -54,7 +53,6 @@ void QoSm1Proxy::initialize(char* gwName)
|
||||
_isActive = true;
|
||||
}
|
||||
|
||||
|
||||
bool QoSm1Proxy::isActive(void)
|
||||
{
|
||||
return _isActive;
|
||||
|
||||
@@ -29,7 +29,7 @@ class MQTTSNPacket;
|
||||
/*=====================================
|
||||
Class QoSm1Proxy
|
||||
=====================================*/
|
||||
class QoSm1Proxy : public Adapter
|
||||
class QoSm1Proxy: public Adapter
|
||||
{
|
||||
public:
|
||||
QoSm1Proxy(Gateway* gw);
|
||||
@@ -41,13 +41,10 @@ public:
|
||||
private:
|
||||
Gateway* _gateway;
|
||||
|
||||
bool _isActive {false};
|
||||
bool _isSecure {false};
|
||||
bool _isActive { false };
|
||||
bool _isSecure { false };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */
|
||||
|
||||
@@ -46,26 +46,33 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
Event* ev1;
|
||||
Event* evsuback;
|
||||
|
||||
if ( packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0 )
|
||||
if (packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
if (msgId == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED )
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
|
||||
{
|
||||
topic = client->getTopics()->getTopicById(&topicFilter);
|
||||
|
||||
if ( !topic )
|
||||
if (!topic)
|
||||
{
|
||||
/* Search the topic in Client common topic table */
|
||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -74,25 +81,26 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
}
|
||||
topicId = topic->getTopicId();
|
||||
subscribe = new MQTTGWPacket();
|
||||
subscribe->setSUBSCRIBE((char*)topic->getTopicName()->c_str(), (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
|
||||
|
||||
}
|
||||
else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
topic = client->getTopics()->getTopicByName(&topicFilter);
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
topic = client->getTopics()->add(&topicFilter);
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return nullptr;
|
||||
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
goto RespExit;
|
||||
}
|
||||
}
|
||||
topicId = topic->getTopicId();
|
||||
subscribe = new MQTTGWPacket();
|
||||
|
||||
subscribe->setSUBSCRIBE((char*)topic->getTopicName()->c_str(), (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE((char*) topic->getTopicName()->c_str(), (uint8_t) qos, (uint16_t) msgId);
|
||||
}
|
||||
else //MQTTSN_TOPIC_TYPE_SHORT
|
||||
{
|
||||
@@ -103,12 +111,12 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
topicId = topicFilter.data.short_name[0] << 8;
|
||||
topicId |= topicFilter.data.short_name[1];
|
||||
subscribe = new MQTTGWPacket();
|
||||
subscribe->setSUBSCRIBE(topicstr, (uint8_t)qos, (uint16_t)msgId);
|
||||
subscribe->setSUBSCRIBE(topicstr, (uint8_t) qos, (uint16_t) msgId);
|
||||
}
|
||||
|
||||
client->setWaitedSubTopicId(msgId, topicId, topicFilter.type);
|
||||
client->setWaitedSubTopicId(msgId, topicId, &topicFilter);
|
||||
|
||||
if ( !client->isAggregated() )
|
||||
if (!client->isAggregated())
|
||||
{
|
||||
ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, subscribe);
|
||||
@@ -120,10 +128,8 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
|
||||
RespExit:
|
||||
MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_NOT_SUPPORTED);
|
||||
RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket();
|
||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
|
||||
evsuback = new Event();
|
||||
evsuback->setClientSendEvent(client, sSuback);
|
||||
_gateway->getClientSendQue()->post(evsuback);
|
||||
@@ -136,17 +142,16 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
||||
MQTTSN_topicid topicFilter;
|
||||
MQTTGWPacket* unsubscribe = nullptr;
|
||||
|
||||
if ( packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0 )
|
||||
if (packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
if (msgId == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||
{
|
||||
char shortTopic[3];
|
||||
@@ -169,7 +174,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
||||
topic = client->getTopics()->getTopicByName(&topicFilter);
|
||||
}
|
||||
|
||||
if ( topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
MQTTSNPacket* sUnsuback = new MQTTSNPacket();
|
||||
sUnsuback->setUNSUBACK(msgId);
|
||||
@@ -185,7 +190,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
||||
}
|
||||
}
|
||||
|
||||
if ( !client->isAggregated() )
|
||||
if (!client->isAggregated())
|
||||
{
|
||||
Event* ev1 = new Event();
|
||||
ev1->setBrokerSendEvent(client, unsubscribe);
|
||||
@@ -202,10 +207,10 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPack
|
||||
{
|
||||
MQTTGWPacket* subscribe = handleSubscribe(client, packet);
|
||||
|
||||
if ( subscribe != nullptr )
|
||||
if (subscribe != nullptr)
|
||||
{
|
||||
int msgId = 0;
|
||||
if ( packet->isDuplicate() )
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
@@ -214,9 +219,10 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPack
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
if (msgId == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -236,10 +242,10 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPack
|
||||
void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet);
|
||||
if ( unsubscribe != nullptr )
|
||||
if (unsubscribe != nullptr)
|
||||
{
|
||||
int msgId = 0;
|
||||
if ( packet->isDuplicate() )
|
||||
if (packet->isDuplicate())
|
||||
{
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
|
||||
}
|
||||
@@ -248,9 +254,10 @@ void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPa
|
||||
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
|
||||
}
|
||||
|
||||
if ( msgId == 0 )
|
||||
if (msgId == 0)
|
||||
{
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,5 +42,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */
|
||||
|
||||
@@ -42,7 +42,7 @@ Topic::Topic(string* topic, MQTTSN_topicTypes type)
|
||||
|
||||
Topic::~Topic()
|
||||
{
|
||||
if ( _topicName )
|
||||
if (_topicName)
|
||||
{
|
||||
delete _topicName;
|
||||
}
|
||||
@@ -83,12 +83,12 @@ bool Topic::isMatch(string* topicName)
|
||||
string wildcard = "#";
|
||||
string wildcards = "+";
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
loc = topicName->find('/', pos);
|
||||
tloc = _topicName->find('/', tpos);
|
||||
|
||||
if ( loc != string::npos && tloc != string::npos )
|
||||
if (loc != string::npos && tloc != string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos, loc - pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
@@ -98,11 +98,11 @@ bool Topic::isMatch(string* topicName)
|
||||
}
|
||||
else if (subtopict == wildcards)
|
||||
{
|
||||
if ( (tpos = tloc + 1 ) > tlen )
|
||||
if ((tpos = tloc + 1) > tlen)
|
||||
{
|
||||
pos = loc + 1;
|
||||
loc = topicName->find('/', pos);
|
||||
if ( loc == string::npos )
|
||||
if (loc == string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -113,13 +113,13 @@ bool Topic::isMatch(string* topicName)
|
||||
}
|
||||
pos = loc + 1;
|
||||
}
|
||||
else if ( subtopic != subtopict )
|
||||
else if (subtopic != subtopict)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (tpos = tloc + 1) > tlen )
|
||||
if ((tpos = tloc + 1) > tlen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -127,15 +127,15 @@ bool Topic::isMatch(string* topicName)
|
||||
pos = loc + 1;
|
||||
}
|
||||
}
|
||||
else if ( loc == string::npos && tloc == string::npos )
|
||||
else if (loc == string::npos && tloc == string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos);
|
||||
if ( subtopict == wildcard || subtopict == wildcards)
|
||||
if (subtopict == wildcard || subtopict == wildcards)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( subtopic == subtopict )
|
||||
else if (subtopic == subtopict)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -144,11 +144,11 @@ bool Topic::isMatch(string* topicName)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( loc == string::npos && tloc != string::npos )
|
||||
else if (loc == string::npos && tloc != string::npos)
|
||||
{
|
||||
string subtopic = topicName->substr(pos);
|
||||
string subtopict = _topicName->substr(tpos, tloc - tpos);
|
||||
if ( subtopic != subtopict)
|
||||
if (subtopic != subtopict)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -157,7 +157,7 @@ bool Topic::isMatch(string* topicName)
|
||||
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
else if ( loc != string::npos && tloc == string::npos )
|
||||
else if (loc != string::npos && tloc == string::npos)
|
||||
{
|
||||
return _topicName->substr(tpos) == wildcard;
|
||||
}
|
||||
@@ -198,7 +198,7 @@ Topic* Topics::getTopicByName(const MQTTSN_topicid* topicid)
|
||||
string sname = string(ch, ch + topicid->data.long_.len);
|
||||
while (p)
|
||||
{
|
||||
if ( p->_topicName->compare(sname) == 0 )
|
||||
if (p->_topicName->compare(sname) == 0)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
|
||||
|
||||
while (p)
|
||||
{
|
||||
if ( p->_type == topicid->type && p->_topicId == topicid->data.id )
|
||||
if (p->_type == topicid->type && p->_topicId == topicid->data.id)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
@@ -225,14 +225,14 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
|
||||
// For MQTTSN_TOPIC_TYPE_NORMAL */
|
||||
Topic* Topics::add(const MQTTSN_topicid* topicid)
|
||||
{
|
||||
if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Topic* topic = getTopicByName(topicid);
|
||||
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
@@ -244,18 +244,17 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
{
|
||||
MQTTSN_topicid topicId;
|
||||
|
||||
if ( _cnt >= MAX_TOPIC_PAR_CLIENT )
|
||||
if (_cnt >= MAX_TOPIC_PAR_CLIENT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
topicId.data.long_.name = (char*)const_cast<char*>(topicName);
|
||||
topicId.data.long_.name = (char*) const_cast<char*>(topicName);
|
||||
topicId.data.long_.len = strlen(topicName);
|
||||
|
||||
|
||||
Topic* topic = getTopicByName(&topicId);
|
||||
|
||||
if ( topic )
|
||||
if (topic)
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
@@ -270,7 +269,7 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
string* name = new string(topicName);
|
||||
topic->_topicName = name;
|
||||
|
||||
if ( id == 0 )
|
||||
if (id == 0)
|
||||
{
|
||||
topic->_type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||
topic->_topicId = getNextTopicId();
|
||||
@@ -283,7 +282,7 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
||||
|
||||
_cnt++;
|
||||
|
||||
if ( _first == nullptr)
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = topic;
|
||||
}
|
||||
@@ -331,7 +330,6 @@ Topic* Topics::match(const MQTTSN_topicid* topicid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Topics::eraseNormal(void)
|
||||
{
|
||||
Topic* topic = _first;
|
||||
@@ -340,14 +338,14 @@ void Topics::eraseNormal(void)
|
||||
|
||||
while (topic)
|
||||
{
|
||||
if ( topic->_type == MQTTSN_TOPIC_TYPE_NORMAL )
|
||||
if (topic->_type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
next = topic->_next;
|
||||
if ( _first == topic )
|
||||
if (_first == topic)
|
||||
{
|
||||
_first = next;
|
||||
}
|
||||
if ( prev )
|
||||
if (prev)
|
||||
{
|
||||
prev->_next = next;
|
||||
}
|
||||
@@ -376,7 +374,7 @@ Topic* Topics::getNextTopic(Topic* topic)
|
||||
void Topics::print(void)
|
||||
{
|
||||
Topic* topic = _first;
|
||||
if (topic == nullptr )
|
||||
if (topic == nullptr)
|
||||
{
|
||||
WRITELOG("No Topic.\n");
|
||||
}
|
||||
@@ -398,13 +396,22 @@ uint8_t Topics::getCount(void)
|
||||
/*=====================================
|
||||
Class TopicIdMap
|
||||
=====================================*/
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement::TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
_msgId = msgId;
|
||||
_topicId = topicId;
|
||||
_type = type;
|
||||
_type = topic->type;
|
||||
_wildcard = 0;
|
||||
_next = nullptr;
|
||||
_prev = nullptr;
|
||||
|
||||
if (_type == MQTTSN_TOPIC_TYPE_NORMAL)
|
||||
{
|
||||
if (strchr(topic->data.long_.name, '#') != 0 || strchr(topic->data.long_.name, '+') != 0)
|
||||
{
|
||||
_wildcard = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMapElement::~TopicIdMapElement()
|
||||
@@ -419,7 +426,14 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
|
||||
|
||||
uint16_t TopicIdMapElement::getTopicId(void)
|
||||
{
|
||||
if (_wildcard > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _topicId;
|
||||
}
|
||||
}
|
||||
|
||||
TopicIdMap::TopicIdMap()
|
||||
@@ -434,7 +448,7 @@ TopicIdMap::TopicIdMap()
|
||||
TopicIdMap::~TopicIdMap()
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
TopicIdMapElement* q = p->_next;
|
||||
delete p;
|
||||
@@ -445,9 +459,9 @@ TopicIdMap::~TopicIdMap()
|
||||
TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_msgId == msgId )
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
@@ -456,23 +470,23 @@ TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type)
|
||||
TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic)
|
||||
{
|
||||
if ( _cnt > _maxInflight * 2 || ( topicId == 0 && type != MQTTSN_TOPIC_TYPE_SHORT ) )
|
||||
if (_cnt > _maxInflight * 2 || (topicId == 0 && topic->type != MQTTSN_TOPIC_TYPE_SHORT))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( getElement(msgId) )
|
||||
if (getElement(msgId))
|
||||
{
|
||||
erase(msgId);
|
||||
}
|
||||
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, type);
|
||||
if ( elm == 0 )
|
||||
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, topic);
|
||||
if (elm == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( _first == nullptr )
|
||||
if (_first == nullptr)
|
||||
{
|
||||
_first = elm;
|
||||
_end = elm;
|
||||
@@ -490,11 +504,11 @@ TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topi
|
||||
void TopicIdMap::erase(uint16_t msgId)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
if ( p->_msgId == msgId )
|
||||
if (p->_msgId == msgId)
|
||||
{
|
||||
if ( p->_prev == nullptr )
|
||||
if (p->_prev == nullptr)
|
||||
{
|
||||
_first = p->_next;
|
||||
}
|
||||
@@ -503,7 +517,7 @@ void TopicIdMap::erase(uint16_t msgId)
|
||||
p->_prev->_next = p->_next;
|
||||
}
|
||||
|
||||
if ( p->_next == nullptr )
|
||||
if (p->_next == nullptr)
|
||||
{
|
||||
_end = p->_prev;
|
||||
}
|
||||
@@ -523,7 +537,7 @@ void TopicIdMap::erase(uint16_t msgId)
|
||||
void TopicIdMap::clear(void)
|
||||
{
|
||||
TopicIdMapElement* p = _first;
|
||||
while ( p )
|
||||
while (p)
|
||||
{
|
||||
TopicIdMapElement* q = p->_next;
|
||||
delete p;
|
||||
@@ -534,5 +548,3 @@ void TopicIdMap::clear(void)
|
||||
_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Topic
|
||||
======================================*/
|
||||
@@ -82,7 +81,7 @@ class TopicIdMapElement
|
||||
{
|
||||
friend class TopicIdMap;
|
||||
public:
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
~TopicIdMapElement();
|
||||
MQTTSN_topicTypes getTopicType(void);
|
||||
uint16_t getTopicId(void);
|
||||
@@ -90,6 +89,7 @@ public:
|
||||
private:
|
||||
uint16_t _msgId;
|
||||
uint16_t _topicId;
|
||||
uint8_t _wildcard;
|
||||
MQTTSN_topicTypes _type;
|
||||
TopicIdMapElement* _next;
|
||||
TopicIdMapElement* _prev;
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
TopicIdMap();
|
||||
~TopicIdMap();
|
||||
TopicIdMapElement* getElement(uint16_t msgId);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type);
|
||||
TopicIdMapElement* add(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
|
||||
void erase(uint16_t msgId);
|
||||
void clear(void);
|
||||
private:
|
||||
@@ -112,9 +112,6 @@ private:
|
||||
int _maxInflight;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWTOPIC_H_ */
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef MQTTSNGWVERSION_H_IN_
|
||||
#define MQTTSNGWVERSION_H_IN_
|
||||
|
||||
#define PAHO_GATEWAY_VERSION "1.4.0"
|
||||
#define PAHO_GATEWAY_VERSION "1.6.0"
|
||||
|
||||
#endif /* MQTTSNGWVERSION_H_IN_ */
|
||||
|
||||
@@ -32,10 +32,10 @@ MQTTSNGW::Gateway* theGateway = nullptr;
|
||||
|
||||
Gateway::Gateway(void)
|
||||
{
|
||||
theGateway = this;
|
||||
theMultiTaskProcess = this;
|
||||
theProcess = this;
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
_clientList = new ClientList();
|
||||
_clientList = new ClientList(this);
|
||||
_adapterManager = new AdapterManager(this);
|
||||
_topics = new Topics();
|
||||
_stopFlg = false;
|
||||
@@ -43,78 +43,87 @@ Gateway::Gateway(void)
|
||||
|
||||
Gateway::~Gateway()
|
||||
{
|
||||
if ( _params.loginId )
|
||||
if (_params.loginId)
|
||||
{
|
||||
free(_params.loginId);
|
||||
}
|
||||
if ( _params.password )
|
||||
if (_params.password)
|
||||
{
|
||||
free(_params.password);
|
||||
}
|
||||
if ( _params.gatewayName )
|
||||
if (_params.gatewayName)
|
||||
{
|
||||
free(_params.gatewayName);
|
||||
}
|
||||
if ( _params.brokerName )
|
||||
if (_params.brokerName)
|
||||
{
|
||||
free(_params.brokerName);
|
||||
}
|
||||
if ( _params.port )
|
||||
if (_params.port)
|
||||
{
|
||||
free(_params.port);
|
||||
}
|
||||
if ( _params.portSecure )
|
||||
if (_params.portSecure)
|
||||
{
|
||||
free(_params.portSecure);
|
||||
}
|
||||
if ( _params.certKey )
|
||||
if (_params.certKey)
|
||||
{
|
||||
free(_params.certKey);
|
||||
}
|
||||
if ( _params.privateKey )
|
||||
if (_params.privateKey)
|
||||
{
|
||||
free(_params.privateKey);
|
||||
}
|
||||
if ( _params.rootCApath )
|
||||
if (_params.rootCApath)
|
||||
{
|
||||
free(_params.rootCApath);
|
||||
}
|
||||
if ( _params.rootCAfile )
|
||||
if (_params.rootCAfile)
|
||||
{
|
||||
free(_params.rootCAfile);
|
||||
}
|
||||
if ( _params.clientListName )
|
||||
if (_params.clientListName)
|
||||
{
|
||||
free(_params.clientListName);
|
||||
}
|
||||
if ( _params.predefinedTopicFileName )
|
||||
if (_params.predefinedTopicFileName)
|
||||
{
|
||||
free( _params.predefinedTopicFileName);
|
||||
free(_params.predefinedTopicFileName);
|
||||
}
|
||||
if ( _params.configName )
|
||||
if (_params.configName)
|
||||
{
|
||||
free(_params.configName);
|
||||
}
|
||||
|
||||
if ( _params.qosMinusClientListName )
|
||||
if (_params.qosMinusClientListName)
|
||||
{
|
||||
free(_params.qosMinusClientListName);
|
||||
}
|
||||
if (_params.rfcommAddr)
|
||||
{
|
||||
free(_params.rfcommAddr);
|
||||
}
|
||||
if (_params.gwCertskey)
|
||||
{
|
||||
free(_params.gwCertskey);
|
||||
}
|
||||
if (_params.gwPrivatekey)
|
||||
{
|
||||
free(_params.gwPrivatekey);
|
||||
}
|
||||
|
||||
if ( _adapterManager )
|
||||
if (_adapterManager)
|
||||
{
|
||||
delete _adapterManager;
|
||||
}
|
||||
if ( _clientList )
|
||||
if (_clientList)
|
||||
{
|
||||
delete _clientList;
|
||||
}
|
||||
|
||||
if ( _topics )
|
||||
if (_topics)
|
||||
{
|
||||
delete _topics;
|
||||
}
|
||||
// WRITELOG("Gateway is deleted normally.\r\n");
|
||||
}
|
||||
|
||||
int Gateway::getParam(const char* parameter, char* value)
|
||||
@@ -174,6 +183,14 @@ void Gateway::initialize(int argc, char** argv)
|
||||
{
|
||||
_params.rootCAfile = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsCertsKey", param) == 0)
|
||||
{
|
||||
_params.gwCertskey = strdup(param);
|
||||
}
|
||||
if (getParam("DtlsPrivKey", param) == 0)
|
||||
{
|
||||
_params.gwPrivatekey = strdup(param);
|
||||
}
|
||||
|
||||
if (getParam("GatewayID", param) == 0)
|
||||
{
|
||||
@@ -182,7 +199,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (_params.gatewayId == 0 || _params.gatewayId > 255)
|
||||
{
|
||||
throw Exception( "Gateway::initialize: invalid Gateway Id");
|
||||
throw Exception("Gateway::initialize: invalid Gateway Id", 0);
|
||||
}
|
||||
|
||||
if (getParam("GatewayName", param) == 0)
|
||||
@@ -190,9 +207,9 @@ void Gateway::initialize(int argc, char** argv)
|
||||
_params.gatewayName = strdup(param);
|
||||
}
|
||||
|
||||
if (_params.gatewayName == 0 )
|
||||
if (_params.gatewayName == 0)
|
||||
{
|
||||
throw Exception( "Gateway::initialize: Gateway Name is missing.");
|
||||
throw Exception("Gateway::initialize: Gateway Name is missing.", 0);
|
||||
}
|
||||
|
||||
_params.mqttVersion = DEFAULT_MQTT_VERSION;
|
||||
@@ -201,7 +218,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
_params.mqttVersion = atoi(param);
|
||||
}
|
||||
|
||||
_params.maxInflightMsgs = DEFAULT_MQTT_VERSION;
|
||||
_params.maxInflightMsgs = MAX_INFLIGHTMESSAGES;
|
||||
if (getParam("MaxInflightMsgs", param) == 0)
|
||||
{
|
||||
_params.maxInflightMsgs = atoi(param);
|
||||
@@ -238,7 +255,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (getParam("PredefinedTopic", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.predefinedTopic = true;
|
||||
if (getParam("PredefinedTopicList", param) == 0)
|
||||
@@ -250,7 +267,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (getParam("AggregatingGateway", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.aggregatingGw = true;
|
||||
}
|
||||
@@ -258,7 +275,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (getParam("Forwarder", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.forwarder = true;
|
||||
}
|
||||
@@ -266,18 +283,34 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (getParam("QoS-1", param) == 0)
|
||||
{
|
||||
if ( !strcasecmp(param, "YES") )
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
_params.qosMinus1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
_params.maxClients = MAX_CLIENTS;
|
||||
if (getParam("MaxNumberOfClients", param) == 0)
|
||||
{
|
||||
_params.maxClients = atoi(param);
|
||||
}
|
||||
|
||||
if (getParam("RFCOMMAddress", param) == 0)
|
||||
{
|
||||
_params.rfcommAddr = strdup(param);
|
||||
}
|
||||
|
||||
/* Setup max PacketEventQue size */
|
||||
_packetEventQue.setMaxSize(_params.maxInflightMsgs * _params.maxClients);
|
||||
|
||||
/* Initialize adapters */
|
||||
_adapterManager->initialize( _params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||
|
||||
/* Setup ClientList and Predefined topics */
|
||||
_clientList->initialize(_params.aggregatingGw);
|
||||
|
||||
/* SensorNetwork initialize */
|
||||
_sensorNetwork.initialize();
|
||||
}
|
||||
|
||||
void Gateway::run(void)
|
||||
@@ -291,31 +324,36 @@ void Gateway::run(void)
|
||||
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
|
||||
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
|
||||
WRITELOG("%s\n", PAHO_COPYRIGHT4);
|
||||
WRITELOG("\n%s %s has been started.\n\n", currentDateTime(), _params.gatewayName);
|
||||
WRITELOG(" ConfigFile: %s\n", _params.configName);
|
||||
WRITELOG(" ConfigFile : %s\n", _params.configName);
|
||||
|
||||
if ( _params.clientListName )
|
||||
if (_params.clientListName)
|
||||
{
|
||||
WRITELOG(" ClientList: %s\n", _params.clientListName);
|
||||
WRITELOG(" ClientList : %s\n", _params.clientListName);
|
||||
}
|
||||
|
||||
if ( _params.predefinedTopicFileName )
|
||||
if (_params.predefinedTopicFileName)
|
||||
{
|
||||
WRITELOG(" PreDefFile: %s\n", _params.predefinedTopicFileName);
|
||||
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
||||
}
|
||||
|
||||
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
|
||||
WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath: %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile: %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey: %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
|
||||
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
||||
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
||||
WRITELOG(" CertKey : %s\n", _params.certKey);
|
||||
WRITELOG(" PrivateKey : %s\n", _params.privateKey);
|
||||
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
|
||||
#ifdef DTLS
|
||||
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
|
||||
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
|
||||
#endif
|
||||
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
|
||||
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
|
||||
|
||||
_stopFlg = false;
|
||||
|
||||
/* Run Tasks until CTRL+C entred */
|
||||
/* Run Tasks until CTRL+C entered or Exception occurred */
|
||||
MultiTaskProcess::run();
|
||||
|
||||
WRITELOG("\n");
|
||||
_stopFlg = true;
|
||||
|
||||
/* stop Tasks */
|
||||
@@ -332,7 +370,7 @@ void Gateway::run(void)
|
||||
/* wait until all Task stop */
|
||||
MultiTaskProcess::waitStop();
|
||||
|
||||
WRITELOG("\n\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
WRITELOG("\n%s MQTT-SN Gateway stopped.\n\n", currentDateTime());
|
||||
_lightIndicator.allLightOff();
|
||||
}
|
||||
|
||||
@@ -388,17 +426,14 @@ Topics* Gateway::getTopics(void)
|
||||
|
||||
bool Gateway::hasSecureConnection(void)
|
||||
{
|
||||
return ( _params.certKey
|
||||
&& _params.privateKey
|
||||
&& _params.rootCApath
|
||||
&& _params.rootCAfile );
|
||||
return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
=====================================*/
|
||||
EventQue::EventQue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EventQue::~EventQue()
|
||||
@@ -414,16 +449,16 @@ EventQue::~EventQue()
|
||||
|
||||
void EventQue::setMaxSize(uint16_t maxSize)
|
||||
{
|
||||
_que.setMaxSize((int)maxSize);
|
||||
_que.setMaxSize((int) maxSize);
|
||||
}
|
||||
|
||||
Event* EventQue::wait(void)
|
||||
{
|
||||
Event* ev = nullptr;
|
||||
|
||||
while(ev == nullptr)
|
||||
while (ev == nullptr)
|
||||
{
|
||||
if ( _que.size() == 0 )
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
_sem.wait();
|
||||
}
|
||||
@@ -438,7 +473,7 @@ Event* EventQue::wait(void)
|
||||
Event* EventQue::timedwait(uint16_t millsec)
|
||||
{
|
||||
Event* ev;
|
||||
if ( _que.size() == 0 )
|
||||
if (_que.size() == 0)
|
||||
{
|
||||
_sem.timedwait(millsec);
|
||||
}
|
||||
@@ -460,10 +495,10 @@ Event* EventQue::timedwait(uint16_t millsec)
|
||||
|
||||
void EventQue::post(Event* ev)
|
||||
{
|
||||
if ( ev )
|
||||
if (ev)
|
||||
{
|
||||
_mutex.lock();
|
||||
if ( _que.post(ev) )
|
||||
if (_que.post(ev))
|
||||
{
|
||||
_sem.post();
|
||||
}
|
||||
@@ -483,7 +518,6 @@ int EventQue::size()
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Event
|
||||
=====================================*/
|
||||
@@ -586,4 +620,3 @@ MQTTGWPacket* Event::getMQTTGWPacket(void)
|
||||
return _mqttGWPacket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "MQTTSNGWProcess.h"
|
||||
#include "MQTTSNPacket.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTSNGWProcess.h"
|
||||
|
||||
namespace MQTTSNGW
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace MQTTSNGW
|
||||
==================================*/
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway"
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
#define PAHO_COPYRIGHT2 " * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)"
|
||||
#define PAHO_COPYRIGHT2 " * (https://github.com/eclipse/paho.mqtt-sn.embedded-c.git)"
|
||||
#define PAHO_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
|
||||
#define PAHO_COPYRIGHT4 " ***************************************************************************"
|
||||
/*==========================================================
|
||||
@@ -76,7 +77,8 @@ namespace MQTTSNGW
|
||||
====================================*/
|
||||
class Client;
|
||||
|
||||
enum EventType{
|
||||
enum EventType
|
||||
{
|
||||
Et_NA = 0,
|
||||
EtStop,
|
||||
EtTimeout,
|
||||
@@ -88,8 +90,8 @@ enum EventType{
|
||||
EtSensornetSend
|
||||
};
|
||||
|
||||
|
||||
class Event{
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
Event();
|
||||
~Event();
|
||||
@@ -108,14 +110,13 @@ public:
|
||||
MQTTGWPacket* getMQTTGWPacket(void);
|
||||
|
||||
private:
|
||||
EventType _eventType {Et_NA};
|
||||
Client* _client {nullptr};
|
||||
SensorNetAddress* _sensorNetAddr {nullptr};
|
||||
MQTTSNPacket* _mqttSNPacket {nullptr};
|
||||
MQTTGWPacket* _mqttGWPacket {nullptr};
|
||||
EventType _eventType { Et_NA };
|
||||
Client* _client { nullptr };
|
||||
SensorNetAddress* _sensorNetAddr { nullptr };
|
||||
MQTTSNPacket* _mqttSNPacket { nullptr };
|
||||
MQTTGWPacket* _mqttGWPacket { nullptr };
|
||||
};
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class EventQue
|
||||
====================================*/
|
||||
@@ -136,8 +137,6 @@ private:
|
||||
Semaphore _sem;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class GatewayParams
|
||||
====================================*/
|
||||
@@ -145,40 +144,44 @@ class GatewayParams
|
||||
{
|
||||
public:
|
||||
string configDir;
|
||||
char* configName {nullptr};
|
||||
char* clientListName {nullptr};
|
||||
char* loginId {nullptr};
|
||||
char* password {nullptr};
|
||||
uint16_t keepAlive {0};
|
||||
uint8_t gatewayId {0};
|
||||
uint8_t mqttVersion {0};
|
||||
uint16_t maxInflightMsgs {0};
|
||||
char* gatewayName {nullptr};
|
||||
char* brokerName {nullptr};
|
||||
char* port {nullptr};
|
||||
char* portSecure {nullptr};
|
||||
char* rootCApath {nullptr};
|
||||
char* rootCAfile {nullptr};
|
||||
char* certKey {nullptr};
|
||||
char* predefinedTopicFileName {nullptr};
|
||||
char* privateKey {nullptr};
|
||||
char* qosMinusClientListName {nullptr};
|
||||
bool clientAuthentication {false};
|
||||
bool predefinedTopic {false};
|
||||
bool aggregatingGw {false};
|
||||
bool qosMinus1 {false};
|
||||
bool forwarder {false};
|
||||
char* configName { nullptr };
|
||||
char* clientListName { nullptr };
|
||||
char* loginId { nullptr };
|
||||
char* password { nullptr };
|
||||
uint16_t keepAlive { 0 };
|
||||
uint8_t gatewayId { 0 };
|
||||
uint8_t mqttVersion { 0 };
|
||||
uint16_t maxInflightMsgs { 0 };
|
||||
char* gatewayName { nullptr };
|
||||
char* brokerName { nullptr };
|
||||
char* port { nullptr };
|
||||
char* portSecure{ nullptr };
|
||||
char* rootCApath { nullptr };
|
||||
char* rootCAfile { nullptr };
|
||||
char* certKey { nullptr };
|
||||
char* predefinedTopicFileName { nullptr };
|
||||
char* privateKey { nullptr };
|
||||
char* qosMinusClientListName { nullptr };
|
||||
bool clientAuthentication { false };
|
||||
bool predefinedTopic { false };
|
||||
bool aggregatingGw { false };
|
||||
bool qosMinus1 { false };
|
||||
bool forwarder { false };
|
||||
int maxClients {0};
|
||||
char* rfcommAddr { nullptr };
|
||||
char* gwCertskey { nullptr };
|
||||
char* gwPrivatekey { nullptr };
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*=====================================
|
||||
Class Gateway
|
||||
=====================================*/
|
||||
class AdapterManager;
|
||||
class ClientList;
|
||||
class ClientsPool;
|
||||
|
||||
class Gateway: public MultiTaskProcess{
|
||||
class Gateway: public MultiTaskProcess
|
||||
{
|
||||
public:
|
||||
Gateway(void);
|
||||
~Gateway();
|
||||
@@ -196,24 +199,23 @@ public:
|
||||
int getParam(const char* parameter, char* value);
|
||||
char* getClientListFileName(void);
|
||||
char* getPredefinedTopicFileName(void);
|
||||
|
||||
bool hasSecureConnection(void);
|
||||
Topics* getTopics(void);
|
||||
bool IsStopping(void);
|
||||
void requestSensorNetSubTask(void);
|
||||
|
||||
private:
|
||||
GatewayParams _params;
|
||||
ClientList* _clientList {nullptr};
|
||||
ClientList* _clientList;
|
||||
EventQue _packetEventQue;
|
||||
EventQue _brokerSendQue;
|
||||
EventQue _clientSendQue;
|
||||
LightIndicator _lightIndicator;
|
||||
SensorNetwork _sensorNetwork;
|
||||
AdapterManager* _adapterManager {nullptr};
|
||||
AdapterManager* _adapterManager;
|
||||
Topics* _topics;
|
||||
bool _stopFlg;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* MQTTSNGATEWAY_H_ */
|
||||
|
||||
@@ -279,6 +279,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
char errmsg[256];
|
||||
char peer_CN[256];
|
||||
bool rc;
|
||||
X509* peer = nullptr;
|
||||
|
||||
_mutex.lock();
|
||||
try
|
||||
@@ -385,7 +386,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
throw false;
|
||||
}
|
||||
|
||||
X509* peer = SSL_get_peer_certificate(_ssl);
|
||||
peer = SSL_get_peer_certificate(_ssl);
|
||||
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);
|
||||
char* pos = peer_CN;
|
||||
if ( *pos == '*')
|
||||
@@ -413,7 +414,12 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
||||
{
|
||||
rc = x;
|
||||
}
|
||||
|
||||
_mutex.unlock();
|
||||
if (peer != nullptr)
|
||||
{
|
||||
X509_free(peer);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -650,3 +656,7 @@ bool Network::isSecure()
|
||||
return _secureFlg;
|
||||
}
|
||||
|
||||
void Network::setSecure(bool secureFlg)
|
||||
{
|
||||
_secureFlg = secureFlg;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
bool isValid(void);
|
||||
bool isSecure(void);
|
||||
int getSock(void);
|
||||
void setSecure(bool secureFlg);
|
||||
|
||||
private:
|
||||
static SSL_CTX* _ctx;
|
||||
|
||||
@@ -79,23 +79,23 @@ Mutex::Mutex(const char* fileName)
|
||||
|
||||
if ((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't create a shared memory.");
|
||||
throw Exception("Mutex can't create a shared memory.", -1);
|
||||
}
|
||||
_pmutex = (pthread_mutex_t*) shmat(_shmid, NULL, 0);
|
||||
if (_pmutex == (void*) -1)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't attach shared memory.");
|
||||
throw Exception("Mutex can't attach shared memory.", -1);
|
||||
}
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
|
||||
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't set the process-shared flag");
|
||||
throw Exception("Mutex can't set the process-shared flag", -1);
|
||||
}
|
||||
if (pthread_mutex_init(_pmutex, &attr) != 0)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't initialize.");
|
||||
throw Exception("Mutex can't initialize.", -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,44 +121,37 @@ Mutex::~Mutex(void)
|
||||
|
||||
void Mutex::lock(void)
|
||||
{
|
||||
int rc = 0;
|
||||
if (_pmutex)
|
||||
{
|
||||
pthread_mutex_lock(_pmutex);
|
||||
rc = pthread_mutex_lock(_pmutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pthread_mutex_lock(&_mutex))
|
||||
{
|
||||
throw;
|
||||
rc = pthread_mutex_lock(&_mutex);
|
||||
}
|
||||
} catch (char* errmsg)
|
||||
|
||||
if (rc)
|
||||
{
|
||||
throw Exception( -1, "The same thread can't aquire a mutex twice.");
|
||||
}
|
||||
throw Exception("Mutex lock error", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void Mutex::unlock(void)
|
||||
{
|
||||
|
||||
int rc = 0;
|
||||
if (_pmutex)
|
||||
{
|
||||
pthread_mutex_unlock(_pmutex);
|
||||
rc = pthread_mutex_unlock(_pmutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pthread_mutex_unlock(&_mutex))
|
||||
{
|
||||
throw;
|
||||
rc = pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
} catch (char* errmsg)
|
||||
|
||||
if (rc)
|
||||
{
|
||||
throw Exception( -1, "Mutex can't unlock.");
|
||||
}
|
||||
throw Exception("Mutex lock error", errno);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,12 +218,12 @@ NamedSemaphore::NamedSemaphore(const char* name, unsigned int val)
|
||||
_psem = sem_open(name, O_CREAT, 0666, val);
|
||||
if (_psem == SEM_FAILED)
|
||||
{
|
||||
throw Exception( -1, "Semaphore can't be created.");
|
||||
throw Exception("Semaphore can't be created.", -1);
|
||||
}
|
||||
_name = strdup(name);
|
||||
if (_name == NULL)
|
||||
{
|
||||
throw Exception( -1, "Semaphore can't allocate memories.");
|
||||
throw Exception("Semaphore can't allocate memories.", -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,11 +256,6 @@ void NamedSemaphore::timedwait(uint16_t millsec)
|
||||
/*=========================================
|
||||
Class RingBuffer
|
||||
=========================================*/
|
||||
RingBuffer::RingBuffer()
|
||||
{
|
||||
RingBuffer(MQTTSNGW_KEY_DIRECTORY);
|
||||
}
|
||||
|
||||
RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
{
|
||||
int fp = 0;
|
||||
@@ -303,7 +291,7 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't attach shared memory.");
|
||||
throw Exception("RingBuffer can't attach shared memory.", -1);
|
||||
}
|
||||
}
|
||||
else if ((_shmid = shmget(key, PROCESS_LOG_BUFFER_SIZE, IPC_CREAT | 0666)) != -1)
|
||||
@@ -318,12 +306,12 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
||||
throw Exception("RingBuffer can't create a shared memory.", -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
||||
throw Exception( "RingBuffer can't create a shared memory.", -1);
|
||||
}
|
||||
|
||||
_pmx = new Mutex(MQTTSNGW_RB_MUTEX_KEY);
|
||||
@@ -495,7 +483,7 @@ void RingBuffer::reset()
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(-1, "RingBuffer can't reset. need to clear shared memory.");
|
||||
throw Exception("RingBuffer can't reset. need to clear shared memory.", -1);
|
||||
}
|
||||
_pmx->unlock();
|
||||
}
|
||||
@@ -506,6 +494,7 @@ void RingBuffer::reset()
|
||||
Thread::Thread()
|
||||
{
|
||||
_threadID = 0;
|
||||
_taskName = nullptr;
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
@@ -539,11 +528,6 @@ int Thread::start(void)
|
||||
return pthread_create(&_threadID, 0, _run, runnable);
|
||||
}
|
||||
|
||||
void Thread::stopProcess(void)
|
||||
{
|
||||
theMultiTaskProcess->threadStopped();
|
||||
}
|
||||
|
||||
void Thread::stop(void)
|
||||
{
|
||||
if ( _threadID )
|
||||
@@ -552,3 +536,13 @@ void Thread::stop(void)
|
||||
_threadID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::setTaskName(const char* name)
|
||||
{
|
||||
_taskName = name;
|
||||
}
|
||||
|
||||
const char* Thread::getTaskName(void)
|
||||
{
|
||||
return _taskName;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace MQTTSNGW
|
||||
#define MQTTSNGW_RB_MUTEX_KEY "rbmutex.key"
|
||||
#define MQTTSNGW_RB_SEMAPHOR_NAME "/rbsemaphor"
|
||||
|
||||
#define RED_HDR "\033[0m\033[0;31m"
|
||||
#define CLR_HDR "\033[0m\033[0;37m"
|
||||
|
||||
/*=====================================
|
||||
Class Mutex
|
||||
====================================*/
|
||||
@@ -92,8 +95,7 @@ private:
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer();
|
||||
RingBuffer(const char* keyDirctory);
|
||||
RingBuffer(const char* keyDirectory = MQTTSNGW_KEY_DIRECTORY);
|
||||
~RingBuffer();
|
||||
void put(char* buffer);
|
||||
int get(char* buffer, int bufferLength);
|
||||
@@ -127,12 +129,14 @@ public: void EXECRUN() \
|
||||
try \
|
||||
{ \
|
||||
run(); \
|
||||
stopProcess(); \
|
||||
} \
|
||||
catch(...) \
|
||||
catch ( Exception &ex ) \
|
||||
{ \
|
||||
throw; \
|
||||
ex.writeMessage(); \
|
||||
WRITELOG("%s%s caught an exception and stopped.%s\n", RED_HDR, getTaskName(), CLR_HDR); \
|
||||
theMultiTaskProcess->abort(); \
|
||||
} \
|
||||
theMultiTaskProcess->threadStopped(); \
|
||||
}
|
||||
|
||||
/*=====================================
|
||||
@@ -146,12 +150,15 @@ public:
|
||||
static pthread_t getID();
|
||||
static bool equals(pthread_t*, pthread_t*);
|
||||
virtual void initialize(int argc, char** argv);
|
||||
void stopProcess(void);
|
||||
void waitStop(void);
|
||||
void stop(void);
|
||||
const char* getTaskName(void);
|
||||
void setTaskName(const char* name);
|
||||
void abort(int threadNo);
|
||||
private:
|
||||
static void* _run(void*);
|
||||
pthread_t _threadID;
|
||||
const char* _taskName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user