Merge pull request #245 from eclipse/develop

Update Gateway
This commit is contained in:
Tomoaki Yamaguchi
2021-09-16 15:32:13 +09:00
committed by GitHub
138 changed files with 13504 additions and 7737 deletions

540
.cproject
View File

@@ -1,352 +1,192 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> <?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<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">
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1685199227"> <externalSettings/>
<extensions>
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug"> <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"/>
<externalSettings/> <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"/>
<extensions> <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"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> </extensions>
</storageModule>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <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">
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <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">
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <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" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> <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">
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <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.default" valueType="enumerated"/>
</extensions> <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"/>
</storageModule> <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="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}&quot;"/>
<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"> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/>
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath=""> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNClient/src}&quot;"/>
</option>
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <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"/>
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> <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">
<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"/> <listOptionValue builtIn="false" value="DTLS"/>
</option>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.602829827" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> <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.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> <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.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.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">
<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"/> <listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
</option>
<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 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="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}&quot;"/>
<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>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
<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"> </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">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/> <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/> </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">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/> <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" value="ssl"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNClient/src}&quot;"/> <listOptionValue builtIn="false" value="crypto"/>
<listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/> <listOptionValue builtIn="false" value="bluetooth"/>
</option>
</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"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> </option>
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
</tool> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<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"/> </tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<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"/> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> </toolChain>
</folderInfo>
</tool> <sourceEntries>
<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"/>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"> <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"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input"> </sourceEntries>
</configuration>
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> </cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
</inputType> <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/>
</tool> <extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> <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"/>
<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"> <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"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="pthread"/> <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/> <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="">
</option> <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"/>
<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"> <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"/>
<listOptionValue builtIn="false" value="/usr/local/lib"/> <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> <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"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <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="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/>
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/>
</inputType> </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"/>
</tool> <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.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> <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"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> <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>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2140499460" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
</toolChain> <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.46435036" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
</folderInfo> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<sourceEntries> </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">
<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=""/> <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"/>
</sourceEntries> <listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
</configuration> </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">
</storageModule> <listOptionValue builtIn="false" value="/usr/local/lib"/>
</option>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
</cconfiguration> <additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339"> </tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release"> <inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<externalSettings/> </toolChain>
</folderInfo>
<extensions> <sourceEntries>
<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=""/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/> <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"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
</sourceEntries>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> </configuration>
</storageModule>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> <project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
</storageModule>
</extensions> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
</storageModule> <configuration configurationName="Debug"/>
<configuration configurationName="Release">
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
</configuration>
<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"> </storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath=""> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="scannerConfiguration">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> <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.cpp.compiler.exe.debug.109068141;cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<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"/> <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=""/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> </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">
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<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"/> <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=""/>
<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"/> </scannerConfigBuildInfo>
</storageModule>
<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"/> </cproject>
<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="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNPacket/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}&quot;"/>
</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 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="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>
</storageModule>
</cproject>

11
.gitignore vendored
View File

@@ -5,8 +5,15 @@
*.pyc *.pyc
/doc/MQTTSNClient/ /doc/MQTTSNClient/
/doc/MQTTSNPacket/ /doc/MQTTSNPacket/
/rbmutex.key rbmutex.key
/ringbuffer.key ringbuffer.key
/Release/ /Release/
/Debug/ /Debug/
/core /core
Build/
*.a
CMakeFiles/
*.cmake
CMakeCache.txt
bin/
/build.gateway/

View File

@@ -1,48 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project> <project>
<configuration id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug">
<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"/>
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> <language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> </extension>
</configuration>
<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 &quot;${INPUTS}&quot;" prefer-non-shared="true"> <configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<language-scope id="org.eclipse.cdt.core.gcc"/> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<language-scope id="org.eclipse.cdt.core.g++"/> <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="-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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
</provider> <language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</extension> </provider>
</extension>
</configuration> </configuration>
</project>
<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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View 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}

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
formatter_settings_version=1

View File

@@ -13,19 +13,11 @@ addons:
- g++-4.8 - g++-4.8
- cmake - cmake
- cmake-data - cmake-data
- bluez
- libbluetooth-dev
script: script:
- ./travis-build.sh - ./travis-build.sh
- cd MQTTSNGateway
- make SENSORNET="xbee"
- make SENSORNET="udp"
- make SENSORNET="udp6"
- make test
- cd GatewayTester
- make
notifications: notifications:
emails: emails:

View File

@@ -14,7 +14,7 @@
# Ian Craggs - initial version # Ian Craggs - initial version
#*******************************************************************************/ #*******************************************************************************/
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
PROJECT("paho-mqttsn" CXX) PROJECT("paho-mqttsn" CXX)
MESSAGE(STATUS "CMake version: " ${CMAKE_VERSION}) MESSAGE(STATUS "CMake version: " ${CMAKE_VERSION})
MESSAGE(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME}) MESSAGE(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
@@ -39,3 +39,4 @@ INCLUDE(CPack)
ENABLE_TESTING() ENABLE_TESTING()
ADD_SUBDIRECTORY(MQTTSNPacket) ADD_SUBDIRECTORY(MQTTSNPacket)
ADD_SUBDIRECTORY(MQTTSNGateway)

View 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)

Binary file not shown.

View File

@@ -20,6 +20,10 @@ CPPSRCS := \
$(SUBDIR)/LGwProxy.cpp \ $(SUBDIR)/LGwProxy.cpp \
$(SUBDIR)/LMqttsnClient.cpp \ $(SUBDIR)/LMqttsnClient.cpp \
$(SUBDIR)/LNetworkUdp.cpp \ $(SUBDIR)/LNetworkUdp.cpp \
$(SUBDIR)/LNetworkUdp6.cpp \
$(SUBDIR)/LNetworkRfcomm.cpp \
$(SUBDIR)/LNetworkDtls.cpp \
$(SUBDIR)/LNetworkDtls6.cpp \
$(SUBDIR)/LPublishManager.cpp \ $(SUBDIR)/LPublishManager.cpp \
$(SUBDIR)/LRegisterManager.cpp \ $(SUBDIR)/LRegisterManager.cpp \
$(SUBDIR)/LSubscribeManager.cpp \ $(SUBDIR)/LSubscribeManager.cpp \
@@ -36,12 +40,14 @@ $(SUBDIR)/Util.cpp \
CXX := g++ CXX := g++
CPPFLAGS += CPPFLAGS +=
INCLUDES += -I$(SUBDIR) INCLUDES += -I$(SUBDIR) -I/usr/local/opt/openssl/include
DEFS := DEF1 :=
LIBS += DEF2 :=
DEFS := -D$(SN) $(DEF1) $(DEF2)
LIBS += -L/usr/local/lib -L/usr/local/opt/openssl/lib
LDFLAGS := LDFLAGS :=
CXXFLAGS := -Wall -O3 -std=c++11 CXXFLAGS := -Wall -O3 -std=c++11
LDADD := LDADD := -lssl -lcrypto $(LDADDBLT)
OUTDIR := Build OUTDIR := Build
PROG := $(OUTDIR)/$(PROGTEST) PROG := $(OUTDIR)/$(PROGTEST)
@@ -75,23 +81,23 @@ $(PROGQOS): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/$(QOSAPPL).o
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp $(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @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 $(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @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 $(OUTDIR)/$(SRCDIR)/$(SRCPUB)/%.o:$(SRCDIR)/$(SRCPUB)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @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 $(OUTDIR)/$(SRCDIR)/$(SRCSUB)/%.o:$(SRCDIR)/$(SRCSUB)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @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 $(OUTDIR)/$(SRCDIR)/$(SRCQOS)/%.o:$(SRCDIR)/$(SRCQOS)%.cpp
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi @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: clean:
rm -rf $(OUTDIR) rm -rf $(OUTDIR)

View File

@@ -1,119 +1,117 @@
###Gateway Test Program. # Gateway Test Program.
**sample/mainTest.cpp** is a Test sample coading. **sample/mainTest.cpp** is a Test sample coading.
Each test is described as one function. test1(), test2()... 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) void test1(void)
{ {
char payload[300]; char payload[300];
sprintf(payload, "ESP8266-08b133 "); sprintf(payload, "ESP8266-08b133 ");
uint8_t qos = 0; uint8_t qos = 0;
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos); PUBLISH(topic1,(uint8_t*)payload, strlen(payload), qos);
} }
void test2(void) void test2(void)
{ {
uint8_t qos = 1; uint8_t qos = 1;
SUBSCRIBE(topic2, on_publish02, qos); 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 * A List of Test Tasks
*------------------------------------------------------*/ *------------------------------------------------------*/
TEST_LIST = {// e.g. TEST( Label, Test), TEST_LIST = {// e.g. TEST( Label, Test),
TEST("Publish topic1", test1), TEST("Publish topic1", test1),
TEST("Subscribe topic2", test2), TEST("Subscribe topic2", test2),
TEST("Publish topic2", test3), TEST("Publish topic2", test3),
TEST("Unsubscribe topic2", test4), TEST("Unsubscribe topic2", test4),
TEST("Publish topic2", test3), TEST("Publish topic2", test3),
TEST("Disconnect", test5), TEST("Disconnect", test5),
END_OF_TEST_LIST END_OF_TEST_LIST
}; };
````
```
### **step1. Build ** **UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
```` ```
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c /*------------------------------------------------------
* 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
};
```
## How to Build
```
copy codes from the github.
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester $ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
$ make $ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
$ make install
$ make clean
``` ```
MQTT-SNGatewayTester program is copied into ../../../ directory.
### **step2. Execute Gateway Tester.** ## Execute Gateway Tester
```
```` $ ./Build/MQTT-SNGatewayTester
$ cd ../../..
$ ./MQTT-SNGatewayTester
*************************************************************************** ***************************************************************************
* MQTT-SN Gateway Tester * MQTT-SN Gateway Tester DTLS
* Part of Project Paho in Eclipse * Part of Project Paho in Eclipse
* (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/) * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
* *
* Author : Tomoaki YAMAGUCHI * Author : Tomoaki YAMAGUCHI
* Version: 0.0.0 * Version: 2.0.0
*************************************************************************** ***************************************************************************
Attempting to Connect the Broker..... 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 ) :
````

View 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

View File

@@ -51,12 +51,29 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "ClientPUB", // ClientId
"ClientPUB", // ClientId { 225, 1, 1, 1 }, // Multicast group IP
{225,1,1,1}, // Multicast group IP 1883, // Multicast group Port
1883, // Multicast group Port 20010, // Local PortNo
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) * Client Configuration (theMqcon)
@@ -117,7 +134,7 @@ void publishTopic57(void)
char payload[300]; char payload[300];
sprintf(payload, "publish \"ty4tw/topic57\" \n"); sprintf(payload, "publish \"ty4tw/topic57\" \n");
uint8_t qos = 0; uint8_t qos = 0;
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos); PUBLISH(topic57, (uint8_t* )payload, strlen(payload), qos);
} }

View File

@@ -51,12 +51,29 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "QoS-1_Client01", // ClientId
"QoS-1_Client01", // ClientId { 225, 1, 1, 1 }, // Multicast group IP
{225,1,1,1}, // Multicast group IP 1883, // Multicast group Port
1883, // Multicast group Port 20001, // Local PortNo
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) * Client Configuration (theMqcon)

View File

@@ -51,12 +51,29 @@ extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "ClientSUB", // ClientId
"ClientSUB", // ClientId { 225, 1, 1, 1 }, // Multicast group IP
{225,1,1,1}, // Multicast group IP 1883, // Multicast group Port
1883, // Multicast group Port 20011, // Local PortNo
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) * Client Configuration (theMqcon)

View File

@@ -20,13 +20,13 @@
* *
* void PUBLISH ( uint16_t topicId, 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 ( const char* topicName, TopicCallback onPublish, uint8_t qos );
* *
* void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos ); * void SUBSCRIBE ( uint16_t topicId, TopicCallback onPublish, uint8_t qos );
* *
* void UNSUBSCRIBE ( const char* topicName ); * void UNSUBSCRIBE ( const char* topicName );
* *
* void UNSUBSCRIBE ( uint16_t topicId ); * void UNSUBSCRIBE ( uint16_t topicId );
* *
* void DISCONNECT ( uint16_t sleepInSecs ); * void DISCONNECT ( uint16_t sleepInSecs );
* *
@@ -49,27 +49,43 @@ extern LMqttsnClient* theClient;
extern LScreen* theScreen; extern LScreen* theScreen;
/*------------------------------------------------------ /*------------------------------------------------------
* UDP Configuration (theNetcon) * UDP,DTLS Configuration (theNetcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
UDPCONF = { UDPCONF = { "GatewayTestClient", // ClientId
"GatewayTestClient", // ClientId { 225, 1, 1, 1 }, // Multicast group IP
{225,1,1,1}, // Multicast group IP 1883, // Multicast group Port
1883, // Multicast group Port 20020, // Local PortNo
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) * Client Configuration (theMqcon)
*------------------------------------------------------*/ *------------------------------------------------------*/
MQTTSNCONF = { MQTTSNCONF = { 60, //KeepAlive [seconds]
60, //KeepAlive [seconds] true, //Clean session
true, //Clean session 300, //Sleep duration [seconds]
300, //Sleep duration [seconds] "", //WillTopic
"", //WillTopic "", //WillMessage
"", //WillMessage 0, //WillQos
0, //WillQos false //WillRetain
false //WillRetain };
};
/*------------------------------------------------------ /*------------------------------------------------------
* Define Topics * Define Topics
@@ -78,37 +94,45 @@ const char* topic1 = "ty4tw/topic1";
const char* topic2 = "ty4tw/topic2"; const char* topic2 = "ty4tw/topic2";
const char* topic3 = "ty4tw/topic3"; const char* topic3 = "ty4tw/topic3";
const char* topic4 = "ty4tw/topic4"; const char* topic4 = "ty4tw/topic4";
const char* topic40 = "ty4tw/#";
const char* topic51 = "ty4tw/topic5/1"; const char* topic51 = "ty4tw/topic5/1";
const char* topic52 = "ty4tw/topic5/2"; const char* topic52 = "ty4tw/topic5/2";
const char* topic53 = "ty4tw/topic5/3"; const char* topic53 = "ty4tw/topic5/3";
const char* topic50 = "ty4tw/topic5/+"; const char* topic50 = "ty4tw/topic5/+";
/*------------------------------------------------------ /*------------------------------------------------------
* Callback routines for Subscribed Topics * Callback routines for Subscribed Topics
*------------------------------------------------------*/ *------------------------------------------------------*/
int on_Topic01(uint8_t* pload, uint16_t ploadlen) int on_Topic01(uint8_t* pload, uint16_t ploadlen)
{ {
DISPLAY("\n\nTopic1 recv.\n"); DISPLAY("\n\nTopic1 recv.\n");
char c = pload[ploadlen-1]; char c = pload[ploadlen - 1];
pload[ploadlen-1]= 0; // set null terminator pload[ploadlen - 1] = 0; // set null terminator
DISPLAY("Payload -->%s%c<--\n\n",pload, c); DISPLAY("Payload -->%s%c<--\n\n", pload, c);
return 0; return 0;
} }
int on_Topic02(uint8_t* pload, uint16_t ploadlen) int on_Topic02(uint8_t* pload, uint16_t ploadlen)
{ {
DISPLAY("\n\nTopic2 recv.\n"); DISPLAY("\n\nTopic2 recv.\n");
pload[ploadlen-1]= 0; // set null terminator pload[ploadlen - 1] = 0; // set null terminator
DISPLAY("Payload -->%s <--\n\n",pload); DISPLAY("Payload -->%s <--\n\n", pload);
return 0; return 0;
} }
int on_Topic03(uint8_t* pload, uint16_t ploadlen) int on_Topic03(uint8_t* pload, uint16_t ploadlen)
{ {
DISPLAY("\n\nNew callback recv Topic3\n"); DISPLAY("\n\nNew callback recv Topic3\n");
pload[ploadlen-1]= 0; // set null terminator pload[ploadlen - 1] = 0; // set null terminator
DISPLAY("Payload -->%s <--\n\n",pload); 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; return 0;
} }
@@ -116,40 +140,51 @@ int on_Topic03(uint8_t* pload, uint16_t ploadlen)
* A Link list of Callback routines and Topics * A Link list of Callback routines and Topics
*------------------------------------------------------*/ *------------------------------------------------------*/
SUBSCRIBE_LIST = {// e.g. SUB(TopicType, topicName, TopicId, callback, QoSx), SUBSCRIBE_LIST =
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1), { // e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1), SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
END_OF_SUBSCRIBE_LIST SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
}; END_OF_SUBSCRIBE_LIST
};
/*------------------------------------------------------ /*------------------------------------------------------
* Test functions * Test functions
*------------------------------------------------------*/ *------------------------------------------------------*/
void subscribePredefTopic1(void) void subscribePredefTopic1(void)
{ {
SUBSCRIBE(1, on_Topic03, QoS1); SUBSCRIBE_PREDEF(1, on_Topic03, QoS1);
} }
void publishTopic1(void) void publishTopic1(void)
{ {
char payload[300]; char payload[300];
sprintf(payload, "publish \"ty4tw/Topic1\" \n"); sprintf(payload, "publish \"ty4tw/topic1\" \n");
PUBLISH(topic1,(uint8_t*)payload, strlen(payload), QoS0); PUBLISH(topic1, (uint8_t* )payload, strlen(payload), QoS0);
}
void subscribeTopic10(void)
{
SUBSCRIBE(10, on_Topic02, QoS1);
} }
void publishTopic2(void) void publishTopic2(void)
{ {
char payload[300]; char payload[300];
sprintf(payload, "publish \"ty4tw/topic2\" \n"); 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) void unsubscribe(void)
@@ -167,7 +202,7 @@ void test3(void)
char payload[300]; char payload[300];
sprintf(payload, "TEST3 "); sprintf(payload, "TEST3 ");
uint8_t qos = 0; uint8_t qos = 0;
PUBLISH(topic2,(uint8_t*)payload, strlen(payload), qos); PUBLISH(topic2, (uint8_t* )payload, strlen(payload), qos);
} }
void disconnect(void) void disconnect(void)
@@ -180,48 +215,76 @@ void asleep(void)
DISCONNECT(theMqcon.sleepDuration); 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 * A List of Test functions is valid in case of
* line 23 of LMqttsnClientApp.h is commented out. * line 23 of LMqttsnClientApp.h is commented out.
* //#define CLIENT_MODE * //#define CLIENT_MODE
*------------------------------------------------------*/ *------------------------------------------------------*/
TEST_LIST = {// e.g. TEST( Label, Test), TEST_LIST =
TEST("Step0:Subscribe predef topic1", subscribePredefTopic1), { // e.g. TEST( Label, Test),
TEST("Step1:Publish topic1", publishTopic1), TEST("Step0:Connect", connect),
TEST("Step2:Publish topic2", publishTopic2), TEST("Step1:Subscribe list", onconnect),
TEST("Step3:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10), TEST("Step2:Subscribe predef topic1", subscribePredefTopic1),
TEST("Step4:Publish topic2", publishTopic2), TEST("Step3:Publish topic1", publishTopic1),
TEST("Step5:Unsubscribe topic2", unsubscribe), TEST("Step4:Publish topic2", publishTopic2),
TEST("Step6:Publish topic2", publishTopic2), TEST("Step5:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
TEST("Step7:subscribe again", subscribechangeCallback), TEST("Step6:Publish topic2", publishTopic2),
TEST("Step8:Publish topic2", publishTopic2), TEST("Step7:Unsubscribe topic2", unsubscribe),
TEST("Step9:Sleep ", asleep), TEST("Step8:Publish topic2", publishTopic2),
TEST("Step10:Publish topic1", publishTopic1), TEST("Step9:subscribe again", subscribechangeCallback),
TEST("Step11:Disconnect", disconnect), TEST("Step10:Publish topic2", publishTopic2),
END_OF_TEST_LIST
};
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 * List of tasks is valid in case of line23 of
* LMqttsnClientApp.h is uncommented. * LMqttsnClientApp.h is uncommented.
* #define CLIENT_MODE * #define CLIENT_MODE
*------------------------------------------------------*/ *------------------------------------------------------*/
TASK_LIST = {// e.g. TASK( task, executing duration in second), TASK_LIST =
TASK(publishTopic1, 4), // publishTopic1() is executed every 4 seconds { // e.g. TASK( task, executing duration in second),
TASK(publishTopic2, 7), // publishTopic2() is executed every 7 seconds TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
END_OF_TASK_LIST TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
}; END_OF_TASK_LIST
};
/*------------------------------------------------------ /*------------------------------------------------------
* Initialize function * Initialize function
*------------------------------------------------------*/ *------------------------------------------------------*/
void setup(void) void setup(void)
{ {
SetForwarderMode(false); SetForwarderMode(false);
} }
/***************** END OF PROGRAM ********************/ /***************** END OF PROGRAM ********************/

View File

@@ -57,6 +57,8 @@ LGwProxy::LGwProxy()
_initialized = 0; _initialized = 0;
_isForwarderMode = false; _isForwarderMode = false;
_isQoSMinus1Mode = false; _isQoSMinus1Mode = false;
_isPingReqMode = true;
_isAutoConnectMode = true;
} }
LGwProxy::~LGwProxy() LGwProxy::~LGwProxy()
@@ -64,16 +66,20 @@ LGwProxy::~LGwProxy()
_topicTbl.clearTopic(); _topicTbl.clearTopic();
} }
void LGwProxy::initialize(LUdpConfig netconf, LMqttsnConfig mqconf) void LGwProxy::initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf)
{ {
_network.initialize(netconf); if (_network.initialize(netconf) == false)
_clientId = netconf.clientId; {
_willTopic = mqconf.willTopic; DISPLAY("Can't open SensorNetwork\n");
_willMsg = mqconf.willMsg; exit(-1);
_qosWill = mqconf.willQos; }
_retainWill = mqconf.willRetain; _clientId = netconf->clientId;
_cleanSession = mqconf.cleanSession; _willTopic = mqconf->willTopic;
_tkeepAlive = mqconf.keepAlive; _willMsg = mqconf->willMsg;
_qosWill = mqconf->willQos;
_retainWill = mqconf->willRetain;
_cleanSession = mqconf->cleanSession;
_tkeepAlive = mqconf->keepAlive;
_initialized = 1; _initialized = 1;
} }
@@ -85,6 +91,12 @@ void LGwProxy::connect()
{ {
pos = _msg; pos = _msg;
if (!_network.isBroadcastable() && _status == GW_LOST)
{
_status = GW_CONNECTING;
continue;
}
if (_status == GW_LOST) if (_status == GW_LOST)
{ {
@@ -188,7 +200,24 @@ int LGwProxy::getConnectResponce(void)
{ {
_network.setGwAddress(); _network.setGwAddress();
_gwId = _mqttsnMsg[1]; _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; _status = GW_CONNECTING;
#endif
} }
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ) else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
{ {
@@ -231,9 +260,12 @@ int LGwProxy::getConnectResponce(void)
void LGwProxy::reconnect(void) void LGwProxy::reconnect(void)
{ {
D_MQTTLOG("...Gateway reconnect\r\n"); if (_isAutoConnectMode)
_status = GW_DISCONNECTED; {
connect(); D_MQTTLOG("...Gateway reconnect\r\n");
_status = GW_DISCONNECTED;
connect();
}
} }
void LGwProxy::disconnect(uint16_t secs) void LGwProxy::disconnect(uint16_t secs)
@@ -395,7 +427,7 @@ int LGwProxy::getMessage(void)
} }
else if (_mqttsnMsg[0] == MQTTSN_TYPE_DISCONNECT) else if (_mqttsnMsg[0] == MQTTSN_TYPE_DISCONNECT)
{ {
_status = GW_LOST; _status = GW_DISCONNECTED;
_gwAliveTimer.stop(); _gwAliveTimer.stop();
_keepAliveTimer.stop(); _keepAliveTimer.stop();
} }
@@ -586,7 +618,7 @@ uint16_t LGwProxy::getNextMsgId(void)
void LGwProxy::checkPingReq(void) void LGwProxy::checkPingReq(void)
{ {
if ( _isQoSMinus1Mode ) if (_isQoSMinus1Mode || _isPingReqMode == false)
{ {
return; return;
} }
@@ -671,3 +703,23 @@ void LGwProxy::setQoSMinus1Mode(bool valid)
{ {
_isQoSMinus1Mode = 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;
}

View File

@@ -23,6 +23,10 @@
#include "LMqttsnClientApp.h" #include "LMqttsnClientApp.h"
#include "LNetworkUdp.h" #include "LNetworkUdp.h"
#include "LNetworkUdp6.h"
#include "LNetworkRfcomm.h"
#include "LNetworkDtls.h"
#include "LNetworkDtls6.h"
#include "LRegisterManager.h" #include "LRegisterManager.h"
#include "LTimer.h" #include "LTimer.h"
#include "LTopicTable.h" #include "LTopicTable.h"
@@ -42,6 +46,7 @@ using namespace std;
#define GW_SLEEPING 10 #define GW_SLEEPING 10
#define GW_DISCONNECTED 11 #define GW_DISCONNECTED 11
#define GW_SLEPT 12 #define GW_SLEPT 12
#define SSL_CONNECTING 13
#define GW_WAIT_PINGRESP 1 #define GW_WAIT_PINGRESP 1
@@ -54,7 +59,7 @@ public:
LGwProxy(); LGwProxy();
~LGwProxy(); ~LGwProxy();
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf); void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
void connect(void); void connect(void);
void disconnect(uint16_t sec = 0); void disconnect(uint16_t sec = 0);
int getMessage(void); int getMessage(void);
@@ -67,6 +72,9 @@ public:
void setAdvertiseDuration(uint16_t duration); void setAdvertiseDuration(uint16_t duration);
void setForwarderMode(bool valid); void setForwarderMode(bool valid);
void setQoSMinus1Mode(bool valid); void setQoSMinus1Mode(bool valid);
void setPingReqMode(bool valid);
void setAutoConnectMode(bool valid);
void setSessionMode(bool valid);
void reconnect(void); void reconnect(void);
int writeMsg(const uint8_t* msg); int writeMsg(const uint8_t* msg);
void setPingReqTimer(void); void setPingReqTimer(void);
@@ -74,6 +82,7 @@ public:
LTopicTable* getTopicTable(void); LTopicTable* getTopicTable(void);
LRegisterManager* getRegisterManager(void); LRegisterManager* getRegisterManager(void);
const char* getClientId(void); const char* getClientId(void);
uint8_t getStatus(void);
private: private:
int readMsg(void); int readMsg(void);
void writeGwMsg(void); void writeGwMsg(void);
@@ -109,8 +118,10 @@ private:
LTimer _keepAliveTimer; LTimer _keepAliveTimer;
uint16_t _tSleep; uint16_t _tSleep;
uint16_t _tWake; uint16_t _tWake;
bool _isForwarderMode; bool _isForwarderMode;
bool _isQoSMinus1Mode; bool _isQoSMinus1Mode;
bool _isPingReqMode;
bool _isAutoConnectMode;
char _msg[MQTTSN_MAX_MSG_LENGTH + 1]; char _msg[MQTTSN_MAX_MSG_LENGTH + 1];
}; };

View File

@@ -29,7 +29,7 @@ extern TaskList theTaskList[];
extern TestList theTestList[]; extern TestList theTestList[];
extern OnPublishList theOnPublishList[]; extern OnPublishList theOnPublishList[];
extern MQTTSNCONF; extern MQTTSNCONF;
extern UDPCONF; extern SENSORNET_CONFIG_t theNetcon;
extern void setup(void); extern void setup(void);
/*===================================== /*=====================================
@@ -50,7 +50,20 @@ int main(int argc, char** argv)
#ifndef CLIENT_MODE #ifndef CLIENT_MODE
char c = 0; char c = 0;
printf("\n%s", PAHO_COPYRIGHT4); 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_COPYRIGHT1);
printf("%s\n", PAHO_COPYRIGHT2); printf("%s\n", PAHO_COPYRIGHT2);
printf(" *\n%s\n", PAHO_COPYRIGHT3); printf(" *\n%s\n", PAHO_COPYRIGHT3);
@@ -77,11 +90,13 @@ int main(int argc, char** argv)
break; break;
} }
} }
theClient->setAutoConnectMode(false);
theClient->getPublishManager()->setAutoConnectMode(false);
#endif #endif
setup(); setup();
theClient->addTask(theClientMode); theClient->addTask(theClientMode);
theClient->initialize( theNetcon, theMqcon); theClient->initialize( &theNetcon, &theMqcon);
do do
{ {
theClient->run(); theClient->run();
@@ -98,7 +113,7 @@ int main(int argc, char** argv)
======================================*/ ======================================*/
LMqttsnClient::LMqttsnClient() LMqttsnClient::LMqttsnClient()
{ {
_isAutoConnect = true;
} }
LMqttsnClient::~LMqttsnClient() 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); _gwProxy.initialize(netconf, mqconf);
setSleepDuration(mqconf.sleepDuration); setSleepDuration(mqconf->sleepDuration);
} }
void LMqttsnClient::addTask(bool clientMode) void LMqttsnClient::addTask(bool clientMode)
@@ -183,9 +198,10 @@ void LMqttsnClient::subscribe(const char* topicName, TopicCallback onPublish, ui
_subMgr.subscribe(topicName, onPublish, qos); _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) void LMqttsnClient::unsubscribe(const char* topicName)
@@ -205,10 +221,20 @@ void LMqttsnClient::disconnect(uint16_t sleepInSecs)
void LMqttsnClient::run() void LMqttsnClient::run()
{ {
_gwProxy.connect(); if (_isAutoConnect)
{
_gwProxy.connect();
}
_taskMgr.run(); _taskMgr.run();
} }
void LMqttsnClient::setAutoConnectMode(uint8_t flg)
{
_isAutoConnect = flg;
_pubMgr.setAutoConnectMode(flg);
_gwProxy.setAutoConnectMode(flg);
}
void LMqttsnClient::setSleepMode(uint32_t duration) void LMqttsnClient::setSleepMode(uint32_t duration)
{ {
// ToDo: set WDT and sleep mode // ToDo: set WDT and sleep mode
@@ -227,7 +253,10 @@ void LMqttsnClient::setSleepDuration(uint32_t duration)
void LMqttsnClient::onConnect(void) void LMqttsnClient::onConnect(void)
{ {
if (_isAutoConnect)
{
_subMgr.onConnect(); _subMgr.onConnect();
}
} }
const char* LMqttsnClient::getClientId(void) const char* LMqttsnClient::getClientId(void)

View File

@@ -54,15 +54,16 @@ public:
void publish(uint16_t topicId, Payload* payload, uint8_t qos, bool retain = false); 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 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(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 char* topicName);
void unsubscribe(const uint16_t topicId); void unsubscribe(const uint16_t topicId);
void disconnect(uint16_t sleepInSecs); void disconnect(uint16_t sleepInSecs);
void initialize(LUdpConfig netconf, LMqttsnConfig mqconf); void initialize(SENSORNET_CONFIG_t* netconf, LMqttsnConfig* mqconf);
void run(void); void run(void);
void addTask(bool test); void addTask(bool test);
void setSleepDuration(uint32_t duration); void setSleepDuration(uint32_t duration);
void setSleepMode(uint32_t duration); void setSleepMode(uint32_t duration);
void setAutoConnectMode(uint8_t flg);
void sleep(void); void sleep(void);
const char* getClientId(void); const char* getClientId(void);
uint16_t getTopicId(const char* topicName); uint16_t getTopicId(const char* topicName);
@@ -78,6 +79,7 @@ private:
LSubscribeManager _subMgr; LSubscribeManager _subMgr;
LGwProxy _gwProxy; LGwProxy _gwProxy;
uint32_t _sleepDuration; uint32_t _sleepDuration;
uint8_t _isAutoConnect;
}; };

View File

@@ -17,17 +17,17 @@
#ifndef MQTTSNCLIENTAPP_H_ #ifndef MQTTSNCLIENTAPP_H_
#define MQTTSNCLIENTAPP_H_ #define MQTTSNCLIENTAPP_H_
/*======================================
* Program mode Flag
======================================*/
//#define CLIENT_MODE
/*====================================== /*======================================
* Debug Flag * Debug Flag
======================================*/ ======================================*/
//#define DEBUG_NW //#define DEBUG_NW
//#define DEBUG_MQTTSN //#define DEBUG_MQTTSN
/*======================================
* Program mode Flag
======================================*/
//#define CLIENT_MODE
/**************************************** /****************************************
MQTT-SN Parameters MQTT-SN Parameters
*****************************************/ *****************************************/
@@ -55,7 +55,8 @@ typedef signed int int32_t;
Application config structures Application config structures
*****************************************/ *****************************************/
struct LMqttsnConfig{ struct LMqttsnConfig
{
uint16_t keepAlive; uint16_t keepAlive;
bool cleanSession; bool cleanSession;
uint32_t sleepDuration; uint32_t sleepDuration;
@@ -65,13 +66,30 @@ struct LMqttsnConfig{
bool willRetain; bool willRetain;
}; };
struct LUdpConfig{ struct LUdpConfig
{
const char* clientId; const char* clientId;
uint8_t ipAddress[4]; uint8_t ipAddress[4];
uint16_t gPortNo; uint16_t gPortNo;
uint16_t uPortNo; 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 typedef enum
{ {
@@ -85,13 +103,50 @@ typedef enum
MACROs for Application MACROs for Application
=======================================*/ =======================================*/
#define MQTTSN_CONFIG MqttsnConfig theMqttsnConfig #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 CONNECT(...) theClient->getGwProxy()->connect(__VA_ARGS__)
#define PUBLISH(...) theClient->publish(__VA_ARGS__) #define PUBLISH(...) theClient->publish(__VA_ARGS__)
#define SUBSCRIBE(...) theClient->subscribe(__VA_ARGS__) #define SUBSCRIBE(...) theClient->subscribe(__VA_ARGS__)
#define SUBSCRIBE_PREDEF(...) theClient->subscribePredefinedId(__VA_ARGS__)
#define UNSUBSCRIBE(...) theClient->unsubscribe(__VA_ARGS__) #define UNSUBSCRIBE(...) theClient->unsubscribe(__VA_ARGS__)
#define DISCONNECT(...) theClient->disconnect(__VA_ARGS__) #define DISCONNECT(...) theClient->disconnect(__VA_ARGS__)
#define ONCONNECT() theClient->getSubscribeManager()->onConnect()
#define TASK_LIST TaskList theTaskList[] #define TASK_LIST TaskList theTaskList[]
#define TASK(...) {__VA_ARGS__, 0, 0} #define TASK(...) {__VA_ARGS__, 0, 0}
@@ -102,11 +157,13 @@ typedef enum
#define SUBSCRIBE_LIST OnPublishList theOnPublishList[] #define SUBSCRIBE_LIST OnPublishList theOnPublishList[]
#define SUB(...) {__VA_ARGS__} #define SUB(...) {__VA_ARGS__}
#define END_OF_SUBSCRIBE_LIST {MQTTSN_TOPIC_TYPE_NORMAL,0,0,0, 0} #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 SetForwarderMode(...) theClient->getGwProxy()->setForwarderMode(__VA_ARGS__)
#define SetQoSMinus1Mode(...) theClient->getGwProxy()->setQoSMinus1Mode(__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 #ifdef CLIENT_MODE
#define DISPLAY(...) #define DISPLAY(...)
#define PROMPT(...) #define PROMPT(...)
@@ -195,11 +252,11 @@ typedef enum
/*================================= /*=================================
* Starting prompt * 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_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_COPYRIGHT3 " * Author : Tomoaki YAMAGUCHI"
#define PAHO_COPYRIGHT4 " ***************************************************************************" #define PAHO_COPYRIGHT4 " ***************************************************************************"

View 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

View 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_ */

View 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

View 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_ */

View 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

View 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_ */

View File

@@ -13,6 +13,7 @@
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#ifdef UDP
#include <stdio.h> #include <stdio.h>
#include <sys/time.h> #include <sys/time.h>
@@ -25,365 +26,426 @@
#include <fcntl.h> #include <fcntl.h>
#include <termios.h> #include <termios.h>
#include "LMqttsnClientApp.h"
#include "LNetworkUdp.h" #include "LNetworkUdp.h"
#include "LTimer.h" #include "LTimer.h"
#include "LScreen.h" #include "LScreen.h"
#include "LMqttsnClientApp.h"
using namespace std; using namespace std;
using namespace linuxAsyncClient; using namespace linuxAsyncClient;
extern uint16_t getUint16(const uint8_t* pos); extern uint16_t getUint16(const uint8_t *pos);
extern uint32_t getUint32(const uint8_t* pos); extern uint32_t getUint32(const uint8_t *pos);
extern LScreen* theScreen; extern LScreen *theScreen;
extern bool theClientMode; extern bool theClientMode;
/*========================================= /*=========================================
Class LNetwork Class LNetwork
=========================================*/ =========================================*/
LNetwork::LNetwork(){ LNetwork::LNetwork()
_sleepflg = false; {
resetGwAddress(); _sleepflg = false;
resetGwAddress();
} }
LNetwork::~LNetwork(){ LNetwork::~LNetwork()
{
} }
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen){ int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
return LUdpPort::multicast(xmitData, (uint32_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); {
return LUdpPort::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
} }
uint8_t* LNetwork::getMessage(int *len)
{
*len = 0;
if (checkRecvBuf())
{
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
{
return 0;
}
uint8_t* LNetwork::getMessage(int* len){ if (recvLen < 0)
*len = 0; {
if (checkRecvBuf()){ *len = recvLen;
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo); return 0;
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){ }
return 0; else
} {
if (_rxDataBuf[0] == 0x01)
if(recvLen < 0){ {
*len = recvLen; *len = getUint16(_rxDataBuf + 1);
return 0; }
}else{ else
if(_rxDataBuf[0] == 0x01){ {
*len = getUint16(_rxDataBuf + 1 ); *len = _rxDataBuf[0];
}else{ }
*len = _rxDataBuf[0]; //if(recvLen != *len){
} // *len = 0;
//if(recvLen != *len){ // return 0;
// *len = 0; //}else{
// return 0; return _rxDataBuf;
//}else{ //}
return _rxDataBuf; }
//} }
} return 0;
}
return 0;
} }
void LNetwork::setGwAddress(void){ void LNetwork::setGwAddress(void)
_gwPortNo = _portNo; {
_gwIpAddress = _ipAddress; _gwPortNo = _portNo;
_gwIpAddress = _ipAddress;
} }
void LNetwork::setFixedGwAddress(void){ void LNetwork::setFixedGwAddress(void)
{
_gwPortNo = LUdpPort::_gPortNo; _gwPortNo = LUdpPort::_gPortNo;
_gwIpAddress = LUdpPort::_gIpAddr; _gwIpAddress = LUdpPort::_gIpAddr;
} }
void LNetwork::resetGwAddress(void){ void LNetwork::resetGwAddress(void)
_gwIpAddress = 0; {
_gwPortNo = 0; _gwIpAddress = 0;
_gwPortNo = 0;
} }
bool LNetwork::initialize(LUdpConfig *config)
bool LNetwork::initialize(LUdpConfig config){ {
return LUdpPort::open(config); return LUdpPort::open(config);
} }
void LNetwork::setSleep(){ void LNetwork::setSleep()
_sleepflg = true; {
_sleepflg = true;
} }
bool LNetwork::isBroadcastable()
{
return true;
}
/*========================================= /*=========================================
Class udpStack Class udpStack
=========================================*/ =========================================*/
LUdpPort::LUdpPort(){ LUdpPort::LUdpPort()
{
_disconReq = false; _disconReq = false;
_sockfdUcast = -1; _sockfdUcast = -1;
_sockfdMcast = -1; _sockfdMcast = -1;
_castStat = 0; _castStat = 0;
} }
LUdpPort::~LUdpPort(){ LUdpPort::~LUdpPort()
{
close(); close();
} }
void LUdpPort::close()
void LUdpPort::close(){ {
if(_sockfdMcast > 0){ if (_sockfdMcast > 0)
::close( _sockfdMcast); {
_sockfdMcast = -1; ::close(_sockfdMcast);
if(_sockfdUcast > 0){ _sockfdMcast = -1;
::close( _sockfdUcast); if (_sockfdUcast > 0)
_sockfdUcast = -1; {
} ::close(_sockfdUcast);
} _sockfdUcast = -1;
}
}
} }
bool LUdpPort::open(LUdpConfig config){ bool LUdpPort::open(LUdpConfig *config)
const int reuse = 1; {
char loopch = 1; int optval = 0;
uint8_t sav = config.ipAddress[3]; uint8_t sav = config->ipAddress[3];
config.ipAddress[3] = config.ipAddress[0]; config->ipAddress[3] = config->ipAddress[0];
config.ipAddress[0] = sav; config->ipAddress[0] = sav;
sav = config.ipAddress[2]; sav = config->ipAddress[2];
config.ipAddress[2] = config.ipAddress[1]; config->ipAddress[2] = config->ipAddress[1];
config.ipAddress[1] = sav; config->ipAddress[1] = sav;
_gPortNo = htons(config.gPortNo); _gPortNo = htons(config->gPortNo);
_gIpAddr = getUint32((const uint8_t*)config.ipAddress); _gIpAddr = getUint32((const uint8_t*) config->ipAddress);
_uPortNo = htons(config.uPortNo); _uPortNo = htons(config->uPortNo);
if( _gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0){ if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
return false; {
} return false;
}
_sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0); _sockfdUcast = socket(AF_INET, SOCK_DGRAM, 0);
if (_sockfdUcast < 0){ if (_sockfdUcast < 0)
return false; {
} 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_family = AF_INET;
addr.sin_port = _uPortNo; addr.sin_port = _uPortNo;
addr.sin_addr.s_addr = INADDR_ANY; 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)
return false; {
} 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); _sockfdMcast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (_sockfdMcast < 0){ if (_sockfdMcast < 0)
return false; {
} return false;
}
struct sockaddr_in addrm; sockaddr_in addrm;
addrm.sin_family = AF_INET; addrm.sin_family = AF_INET;
addrm.sin_port = _gPortNo; 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){ if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
return false; {
} D_NWLOG("\033[0m\033[0;31merror %s ::bind() in UdpPort::open\033[0m\033[0;37m\n", strerror(errno));
return false;
}
if(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){ ip_mreq mreq;
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n"); mreq.imr_interface.s_addr = INADDR_ANY;
DISPLAY("\033[0m\033[0;31m\nerror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n"); mreq.imr_multiaddr.s_addr = _gIpAddr;
close();
return false;
}
ip_mreq mreq; if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
mreq.imr_interface.s_addr = INADDR_ANY; {
mreq.imr_multiaddr.s_addr = _gIpAddr; D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
close();
return false;
}
if( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){ optval= 1;
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n"); if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
DISPLAY("\033[0m\033[0;31m\nerror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n"); {
close(); D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
return false; close();
} return false;
return true; }
return true;
} }
bool LUdpPort::isUnicast(){ bool LUdpPort::isUnicast()
return ( _castStat == STAT_UNICAST); {
return (_castStat == STAT_UNICAST);
} }
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 LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){ int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
struct sockaddr_in dest; if (status < 0)
dest.sin_family = AF_INET; {
dest.sin_port = port; D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
dest.sin_addr.s_addr = ipAddress; }
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");
int status = ::sendto( _sockfdUcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) ); if (!theClientMode)
if( status < 0){ {
D_NWLOG("errno == %d in UdpPort::unicast\n", errno); char sbuf[SCREEN_BUFF_SIZE];
DISPLAY("errno == %d in UdpPort::unicast\n", errno); int pos = 0;
}else{ sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
D_NWLOG("sendto %-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++)
D_NWLOG(" %02x", *(buf + i)); {
} sprintf(sbuf + pos, " %02x", *(buf + i));
D_NWLOG("\n"); if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
{
if ( !theClientMode ) break;
{ }
char sbuf[SCREEN_BUFF_SIZE]; pos += 3;
int pos = 0; }
sprintf(sbuf,"\033[0;34msendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port)); sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
pos = strlen(sbuf); }
for(uint16_t i = 0; i < length ; i++){ }
sprintf(sbuf + pos, " %02x", *(buf + i)); return status;
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)
{
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_port = _gPortNo;
dest.sin_addr.s_addr = _gIpAddr;
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){ int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
struct sockaddr_in dest; if (status < 0)
dest.sin_family = AF_INET; {
dest.sin_port = _gPortNo; D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
dest.sin_addr.s_addr = _gIpAddr; return errno;
}
else
{
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
int status = ::sendto( _sockfdMcast, buf, length, 0, (const sockaddr*)&dest, sizeof(dest) ); for (uint16_t i = 0; i < length; i++)
if( status < 0){ {
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno); D_NWLOG(" %02x", *(buf + i));
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno); } D_NWLOG("\n");
return errno;
}else{
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
for(uint16_t i = 0; i < length ; i++){ if (!theClientMode)
D_NWLOG(" %02x", *(buf + i)); {
DISPLAY(" %02x", *(buf + i)); char sbuf[SCREEN_BUFF_SIZE];
} int pos = 0;
D_NWLOG("\n"); sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
pos = strlen(sbuf);
if ( !theClientMode ) for (uint16_t i = 0; i < length; i++)
{ {
char sbuf[SCREEN_BUFF_SIZE]; sprintf(sbuf + pos, " %02x", *(buf + i));
int pos = 0; if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
sprintf(sbuf,"\033[0;34msendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo)); {
pos = strlen(sbuf); break;
for(uint16_t i = 0; i < length ; i++){ }
sprintf(sbuf + pos, " %02x", *(buf + i)); pos += 3;
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20 ) }
{ sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
break; theScreen->display(sbuf);
} }
pos += 3; return status;
} }
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
theScreen->display(sbuf);
}
return status;
}
} }
bool LUdpPort::checkRecvBuf(){ bool LUdpPort::checkRecvBuf()
struct timeval timeout; {
timeout.tv_sec = 0; struct timeval timeout;
timeout.tv_usec = 50000; // 50 msec timeout.tv_sec = 0;
timeout.tv_usec = 50000; // 50 msec
uint8_t buf[2]; uint8_t buf[2];
fd_set recvfds; fd_set recvfds;
int maxSock = 0; int maxSock = 0;
FD_ZERO(&recvfds); FD_ZERO(&recvfds);
FD_SET(_sockfdUcast, &recvfds); FD_SET(_sockfdUcast, &recvfds);
FD_SET(_sockfdMcast, &recvfds); FD_SET(_sockfdMcast, &recvfds);
if(_sockfdMcast > _sockfdUcast){ if (_sockfdMcast > _sockfdUcast)
maxSock = _sockfdMcast; {
}else{ maxSock = _sockfdMcast;
maxSock = _sockfdUcast; }
} else
{
maxSock = _sockfdUcast;
}
select(maxSock + 1, &recvfds, 0, 0, &timeout); select(maxSock + 1, &recvfds, 0, 0, &timeout);
if(FD_ISSET(_sockfdUcast, &recvfds)){ if (FD_ISSET(_sockfdUcast, &recvfds))
if( ::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){ {
_castStat = STAT_UNICAST; if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
return true; {
} _castStat = STAT_UNICAST;
}else if(FD_ISSET(_sockfdMcast, &recvfds)){ return true;
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){ }
_castStat = STAT_MULTICAST; }
return true; else if (FD_ISSET(_sockfdMcast, &recvfds))
} {
} if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
_castStat = 0; {
return false; _castStat = STAT_MULTICAST;
return true;
}
}
_castStat = 0;
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 ); int flags = flg ? MSG_DONTWAIT : 0;
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; struct sockaddr_in sender;
socklen_t addrlen = sizeof(sender); int status;
memset(&sender, 0, addrlen); socklen_t addrlen = sizeof(sender);
memset(&sender, 0, addrlen);
if(isUnicast()){ if (isUnicast())
status = ::recvfrom( _sockfdUcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen ); {
}else if(_castStat == STAT_MULTICAST){ D_NWLOG("Ucast ");
status = ::recvfrom( _sockfdMcast, buf, length, flags, (struct sockaddr*)&sender, &addrlen ); status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
}else{ }
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) { 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); D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
}else if(status > 0){ }
*ipAddressPtr = sender.sin_addr.s_addr; else if (status > 0)
*portPtr = sender.sin_port; {
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr)); *ipAddressPtr = sender.sin_addr.s_addr;
for(uint16_t i = 0; i < status ; i++){ *portPtr = sender.sin_port;
D_NWLOG(" %02x", *(buf + i)); D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
} for (uint16_t i = 0; i < status; i++)
D_NWLOG("\n"); {
D_NWLOG(" %02x", *(buf + i));
} D_NWLOG("\n");
if ( !theClientMode ) if (!theClientMode)
{ {
char sbuf[SCREEN_BUFF_SIZE]; char sbuf[SCREEN_BUFF_SIZE];
int pos = 0; 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); 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 ) sprintf(sbuf + pos, " %02x", *(buf + i));
{ if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
break; {
} break;
pos += 3; }
} pos += 3;
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n"); }
theScreen->display(sbuf); sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
} theScreen->display(sbuf);
return status; }
}else{ return status;
return 0; }
} else
return status; {
return 0;
}
return status;
} }
#endif

View File

@@ -17,6 +17,8 @@
#ifndef NETWORKUDP_H_ #ifndef NETWORKUDP_H_
#define NETWORKUDP_H_ #define NETWORKUDP_H_
#ifdef UDP
#include <sys/time.h> #include <sys/time.h>
#include <iostream> #include <iostream>
#include <sys/types.h> #include <sys/types.h>
@@ -27,8 +29,6 @@
#include <string> #include <string>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "LMqttsnClientApp.h"
#define SOCKET_MAXHOSTNAME 200 #define SOCKET_MAXHOSTNAME 200
#define SOCKET_MAXCONNECTIONS 5 #define SOCKET_MAXCONNECTIONS 5
#define SOCKET_MAXRECV 500 #define SOCKET_MAXRECV 500
@@ -49,7 +49,7 @@ public:
LUdpPort(); LUdpPort();
virtual ~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 unicast(const uint8_t* buf, uint32_t length, uint32_t ipaddress, uint16_t port );
int multicast( const uint8_t* buf, uint32_t length ); int multicast( const uint8_t* buf, uint32_t length );
@@ -87,8 +87,9 @@ public:
void setGwAddress(void); void setGwAddress(void);
void resetGwAddress(void); void resetGwAddress(void);
void setFixedGwAddress(void); void setFixedGwAddress(void);
bool initialize(LUdpConfig config); bool initialize(LUdpConfig* config);
uint8_t* getMessage(int* len); uint8_t* getMessage(int* len);
bool isBroadcastable();
private: private:
void setSleep(); void setSleep();
int readApiFrame(void); int readApiFrame(void);
@@ -103,6 +104,6 @@ private:
}; };
} /* end of namespace */ } /* end of namespace */
#endif /* UDP */
#endif /* NETWORKUDP_H_ */ #endif /* NETWORKUDP_H_ */

View 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 */

View 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_ */

View File

@@ -44,6 +44,7 @@ LPublishManager::LPublishManager()
_last = 0; _last = 0;
_elmCnt = 0; _elmCnt = 0;
_publishedFlg = SAVE_TASK_INDEX; _publishedFlg = SAVE_TASK_INDEX;
_autoConnectFlg = false;
} }
LPublishManager::~LPublishManager() LPublishManager::~LPublishManager()
@@ -115,7 +116,10 @@ void LPublishManager::sendPublish(PubElement* elm)
return; return;
} }
theClient->getGwProxy()->connect(); if (_autoConnectFlg)
{
theClient->getGwProxy()->connect();
}
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1]; uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
uint8_t org = 0; 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* LPublishManager::getElement(uint16_t msgId)
{ {
PubElement* elm = _first; PubElement* elm = _first;

View File

@@ -70,6 +70,7 @@ public:
void sendSuspend(const char* topicName, uint16_t topicId, uint8_t topicType); void sendSuspend(const char* topicName, uint16_t topicId, uint8_t topicType);
bool isDone(void); bool isDone(void);
bool isMaxFlight(void); bool isMaxFlight(void);
void setAutoConnectMode(bool);
private: private:
PubElement* getElement(uint16_t msgId); PubElement* getElement(uint16_t msgId);
PubElement* getElement(const char* topicName); PubElement* getElement(const char* topicName);
@@ -84,7 +85,8 @@ private:
PubElement* _last; PubElement* _last;
uint8_t _elmCnt; uint8_t _elmCnt;
uint8_t _publishedFlg; uint8_t _publishedFlg;
uint8_t _autoConnectFlg;
}; };
} /* tomyAsyncClient */ } /* tomyAsyncClient */
#endif /* PUBLISHMANAGER_H_ */ #endif /* PUBLISHMANAGER_H_ */

View File

@@ -67,7 +67,9 @@ void LSubscribeManager::onConnect(void)
{ {
if ( theOnPublishList[i].type == MQTTSN_TOPIC_TYPE_PREDEFINED) 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 else
{ {
@@ -122,6 +124,7 @@ void LSubscribeManager::send(SubElement* elm)
{ {
return; return;
} }
uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1]; uint8_t msg[MQTTSN_MAX_MSG_LENGTH + 1];
if (elm->topicType == MQTTSN_TOPIC_TYPE_PREDEFINED) if (elm->topicType == MQTTSN_TOPIC_TYPE_PREDEFINED)
{ {
@@ -169,7 +172,7 @@ void LSubscribeManager::subscribe(const char* topicName, TopicCallback onPublish
send(elm); 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); SubElement* elm = add(MQTTSN_TYPE_SUBSCRIBE, 0, MQTTSN_TOPIC_TYPE_PREDEFINED, topicId, qos, onPublish);
send(elm); send(elm);
@@ -262,7 +265,9 @@ void LSubscribeManager::responce(const uint8_t* msg)
} }
else 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);
} }
} }
} }

View File

@@ -56,7 +56,7 @@ public:
~LSubscribeManager(); ~LSubscribeManager();
void onConnect(void); void onConnect(void);
void subscribe(const char* topicName, TopicCallback onPublish, uint8_t qos); 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 char* topicName);
void unsubscribe(uint16_t topicId); void unsubscribe(uint16_t topicId);
void responce(const uint8_t* msg); void responce(const uint8_t* msg);

View File

@@ -14,7 +14,6 @@
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -32,148 +31,153 @@ extern LMqttsnClient* theClient;
extern LScreen* theScreen; extern LScreen* theScreen;
extern bool theClientMode; extern bool theClientMode;
/*===================================== /*=====================================
TaskManager TaskManager
======================================*/ ======================================*/
LTaskManager::LTaskManager(void){ LTaskManager::LTaskManager(void)
_tasks = 0; {
_tests = 0; _tasks = 0;
_index = 0; _tests = 0;
_index = 0;
} }
LTaskManager::~LTaskManager(void){ LTaskManager::~LTaskManager(void)
{
} }
void LTaskManager::add(TaskList* task){ void LTaskManager::add(TaskList* task)
{
_tasks = task; _tasks = task;
} }
void LTaskManager::add(TestList* test){ void LTaskManager::add(TestList* test)
{
_tests = test; _tests = test;
} }
void LTaskManager::run(void){ void LTaskManager::run(void)
int i = 0; {
char c = 0; int i = 0;
bool cancelFlg = false; char c = 0;
TestList test = {0}; bool cancelFlg = false;
TaskList task = {0}; TestList test = { 0 };
TaskList task = { 0 };
if ( !theClientMode ) if (!theClientMode)
{ {
theClient->getGwProxy()->getMessage(); theClient->getGwProxy()->getMessage();
for (i = 0; _tests[i].testTask > test.testTask; i++) for (i = 0; _tests[i].testTask > test.testTask; i++)
{ {
PROMPT("Execute \"%s\" ? ( y/n ) : ", _tests[i].testLabel); PROMPT("Execute \"%s\" ? ( y/n ) : ", _tests[i].testLabel);
while (true) while (true)
{ {
if (CHECKKEYIN(&c)) 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); DISPLAY("\033[0m\033[0;32m\n**** %s is canceled ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
theScreen->prompt(""); theScreen->prompt("");
cancelFlg = true; cancelFlg = true;
break; 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); DISPLAY("\033[0m\033[0;32m\n\n**** %s start ****\033[0m\033[0;37m\n", _tests[i].testLabel);
theScreen->prompt(""); theScreen->prompt("");
(_tests[i].testTask)(); (_tests[i].testTask)();
cancelFlg = false; cancelFlg = false;
break; break;
} }
} }
else else
{ {
theClient->getGwProxy()->getMessage(); theClient->getGwProxy()->getMessage();
} }
} }
while ( true ) while (true)
{ {
do do
{ {
theClient->getGwProxy()->getMessage(); theClient->getGwProxy()->getMessage();
} }
while(theClient->getPublishManager()->isMaxFlight() || while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
!theClient->getSubscribeManager()->isDone() || || !theClient->getRegisterManager()->isDone());
!theClient->getRegisterManager()->isDone());
if (theClient->getPublishManager()->isDone()) if (theClient->getPublishManager()->isDone())
{ {
break; break;
} }
} }
if ( !cancelFlg ) if (!cancelFlg)
{ {
DISPLAY("\033[0m\033[0;32m\n**** %s complete ****\033[0m\033[0;37m\n\n", _tests[i].testLabel); DISPLAY("\033[0m\033[0;32m\n**** %s complete ****\033[0m\033[0;37m\n\n", _tests[i].testLabel);
} }
} }
DISPLAY("\033[0m\033[0;32m\n\n######### All tests complete! ###########\033[0m\033[0;37m\n\n"); DISPLAY("\033[0m\033[0;32m\n\n######### All tests complete! ###########\033[0m\033[0;37m\n\n");
} }
else else
{ {
while (true) while (true)
{ {
theClient->getGwProxy()->getMessage(); theClient->getGwProxy()->getMessage();
for (_index = 0; _tasks[_index].callback > task.callback; _index++) for (_index = 0; _tasks[_index].callback > task.callback; _index++)
{ {
if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) && if ((_tasks[_index].prevTime + _tasks[_index].interval <= time(NULL)) && _tasks[_index].count == 0)
_tasks[_index].count == 0) {
{ _tasks[_index].prevTime = time(NULL);
_tasks[_index].prevTime = time(NULL); (_tasks[_index].callback)();
(_tasks[_index].callback)(); }
} }
}
do do
{ {
theClient->getGwProxy()->getMessage(); theClient->getGwProxy()->getMessage();
} }
while(theClient->getPublishManager()->isMaxFlight() || while (theClient->getPublishManager()->isMaxFlight() || !theClient->getSubscribeManager()->isDone()
!theClient->getSubscribeManager()->isDone() || || !theClient->getRegisterManager()->isDone());
!theClient->getRegisterManager()->isDone());
if (theClient->getPublishManager()->isDone()) if (theClient->getPublishManager()->isDone())
{ {
break; break;
} }
} }
} }
} }
uint8_t LTaskManager::getIndex(void){ uint8_t LTaskManager::getIndex(void)
return _index; {
return _index;
} }
void LTaskManager::done(uint8_t index){ void LTaskManager::done(uint8_t index)
if (_tasks ) {
{ if (_tasks)
if (_tasks[index].count > 0) {
{ if (_tasks[index].count > 0)
_tasks[index].count--; {
} _tasks[index].count--;
} }
if (_tests ) }
{ if (_tests)
if (_tests[index].count > 0) {
{ if (_tests[index].count > 0)
_tests[index].count--; {
} _tests[index].count--;
} }
}
} }
void LTaskManager::suspend(uint8_t index){ void LTaskManager::suspend(uint8_t index)
if ( _tasks ) {
{ if (_tasks)
_tasks[index].count++; {
} _tasks[index].count++;
if ( _tests ) }
{ if (_tests)
_tests[index].count++; {
} _tests[index].count++;
}
} }

View File

@@ -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

View File

@@ -1,145 +1,211 @@
# MQTT-SN Transparent / Aggregating Gateway # 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).
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
### step1. Build the gateway
copy and expand source code then,
```
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
```
In order to build a gateway, one sensor network argument is required.
```
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm|dtls|dtls6]
```
**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-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin directory.
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
### **step1. Build the gateway** ### step2. Execute the Gateway.
````
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
$ 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.
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
````
```
### **step2. Execute the Gateway.** $ cd bin
$ ./MQTT-SNGateway
```` ```
$ cd ../../
$ ./MQTT-SNGateway [-f Config file name]
````
If you get the error message as follows: If you get the error message as follows:
````
what(): RingBuffer can't create a shared memory. RingBuffer can't create a shared memory. ABORT Gateway!!!
Aborted (core dumped)
````
You have to start using sudo command only once for the first time. You have to start using sudo command only once for the first time.
```` ```
$ sudo ./MQTT-SNGateway [-f Config file name] $ sudo ./MQTT-SNGateway
```` ```
## Contents of the gateway configuration file
### **How to Change the configuration of the gateway** **gateway.conf** is in bin directory. It's contents are follows:
**../gateway.conf** Contents are follows:
<pre><dev>
```
#**************************************************************************
# 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 # 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 BrokerPortNo=1883
BrokerSecurePortNo=8883 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, # When AggregatingGateway=YES or ClientAuthentication=YES,
# All clients must be specified by the ClientList File # All clients must be specified by the ClientList File
# #
ClientAuthentication=NO
AggregatingGateway=NO AggregatingGateway=NO
QoS-1=NO QoS-1=NO
Forwarder=NO Forwarder=NO
#ClientsList=/path/to/your_clients.conf
PredefinedTopic=NO PredefinedTopic=NO
#PredefinedTopicList=/path/to/your_predefinedTopic.conf ClientAuthentication=NO
#RootCAfile=/etc/ssl/certs/ca-certificates.crt ClientsList=/path/to/your_clients.conf
#RootCApath=/etc/ssl/certs/ PredefinedTopicList=/path/to/your_predefinedTopic.conf
#CertsFile=/path/to/certKey.pem ```
#PrivateKey=/path/to/privateKey.pem 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.
GatewayID=1 If **Forwarder** is 'YES', the gateway prepare a forwarder agent.
GatewayName=PahoGateway-01 If **ClientAuthentication** is 'YES', the client cannot connect unless it is registered in the clients.conf file.
KeepAlive=900 **ClientsList** defines clients and those address so on.
#LoginID=your_ID **PredefinedTopicList** file defines Predefined Topic.
#Password=your_Password
# UDP ```
#==============================
# SensorNetworks parameters
#==============================
#
# UDP | DTLS
#
GatewayPortNo=10000 GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1883 MulticastPortNo=1883
MulticastTTL=1 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 GatewayIPv6PortNo=10000
GatewayUDP6Bind=FFFF:FFFE::1 MulticastIPv6PortNo=1883
GatewayUDP6Port=10000 MulticastIPv6=ff1e:feed:caca:dead::feed:caca:dead
GatewayUDP6Broadcast=FF02::1 MulticastIPv6If=wlp4s0
GatewayUDP6If=wpan0 MulticastHops=1
GatewayUDP6Hops=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 # XBee
#
Baudrate=38400 Baudrate=38400
SerialDevice=/dev/ttyUSB0 SerialDevice=/dev/ttyUSB0
ApiMode=2 ApiMode=2
```
**Baudrate** is a baudrate of xbee.
```
#
# LoRaLink
#
#LoRaLink
BaudrateLoRaLink=115200 BaudrateLoRaLink=115200
DeviceRxLoRaLink=/dev/ttyLoRaLinkRx DeviceRxLoRaLink=/dev/loralinkRx
DeviceTxLoRaLink=/dev/ttyLoRaLinkTx 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 # 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. ### How to monitor the gateway from a remote terminal.
**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. **
Change gateway.conf as follows: Change gateway.conf as follows:
``` ```
# LOG # LOG
ShearedMemory=YES; ShearedMemory=YES;
```` ```
Restart the gateway with sudo only once to create shared memories.
Restart the gateway with sudo only once to create shared memories.
open ssh terminal and execute LogMonitor. open ssh terminal and execute LogMonitor.
```
`$ ./MQTT-SNLogmonitor` $ cd bin
$ ./MQTT-SNLogmonitor
```
Now you can get the Log on your terminal. Now you can get the Log on your terminal.
## ** Tips ** ##### Tips
Uncomment the line 62, 63 in MQTTSNDefines.h then you can get more precise logs. 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.
``` ```
/*================================= ./build.sh udp -DDEBUG -DDEBUG_NW
* Log controls
==================================*/
//#define DEBUG // print out log for debug
//#define DEBUG_NWSTACK // print out SensorNetwork log
``` ```

42
MQTTSNGateway/build.sh Executable file
View 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

View File

@@ -15,10 +15,10 @@
# Lines bigning with # are comment line. # Lines bigning with # are comment line.
# ClientId, SensorNetAddress, "unstableLine", "secureConnection" # ClientId, SensorNetAddress, "unstableLine", "secureConnection"
# in case of UDP, SensorNetAddress format is IPAddress: port no. # in case of UDP, SensorNetAddress format is IPAddress: port no.
# if the SensorNetwork is not stable, write "unstableLine". # if the SensorNetwork is not stable, specify "unstableLine".
# if Broker's Connection is SSL, write "secureConnection". # if Broker's Connection is TLS, specify "secureConnection".
# if the client is a forwarder, "forwarder" is required. # if the client is a forwarder,specify "forwarder".
# if the client send PUBLISH QoS-1, "QoS-1" is required. # if the client send PUBLISH QoS-1, specify "QoS-1".
# #
# Ex: # Ex:
# #Client List # #Client List
@@ -31,6 +31,17 @@
# #
# SensorNetwork address format is defined by SensorNetAddress::setAddress(string* data) function. # 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 GatewayTester, 172.16.1.11:20020
ClientPUB,172.16.1.11:2010 ClientPUB,172.16.1.11:2010
Client01,172.16.1.11:12001 Client01,172.16.1.11:12001

View File

@@ -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 # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
@@ -14,55 +14,95 @@
# config file of MQTT-SN Gateway # 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 BrokerPortNo=1883
BrokerSecurePortNo=8883 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, # When AggregatingGateway=YES or ClientAuthentication=YES,
# All clients must be specified by the ClientList File # All clients must be specified by the ClientList File
# #
ClientAuthentication=NO
AggregatingGateway=NO AggregatingGateway=NO
QoS-1=NO QoS-1=NO
Forwarder=NO Forwarder=NO
#ClientsList=/path/to/your_clients.conf
PredefinedTopic=NO PredefinedTopic=NO
#PredefinedTopicList=/path/to/your_predefinedTopic.conf ClientAuthentication=NO
#RootCAfile=/etc/ssl/certs/ca-certificates.crt ClientsList=/path/to/your_clients.conf
#RootCApath=/etc/ssl/certs/ PredefinedTopicList=/path/to/your_predefinedTopic.conf
#CertsFile=/path/to/certKey.pem
#PrivateKey=/path/to/privateKey.pem
GatewayID=1
GatewayName=PahoGateway-01
KeepAlive=900
#LoginID=your_ID
#Password=your_Password
# UDP #==============================
# SensorNetworks parameters
#==============================
#
# UDP | DTLS
#
GatewayPortNo=10000 GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1883 MulticastPortNo=1883
MulticastIP=225.1.1.1
MulticastTTL=1 MulticastTTL=1
# UDP6 #
GatewayUDP6Bind=FFFF:FFFE::1 # UDP6 | DTLS6
GatewayUDP6Port=10000 #
GatewayUDP6Broadcast=FF02::1
GatewayUDP6If=wpan0
GatewayUDP6Hops=1
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 # XBee
#
Baudrate=38400 Baudrate=38400
SerialDevice=/dev/ttyUSB0 SerialDevice=/dev/ttyUSB0
ApiMode=2 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

View 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)

View File

@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
MQTTGWConnectionHandler::MQTTGWConnectionHandler(Gateway* gateway) MQTTGWConnectionHandler::MQTTGWConnectionHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTGWConnectionHandler::~MQTTGWConnectionHandler() MQTTGWConnectionHandler::~MQTTGWConnectionHandler()
@@ -32,68 +32,67 @@ MQTTGWConnectionHandler::~MQTTGWConnectionHandler()
void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet) void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet)
{ {
uint8_t rc = MQTT_SERVER_UNAVAILABLE; uint8_t rc = MQTT_SERVER_UNAVAILABLE;
Connack resp; Connack resp;
packet->getCONNACK(&resp); packet->getCONNACK(&resp);
/* convert MQTT ReturnCode to MQTT-SN one */ /* convert MQTT ReturnCode to MQTT-SN one */
if (resp.rc == MQTT_CONNECTION_ACCEPTED) if (resp.rc == MQTT_CONNECTION_ACCEPTED)
{ {
rc = MQTTSN_RC_ACCEPTED; rc = MQTTSN_RC_ACCEPTED;
} }
else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION) else if (resp.rc == MQTT_UNACCEPTABLE_PROTOCOL_VERSION)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG(" ClientID : %s Requested Protocol version is not supported.\n", client->getClientId()); WRITELOG(" ClientID : %s Requested Protocol version is not supported.\n", client->getClientId());
} }
else if (resp.rc == MQTT_IDENTIFIER_REJECTED) else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
{ {
rc = MQTTSN_RC_NOT_SUPPORTED; rc = MQTTSN_RC_NOT_SUPPORTED;
WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", WRITELOG(" ClientID : %s ClientID is collect UTF-8 but not allowed by the Server.\n", client->getClientId());
client->getClientId()); }
} else if (resp.rc == MQTT_SERVER_UNAVAILABLE)
else if (resp.rc == MQTT_SERVER_UNAVAILABLE) {
{ rc = MQTTSN_RC_REJECTED_CONGESTED;
rc = MQTTSN_RC_REJECTED_CONGESTED; WRITELOG(" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n",
WRITELOG(" ClientID : %s The Network Connection has been made but the MQTT service is unavailable.\n", client->getClientId());
client->getClientId()); }
} else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD)
else if (resp.rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
{ rc = MQTTSN_RC_NOT_SUPPORTED;
rc = MQTTSN_RC_NOT_SUPPORTED; WRITELOG(" Gateway Configuration Error: The data in the user name or password is malformed.\n");
WRITELOG(" Gateway Configuration Error: The data in the user name or password is malformed.\n"); }
} else if (resp.rc == MQTT_NOT_AUTHORIZED)
else if (resp.rc == MQTT_NOT_AUTHORIZED) {
{ rc = MQTTSN_RC_NOT_SUPPORTED;
rc = MQTTSN_RC_NOT_SUPPORTED; WRITELOG(" Gateway Configuration Error: The Client is not authorized to connect.\n");
WRITELOG(" Gateway Configuration Error: The Client is not authorized to connect.\n"); }
}
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setCONNACK(rc); snPacket->setCONNACK(rc);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, snPacket); ev1->setClientSendEvent(client, snPacket);
client->connackSended(rc); // update the client's status client->connackSended(rc); // update the client's status
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
void MQTTGWConnectionHandler::handlePingresp(Client* client, MQTTGWPacket* packet) void MQTTGWConnectionHandler::handlePingresp(Client* client, MQTTGWPacket* packet)
{ {
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setPINGRESP(); snPacket->setPINGRESP();
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, snPacket); ev1->setClientSendEvent(client, snPacket);
client->updateStatus(snPacket); client->updateStatus(snPacket);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
void MQTTGWConnectionHandler::handleDisconnect(Client* client, MQTTGWPacket* packet) void MQTTGWConnectionHandler::handleDisconnect(Client* client, MQTTGWPacket* packet)
{ {
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setDISCONNECT(0); snPacket->setDISCONNECT(0);
client->disconnected(); client->disconnected();
client->getNetwork()->close(); client->getNetwork()->close();
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, snPacket); ev1->setClientSendEvent(client, snPacket);
} }

View File

@@ -26,13 +26,13 @@ namespace MQTTSNGW
class MQTTGWConnectionHandler class MQTTGWConnectionHandler
{ {
public: public:
MQTTGWConnectionHandler(Gateway* gateway); MQTTGWConnectionHandler(Gateway* gateway);
~MQTTGWConnectionHandler(); ~MQTTGWConnectionHandler();
void handleConnack(Client* client, MQTTGWPacket* packet); void handleConnack(Client* client, MQTTGWPacket* packet);
void handlePingresp(Client* client, MQTTGWPacket* packet); void handlePingresp(Client* client, MQTTGWPacket* packet);
void handleDisconnect(Client* client, MQTTGWPacket* packet); void handleDisconnect(Client* client, MQTTGWPacket* packet);
private: private:
Gateway* _gateway; Gateway* _gateway;
}; };
} }

View File

@@ -28,9 +28,8 @@ void writeInt(unsigned char** pptr, int msgId);
/** /**
* List of the predefined MQTT v3 packet names. * List of the predefined MQTT v3 packet names.
*/ */
static const char* mqtt_packet_names[] = static const char* mqtt_packet_names[] = { "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP",
{ "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", "PUBCOMP", "SUBSCRIBE", "SUBACK", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
"UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" };
/** /**
* Encodes the message length according to the MQTT algorithm * Encodes the message length according to the MQTT algorithm
@@ -40,17 +39,18 @@ static const char* mqtt_packet_names[] =
*/ */
int MQTTPacket_encode(char* buf, int length) int MQTTPacket_encode(char* buf, int length)
{ {
int rc = 0; int rc = 0;
do do
{ {
char d = length % 128; char d = length % 128;
length /= 128; length /= 128;
/* if there are more digits to encode, set the top bit of this digit */ /* if there are more digits to encode, set the top bit of this digit */
if (length > 0) if (length > 0)
d |= 0x80; d |= 0x80;
buf[rc++] = d; buf[rc++] = d;
} while (length > 0); }
return rc; while (length > 0);
return rc;
} }
/** /**
@@ -60,10 +60,10 @@ int MQTTPacket_encode(char* buf, int length)
*/ */
int readInt(char** pptr) int readInt(char** pptr)
{ {
char* ptr = *pptr; char* ptr = *pptr;
int len = 256 * ((unsigned char) (*ptr)) + (unsigned char) (*(ptr + 1)); int len = 256 * ((unsigned char) (*ptr)) + (unsigned char) (*(ptr + 1));
*pptr += 2; *pptr += 2;
return len; return len;
} }
/** /**
@@ -80,20 +80,20 @@ int readInt(char** pptr)
*/ */
char* readUTFlen(char** pptr, char* enddata, int* len) char* readUTFlen(char** pptr, char* enddata, int* len)
{ {
char* string = NULL; char* string = NULL;
if (enddata - (*pptr) > 1) /* enough length to read the integer? */ if (enddata - (*pptr) > 1) /* enough length to read the integer? */
{ {
*len = readInt(pptr); *len = readInt(pptr);
if (&(*pptr)[*len] <= enddata) if (&(*pptr)[*len] <= enddata)
{ {
string = (char*)calloc(*len + 1, 1); string = (char*) calloc(*len + 1, 1);
memcpy(string, *pptr, (size_t)*len); memcpy(string, *pptr, (size_t) *len);
string[*len] = '\0'; string[*len] = '\0';
*pptr += *len; *pptr += *len;
} }
} }
return string; return string;
} }
/** /**
@@ -108,8 +108,8 @@ char* readUTFlen(char** pptr, char* enddata, int* len)
*/ */
char* readUTF(char** pptr, char* enddata) char* readUTF(char** pptr, char* enddata)
{ {
int len; int len;
return readUTFlen(pptr, enddata, &len); return readUTFlen(pptr, enddata, &len);
} }
/** /**
@@ -119,9 +119,9 @@ char* readUTF(char** pptr, char* enddata)
*/ */
unsigned char readChar(char** pptr) unsigned char readChar(char** pptr)
{ {
unsigned char c = **pptr; unsigned char c = **pptr;
(*pptr)++; (*pptr)++;
return c; return c;
} }
/** /**
@@ -131,8 +131,8 @@ unsigned char readChar(char** pptr)
*/ */
void writeChar(unsigned char** pptr, char c) void writeChar(unsigned char** pptr, char c)
{ {
**pptr = c; **pptr = c;
(*pptr)++; (*pptr)++;
} }
/** /**
@@ -142,10 +142,10 @@ void writeChar(unsigned char** pptr, char c)
*/ */
void writeInt(unsigned char** pptr, int anInt) void writeInt(unsigned char** pptr, int anInt)
{ {
**pptr = (unsigned char)(anInt / 256); **pptr = (unsigned char) (anInt / 256);
(*pptr)++; (*pptr)++;
**pptr = (unsigned char)(anInt % 256); **pptr = (unsigned char) (anInt % 256);
(*pptr)++; (*pptr)++;
} }
/** /**
@@ -155,10 +155,10 @@ void writeInt(unsigned char** pptr, int anInt)
*/ */
void writeUTF(unsigned char** pptr, const char* string) void writeUTF(unsigned char** pptr, const char* string)
{ {
int len = (int)strlen(string); int len = (int) strlen(string);
writeInt(pptr, len); writeInt(pptr, len);
memcpy(*pptr, string, (size_t)len); memcpy(*pptr, string, (size_t) len);
*pptr += len; *pptr += len;
} }
/** /**
@@ -167,479 +167,480 @@ void writeUTF(unsigned char** pptr, const char* string)
*/ */
MQTTGWPacket::MQTTGWPacket() MQTTGWPacket::MQTTGWPacket()
{ {
_data = 0; _data = 0;
_header.byte = 0; _header.byte = 0;
_remainingLength = 0; _remainingLength = 0;
} }
MQTTGWPacket::~MQTTGWPacket() MQTTGWPacket::~MQTTGWPacket()
{ {
if (_data) if (_data)
{ {
free(_data); free(_data);
} }
} }
int MQTTGWPacket::recv(Network* network) int MQTTGWPacket::recv(Network* network)
{ {
int len = 0; int len = 0;
int multiplier = 1; int multiplier = 1;
unsigned char c; unsigned char c;
/* read First Byte of Packet */ /* read First Byte of Packet */
int rc = network->recv((unsigned char*)&_header.byte, 1); int rc = network->recv((unsigned char*) &_header.byte, 1);
if ( rc <= 0) if (rc <= 0)
{ {
return rc; return rc;
} }
/* read RemainingLength */ /* read RemainingLength */
do do
{ {
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES) if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{ {
return -2; return -2;
} }
if (network->recv(&c, 1) == -1) if (network->recv(&c, 1) == -1)
{ {
return -1; return -1;
} }
_remainingLength += (c & 127) * multiplier; _remainingLength += (c & 127) * multiplier;
multiplier *= 128; multiplier *= 128;
} while ((c & 128) != 0); }
while ((c & 128) != 0);
if ( _remainingLength > 0 ) if (_remainingLength > 0)
{ {
/* allocate buffer */ /* allocate buffer */
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if ( !_data ) if (!_data)
{ {
return -3; return -3;
} }
/* read Payload */ /* read Payload */
int remlen = network->recv(_data, _remainingLength); int remlen = network->recv(_data, _remainingLength);
if (remlen == -1 ) if (remlen == -1)
{ {
return -1; return -1;
} }
else if ( remlen != _remainingLength ) else if (remlen != _remainingLength)
{ {
return -2; return -2;
} }
} }
return 1 + len + _remainingLength; return 1 + len + _remainingLength;
} }
int MQTTGWPacket::send(Network* network) int MQTTGWPacket::send(Network* network)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
memset(buf, 0, MQTTSNGW_MAX_PACKET_SIZE); memset(buf, 0, MQTTSNGW_MAX_PACKET_SIZE);
int len = getPacketData(buf); int len = getPacketData(buf);
return network->send(buf, len); return network->send(buf, len);
} }
int MQTTGWPacket::getAck(Ack* ack) int MQTTGWPacket::getAck(Ack* ack)
{ {
if (PUBACK != _header.bits.type && PUBREC != _header.bits.type && PUBREL != _header.bits.type if (PUBACK != _header.bits.type && PUBREC != _header.bits.type && PUBREL != _header.bits.type
&& PUBCOMP != _header.bits.type && UNSUBACK != _header.bits.type) && PUBCOMP != _header.bits.type && UNSUBACK != _header.bits.type)
{ {
return 0; return 0;
} }
char* ptr = (char*) _data; char* ptr = (char*) _data;
ack->header.byte = _header.byte; ack->header.byte = _header.byte;
ack->msgId = readInt((char**) &ptr); ack->msgId = readInt((char**) &ptr);
return 1; return 1;
} }
int MQTTGWPacket::getCONNACK(Connack* resp) int MQTTGWPacket::getCONNACK(Connack* resp)
{ {
if (_header.bits.type != CONNACK) if (_header.bits.type != CONNACK)
{ {
return 0; return 0;
} }
char* ptr = (char*) _data; char* ptr = (char*) _data;
resp->header.byte = _header.byte; resp->header.byte = _header.byte;
resp->flags.all = *ptr++; resp->flags.all = *ptr++;
resp->rc = readChar(&ptr); resp->rc = readChar(&ptr);
return 1; return 1;
} }
int MQTTGWPacket::getSUBACK(unsigned short* msgId, unsigned char* rc) int MQTTGWPacket::getSUBACK(unsigned short* msgId, unsigned char* rc)
{ {
if (_header.bits.type != SUBACK) if (_header.bits.type != SUBACK)
{ {
return 0; return 0;
} }
char *ptr = (char*) _data; char *ptr = (char*) _data;
*msgId = readInt((char**) &ptr); *msgId = readInt((char**) &ptr);
*rc = readChar(&ptr); *rc = readChar(&ptr);
return 1; return 1;
} }
int MQTTGWPacket::getPUBLISH(Publish* pub) int MQTTGWPacket::getPUBLISH(Publish* pub)
{ {
if (_header.bits.type != PUBLISH) if (_header.bits.type != PUBLISH)
{ {
return 0; return 0;
} }
char* ptr = (char*) _data; char* ptr = (char*) _data;
pub->header = _header; pub->header = _header;
pub->topiclen = readInt((char**) &ptr); pub->topiclen = readInt((char**) &ptr);
pub->topic = (char*) _data + 2; pub->topic = (char*) _data + 2;
ptr += pub->topiclen; ptr += pub->topiclen;
if (_header.bits.qos > 0) if (_header.bits.qos > 0)
{ {
pub->msgId = readInt(&ptr); pub->msgId = readInt(&ptr);
pub->payloadlen = _remainingLength - pub->topiclen - 4; pub->payloadlen = _remainingLength - pub->topiclen - 4;
} }
else else
{ {
pub->msgId = 0; pub->msgId = 0;
pub->payloadlen = _remainingLength - pub->topiclen - 2; pub->payloadlen = _remainingLength - pub->topiclen - 2;
} }
pub->payload = ptr; pub->payload = ptr;
return 1; return 1;
} }
int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, unsigned char* password) int MQTTGWPacket::setCONNECT(Connect* connect, unsigned char* username, unsigned char* password)
{ {
clearData(); clearData();
_header = connect->header; _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) 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) 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; unsigned char* ptr = _data;
if (connect->version == 3) if (connect->version == 3)
{ {
writeUTF(&ptr, "MQIsdp"); writeUTF(&ptr, "MQIsdp");
writeChar(&ptr, (char) 3); writeChar(&ptr, (char) 3);
} }
else if (connect->version == 4) else if (connect->version == 4)
{ {
writeUTF(&ptr, "MQTT"); writeUTF(&ptr, "MQTT");
writeChar(&ptr, (char) 4); writeChar(&ptr, (char) 4);
} }
else else
{ {
return 0; return 0;
} }
writeChar(&ptr, connect->flags.all); writeChar(&ptr, connect->flags.all);
writeInt(&ptr, connect->keepAliveTimer); writeInt(&ptr, connect->keepAliveTimer);
writeUTF(&ptr, connect->clientID); writeUTF(&ptr, connect->clientID);
if (connect->flags.bits.will) if (connect->flags.bits.will)
{ {
writeUTF(&ptr, connect->willTopic); writeUTF(&ptr, connect->willTopic);
writeUTF(&ptr, connect->willMsg); writeUTF(&ptr, connect->willMsg);
} }
if (connect->flags.bits.username) if (connect->flags.bits.username)
{ {
writeUTF(&ptr, (const char*) username); writeUTF(&ptr, (const char*) username);
} }
if (connect->flags.bits.password) if (connect->flags.bits.password)
{ {
writeUTF(&ptr, (const char*) password); writeUTF(&ptr, (const char*) password);
} }
return 1; return 1;
} }
int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId) int MQTTGWPacket::setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId)
{ {
clearData(); clearData();
_header.byte = 0; _header.byte = 0;
_header.bits.type = SUBSCRIBE; _header.bits.type = SUBSCRIBE;
_header.bits.qos = 1; // Reserved _header.bits.qos = 1; // Reserved
_remainingLength = (int)strlen(topic) + 5; _remainingLength = (int) strlen(topic) + 5;
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if (_data) if (_data)
{ {
unsigned char* ptr = _data; unsigned char* ptr = _data;
writeInt(&ptr, msgId); writeInt(&ptr, msgId);
writeUTF(&ptr, topic); writeUTF(&ptr, topic);
writeChar(&ptr, (char) qos); writeChar(&ptr, (char) qos);
return 1; return 1;
} }
clearData(); clearData();
return 0; return 0;
} }
int MQTTGWPacket::setUNSUBSCRIBE(const char* topic, unsigned short msgid) int MQTTGWPacket::setUNSUBSCRIBE(const char* topic, unsigned short msgid)
{ {
clearData(); clearData();
_header.byte = 0; _header.byte = 0;
_header.bits.type = UNSUBSCRIBE; _header.bits.type = UNSUBSCRIBE;
_header.bits.qos = 1; _header.bits.qos = 1;
_remainingLength = (int)strlen(topic) + 4; _remainingLength = (int) strlen(topic) + 4;
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if (_data) if (_data)
{ {
unsigned char* ptr = _data; unsigned char* ptr = _data;
writeInt(&ptr, msgid); writeInt(&ptr, msgid);
writeUTF(&ptr, topic); writeUTF(&ptr, topic);
return 1; return 1;
} }
clearData(); clearData();
return 0; return 0;
} }
int MQTTGWPacket::setPUBLISH(Publish* pub) int MQTTGWPacket::setPUBLISH(Publish* pub)
{ {
clearData(); clearData();
_header.byte = pub->header.byte; _header.byte = pub->header.byte;
_header.bits.type = PUBLISH; _header.bits.type = PUBLISH;
_remainingLength = 4 + pub->topiclen + pub->payloadlen; _remainingLength = 4 + pub->topiclen + pub->payloadlen;
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if (_data) if (_data)
{ {
unsigned char* ptr = _data; unsigned char* ptr = _data;
writeInt(&ptr, pub->topiclen); writeInt(&ptr, pub->topiclen);
memcpy(ptr, pub->topic, pub->topiclen); memcpy(ptr, pub->topic, pub->topiclen);
ptr += pub->topiclen; ptr += pub->topiclen;
if ( _header.bits.qos > 0 ) if (_header.bits.qos > 0)
{ {
writeInt(&ptr, pub->msgId); writeInt(&ptr, pub->msgId);
} }
else else
{ {
_remainingLength -= 2; _remainingLength -= 2;
} }
memcpy(ptr, pub->payload, pub->payloadlen); memcpy(ptr, pub->payload, pub->payloadlen);
return 1; return 1;
} }
else else
{ {
clearData(); clearData();
return 0; return 0;
} }
} }
int MQTTGWPacket::setAck(unsigned char msgType, unsigned short msgid) int MQTTGWPacket::setAck(unsigned char msgType, unsigned short msgid)
{ {
clearData(); clearData();
_remainingLength = 2; _remainingLength = 2;
_header.bits.type = msgType; _header.bits.type = msgType;
_header.bits.qos = (msgType == PUBREL) ? 1 : 0; _header.bits.qos = (msgType == PUBREL) ? 1 : 0;
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if (_data) if (_data)
{ {
unsigned char* data = _data; unsigned char* data = _data;
writeInt(&data, msgid); writeInt(&data, msgid);
return 1; return 1;
} }
return 0; return 0;
} }
int MQTTGWPacket::setHeader(unsigned char msgType) int MQTTGWPacket::setHeader(unsigned char msgType)
{ {
clearData(); clearData();
if (msgType < CONNECT || msgType > DISCONNECT) if (msgType < CONNECT || msgType > DISCONNECT)
{ {
return 0; return 0;
} }
_header.bits.type = msgType; _header.bits.type = msgType;
return 0; return 0;
} }
int MQTTGWPacket::getType(void) int MQTTGWPacket::getType(void)
{ {
return _header.bits.type; return _header.bits.type;
} }
const char* MQTTGWPacket::getName(void) const char* MQTTGWPacket::getName(void)
{ {
return getType() > DISCONNECT ? "UNKNOWN" : mqtt_packet_names[getType()]; return getType() > DISCONNECT ? "UNKNOWN" : mqtt_packet_names[getType()];
} }
int MQTTGWPacket::getPacketData(unsigned char* buf) int MQTTGWPacket::getPacketData(unsigned char* buf)
{ {
unsigned char* ptr = buf; unsigned char* ptr = buf;
*ptr++ = _header.byte; *ptr++ = _header.byte;
int len = MQTTPacket_encode((char*)ptr, _remainingLength); int len = MQTTPacket_encode((char*) ptr, _remainingLength);
ptr += len; ptr += len;
memcpy(ptr, _data, _remainingLength); memcpy(ptr, _data, _remainingLength);
return 1 + len + _remainingLength; return 1 + len + _remainingLength;
} }
int MQTTGWPacket::getPacketLength(void) int MQTTGWPacket::getPacketLength(void)
{ {
char buf[4]; char buf[4];
return 1 + MQTTPacket_encode(buf, _remainingLength) + _remainingLength; return 1 + MQTTPacket_encode(buf, _remainingLength) + _remainingLength;
} }
void MQTTGWPacket::clearData(void) void MQTTGWPacket::clearData(void)
{ {
if (_data) if (_data)
{ {
free(_data); free(_data);
} }
_header.byte = 0; _header.byte = 0;
_remainingLength = 0; _remainingLength = 0;
} }
char* MQTTGWPacket::getMsgId(char* pbuf) char* MQTTGWPacket::getMsgId(char* pbuf)
{ {
int type = getType(); int type = getType();
switch ( type ) switch (type)
{ {
case PUBLISH: case PUBLISH:
Publish pub; Publish pub;
pub.msgId = 0; pub.msgId = 0;
getPUBLISH(&pub); getPUBLISH(&pub);
if ( _header.bits.dup ) if (_header.bits.dup)
{ {
sprintf(pbuf, "+%04X", pub.msgId); sprintf(pbuf, "+%04X", pub.msgId);
} }
else else
{ {
sprintf(pbuf, " %04X", pub.msgId); sprintf(pbuf, " %04X", pub.msgId);
} }
break; break;
case SUBSCRIBE: case SUBSCRIBE:
case UNSUBSCRIBE: case UNSUBSCRIBE:
case PUBACK: case PUBACK:
case PUBREC: case PUBREC:
case PUBREL: case PUBREL:
case PUBCOMP: case PUBCOMP:
case SUBACK: case SUBACK:
case UNSUBACK: case UNSUBACK:
sprintf(pbuf, " %02X%02X", _data[0], _data[1]); sprintf(pbuf, " %02X%02X", _data[0], _data[1]);
break; break;
default: default:
sprintf(pbuf, " "); sprintf(pbuf, " ");
break; break;
} }
if ( strcmp(pbuf, " 0000") == 0 ) if (strcmp(pbuf, " 0000") == 0)
{ {
sprintf(pbuf, " "); sprintf(pbuf, " ");
} }
return pbuf; return pbuf;
} }
int MQTTGWPacket::getMsgId(void) int MQTTGWPacket::getMsgId(void)
{ {
int type = getType(); int type = getType();
int msgId = 0; int msgId = 0;
switch ( type ) switch (type)
{ {
case PUBLISH: case PUBLISH:
Publish pub; Publish pub;
pub.msgId = 0; pub.msgId = 0;
getPUBLISH(&pub); getPUBLISH(&pub);
msgId = pub.msgId; msgId = pub.msgId;
break; break;
case PUBACK: case PUBACK:
case PUBREC: case PUBREC:
case PUBREL: case PUBREL:
case PUBCOMP: case PUBCOMP:
case SUBSCRIBE: case SUBSCRIBE:
case UNSUBSCRIBE: case UNSUBSCRIBE:
case SUBACK: case SUBACK:
case UNSUBACK: case UNSUBACK:
msgId = 256 * (unsigned char)_data[0] + (unsigned char)_data[1]; msgId = 256 * (unsigned char) _data[0] + (unsigned char) _data[1];
break; break;
default: default:
break; break;
} }
return msgId; return msgId;
} }
void MQTTGWPacket::setMsgId(int msgId) void MQTTGWPacket::setMsgId(int msgId)
{ {
int type = getType(); int type = getType();
unsigned char* ptr = 0; unsigned char* ptr = 0;
switch ( type ) switch (type)
{ {
case PUBLISH: case PUBLISH:
Publish pub; Publish pub;
pub.topiclen = 0; pub.topiclen = 0;
pub.msgId = 0; pub.msgId = 0;
getPUBLISH(&pub); getPUBLISH(&pub);
pub.msgId = msgId; pub.msgId = msgId;
ptr = _data + pub.topiclen; ptr = _data + pub.topiclen;
writeInt(&ptr, pub.msgId); 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; break;
case SUBSCRIBE: case SUBSCRIBE:
case UNSUBSCRIBE: case UNSUBSCRIBE:
case PUBACK: case PUBACK:
case PUBREC: case PUBREC:
case PUBREL: case PUBREL:
case PUBCOMP: case PUBCOMP:
case SUBACK: case SUBACK:
case UNSUBACK: case UNSUBACK:
ptr = _data; ptr = _data;
*ptr++ = (unsigned char)(msgId / 256); *ptr++ = (unsigned char) (msgId / 256);
*ptr = (unsigned char)(msgId % 256); *ptr = (unsigned char) (msgId % 256);
break; break;
default: default:
break; break;
} }
} }
char* MQTTGWPacket::print(char* pbuf) char* MQTTGWPacket::print(char* pbuf)
{ {
uint8_t packetData[MQTTSNGW_MAX_PACKET_SIZE]; uint8_t packetData[MQTTSNGW_MAX_PACKET_SIZE];
char* ptr = pbuf; char* ptr = pbuf;
char** pptr = &pbuf; char** pptr = &pbuf;
int len = getPacketData(packetData); int len = getPacketData(packetData);
int size = len > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : len; int size = len > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : len;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
sprintf(*pptr, " %02X", packetData[i]); sprintf(*pptr, " %02X", packetData[i]);
*pptr += 3; *pptr += 3;
} }
**pptr = 0; **pptr = 0;
return ptr; return ptr;
} }
MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet) MQTTGWPacket& MQTTGWPacket::operator =(MQTTGWPacket& packet)
{ {
clearData(); clearData();
this->_header.byte = packet._header.byte; this->_header.byte = packet._header.byte;
this->_remainingLength = packet._remainingLength; this->_remainingLength = packet._remainingLength;
_data = (unsigned char*)calloc(_remainingLength, 1); _data = (unsigned char*) calloc(_remainingLength, 1);
if (_data) if (_data)
{ {
memcpy(this->_data, packet._data, _remainingLength); memcpy(this->_data, packet._data, _remainingLength);
} }
else else
{ {
clearData(); clearData();
} }
return *this; return *this;
} }
UTF8String MQTTGWPacket::getTopic(void) UTF8String MQTTGWPacket::getTopic(void)
{ {
UTF8String str = {0, nullptr}; UTF8String str = { 0, nullptr };
if ( _header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE ) if (_header.bits.type == SUBSCRIBE || _header.bits.type == UNSUBSCRIBE)
{ {
char* ptr = (char*)(_data + 2); char* ptr = (char*) (_data + 2);
str.len = readInt(&ptr); str.len = readInt(&ptr);
str.data = (char*)(_data + 4); str.data = (char*) (_data + 4);
} }
return str; return str;
} }

View File

@@ -31,89 +31,100 @@ typedef void* (*pf)(unsigned char, char*, size_t);
enum msgTypes enum msgTypes
{ {
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, CONNECT = 1,
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, CONNACK,
PINGREQ, PINGRESP, DISCONNECT PUBLISH,
PUBACK,
PUBREC,
PUBREL,
PUBCOMP,
SUBSCRIBE,
SUBACK,
UNSUBSCRIBE,
UNSUBACK,
PINGREQ,
PINGRESP,
DISCONNECT
}; };
/** /**
* Bitfields for the MQTT header byte. * Bitfields for the MQTT header byte.
*/ */
typedef union typedef union
{ {
/*unsigned*/ char byte; /**< the whole byte */ /*unsigned*/
char byte; /**< the whole byte */
#if defined(REVERSED) #if defined(REVERSED)
struct struct
{ {
unsigned int type : 4; /**< message type nibble */ unsigned int type : 4; /**< message type nibble */
bool dup : 1; /**< DUP flag bit */ bool dup : 1; /**< DUP flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
bool retain : 1; /**< retained flag bit */ bool retain : 1; /**< retained flag bit */
} bits; }bits;
#else #else
struct struct
{ {
bool retain : 1; /**< retained flag bit */ bool retain :1; /**< retained flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ unsigned int qos :2; /**< QoS value, 0, 1 or 2 */
bool dup : 1; /**< DUP flag bit */ bool dup :1; /**< DUP flag bit */
unsigned int type : 4; /**< message type nibble */ unsigned int type :4; /**< message type nibble */
} bits; } bits;
#endif #endif
} Header; } Header;
/** /**
* Data for a connect packet. * Data for a connect packet.
*/ */
enum MQTT_connackCodes{ enum MQTT_connackCodes
MQTT_CONNECTION_ACCEPTED , {
MQTT_UNACCEPTABLE_PROTOCOL_VERSION, MQTT_CONNECTION_ACCEPTED,
MQTT_IDENTIFIER_REJECTED, MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
MQTT_SERVER_UNAVAILABLE, MQTT_IDENTIFIER_REJECTED,
MQTT_BAD_USERNAME_OR_PASSWORD, MQTT_SERVER_UNAVAILABLE,
MQTT_NOT_AUTHORIZED MQTT_BAD_USERNAME_OR_PASSWORD,
MQTT_NOT_AUTHORIZED
}; };
typedef struct typedef struct
{ {
Header header; /**< MQTT header byte */ Header header; /**< MQTT header byte */
union union
{ {
unsigned char all; /**< all connect flags */ unsigned char all; /**< all connect flags */
#if defined(REVERSED) #if defined(REVERSED)
struct struct
{ {
bool username : 1; /**< 3.1 user name */ bool username : 1; /**< 3.1 user name */
bool password : 1; /**< 3.1 password */ bool password : 1; /**< 3.1 password */
bool willRetain : 1; /**< will retain setting */ bool willRetain : 1; /**< will retain setting */
unsigned int willQoS : 2; /**< will QoS value */ unsigned int willQoS : 2; /**< will QoS value */
bool will : 1; /**< will flag */ bool will : 1; /**< will flag */
bool cleanstart : 1; /**< cleansession flag */ bool cleanstart : 1; /**< cleansession flag */
int : 1; /**< unused */ int : 1; /**< unused */
} bits; }bits;
#else #else
struct struct
{ {
int : 1; /**< unused */ int :1; /**< unused */
bool cleanstart : 1; /**< cleansession flag */ bool cleanstart :1; /**< cleansession flag */
bool will : 1; /**< will flag */ bool will :1; /**< will flag */
unsigned int willQoS : 2; /**< will QoS value */ unsigned int willQoS :2; /**< will QoS value */
bool willRetain : 1; /**< will retain setting */ bool willRetain :1; /**< will retain setting */
bool password : 1; /**< 3.1 password */ bool password :1; /**< 3.1 password */
bool username : 1; /**< 3.1 user name */ bool username :1; /**< 3.1 user name */
} bits; } bits;
#endif #endif
} flags; /**< connect flags byte */ } flags; /**< connect flags byte */
char *Protocol, /**< MQTT protocol name */ char *Protocol, /**< MQTT protocol name */
*clientID, /**< string client id */ *clientID, /**< string client id */
*willTopic, /**< will topic */ *willTopic, /**< will topic */
*willMsg; /**< will payload */ *willMsg; /**< will payload */
int keepAliveTimer; /**< keepalive timeout value in seconds */ int keepAliveTimer; /**< keepalive timeout value in seconds */
unsigned char version; /**< MQTT version number */ unsigned char version; /**< MQTT version number */
} Connect; } Connect;
#define MQTTPacket_Connect_Initializer {{0}, {0}, nullptr, nullptr, nullptr, nullptr, 0, 0} #define MQTTPacket_Connect_Initializer {{0}, {0}, nullptr, nullptr, nullptr, nullptr, 0, 0}
@@ -121,57 +132,54 @@ typedef struct
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \ #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}} } MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
/** /**
* Data for a willMessage. * Data for a willMessage.
*/ */
typedef struct typedef struct
{ {
char* topic; char* topic;
char* msg; char* msg;
int retained; int retained;
int qos; int qos;
}willMessages; } willMessages;
/** /**
* Data for a connack packet. * Data for a connack packet.
*/ */
typedef struct typedef struct
{ {
Header header; /**< MQTT header byte */ Header header; /**< MQTT header byte */
union union
{ {
unsigned char all; /**< all connack flags */ unsigned char all; /**< all connack flags */
#if defined(REVERSED) #if defined(REVERSED)
struct struct
{ {
unsigned int reserved : 7; /**< message type nibble */ unsigned int reserved : 7; /**< message type nibble */
bool sessionPresent : 1; /**< was a session found on the server? */ bool sessionPresent : 1; /**< was a session found on the server? */
} bits; }bits;
#else #else
struct struct
{ {
bool sessionPresent : 1; /**< was a session found on the server? */ bool sessionPresent :1; /**< was a session found on the server? */
unsigned int reserved : 7; /**< message type nibble */ unsigned int reserved :7; /**< message type nibble */
} bits; } bits;
#endif #endif
} flags; /**< connack flags byte */ } flags; /**< connack flags byte */
char rc; /**< connack return code */ char rc; /**< connack return code */
} Connack; } Connack;
/** /**
* Data for a publish packet. * Data for a publish packet.
*/ */
typedef struct typedef struct
{ {
Header header; /**< MQTT header byte */ Header header; /**< MQTT header byte */
char* topic; /**< topic string */ char* topic; /**< topic string */
int topiclen; int topiclen;
int msgId; /**< MQTT message id */ int msgId; /**< MQTT message id */
char* payload; /**< binary payload, length delimited */ char* payload; /**< binary payload, length delimited */
int payloadlen; /**< payload length */ int payloadlen; /**< payload length */
} Publish; } Publish;
#define MQTTPacket_Publish_Initializer {{0}, nullptr, 0, 0, nullptr, 0} #define MQTTPacket_Publish_Initializer {{0}, nullptr, 0, 0, nullptr, 0}
@@ -181,8 +189,8 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
Header header; /**< MQTT header byte */ Header header; /**< MQTT header byte */
int msgId; /**< MQTT message id */ int msgId; /**< MQTT message id */
} Ack; } Ack;
/** /**
@@ -190,8 +198,8 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
unsigned char len; unsigned char len;
char* data; char* data;
} UTF8String; } UTF8String;
/** /**
@@ -200,39 +208,41 @@ typedef struct
class MQTTGWPacket class MQTTGWPacket
{ {
public: public:
MQTTGWPacket(); MQTTGWPacket();
~MQTTGWPacket(); ~MQTTGWPacket();
int recv(Network* network); int recv(Network* network);
int send(Network* network); int send(Network* network);
int getType(void); int getType(void);
int getPacketData(unsigned char* buf); int getPacketData(unsigned char* buf);
int getPacketLength(void); int getPacketLength(void);
const char* getName(void); const char* getName(void);
int getAck(Ack* ack); int getAck(Ack* ack);
int getCONNACK(Connack* resp); int getCONNACK(Connack* resp);
int getSUBACK(unsigned short* msgId, unsigned char* rc); int getSUBACK(unsigned short* msgId, unsigned char* rc);
int getPUBLISH(Publish* pub); int getPUBLISH(Publish* pub);
int setCONNECT(Connect* conect, unsigned char* username, unsigned char* password); int setCONNECT(Connect* conect, unsigned char* username,
int setPUBLISH(Publish* pub); unsigned char* password);
int setAck(unsigned char msgType, unsigned short msgid); int setPUBLISH(Publish* pub);
int setHeader(unsigned char msgType); int setAck(unsigned char msgType, unsigned short msgid);
int setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId); int setHeader(unsigned char msgType);
int setUNSUBSCRIBE(const char* topics, 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); UTF8String getTopic(void);
char* getMsgId(char* buf); char* getMsgId(char* buf);
int getMsgId(void); int getMsgId(void);
void setMsgId(int msgId); void setMsgId(int msgId);
char* print(char* buf); char* print(char* buf);
MQTTGWPacket& operator =(MQTTGWPacket& packet); MQTTGWPacket& operator =(MQTTGWPacket& packet);
private: private:
void clearData(void); void clearData(void);
Header _header; Header _header;
int _remainingLength; int _remainingLength;
unsigned char* _data; unsigned char* _data;
}; };
} }

View File

@@ -27,7 +27,7 @@ char* currentDateTime(void);
MQTTGWPublishHandler::MQTTGWPublishHandler(Gateway* gateway) MQTTGWPublishHandler::MQTTGWPublishHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTGWPublishHandler::~MQTTGWPublishHandler() MQTTGWPublishHandler::~MQTTGWPublishHandler()
@@ -37,266 +37,283 @@ MQTTGWPublishHandler::~MQTTGWPublishHandler()
void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet) 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",
return; ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
} return;
}
/* client is sleeping. save PUBLISH */ /* client is sleeping. save PUBLISH */
if ( client->isSleep() ) if (client->isSleep())
{ {
Publish pub; Publish pub;
packet->getPUBLISH(&pub); packet->getPUBLISH(&pub);
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(),
RIGHTARROW, client->getClientId(), "is sleeping. a message was saved."); RIGHTARROW, client->getClientId(), "is sleeping. a message was saved.");
if (pub.header.bits.qos == 1) if (pub.header.bits.qos == 1)
{ {
replyACK(client, &pub, PUBACK); replyACK(client, &pub, PUBACK);
} }
else if ( pub.header.bits.qos == 2) else if (pub.header.bits.qos == 2)
{ {
replyACK(client, &pub, PUBREC); replyACK(client, &pub, PUBREC);
} }
MQTTGWPacket* msg = new MQTTGWPacket(); MQTTGWPacket* msg = new MQTTGWPacket();
*msg = *packet; *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",
delete msg; ERRMSG_HEADER, ERRMSG_FOOTER);
return; delete msg;
} return;
client->setClientSleepPacket(msg); }
return; client->setClientSleepPacket(msg);
} return;
}
Publish pub; Publish pub;
packet->getPUBLISH(&pub); packet->getPUBLISH(&pub);
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
/* create MQTTSN_topicid */ /* create MQTTSN_topicid */
MQTTSN_topicid topicId; MQTTSN_topicid topicId;
uint16_t id = 0; uint16_t id = 0;
if (pub.topiclen <= 2) if (pub.topiclen <= 2)
{ {
topicId.type = MQTTSN_TOPIC_TYPE_SHORT; topicId.type = MQTTSN_TOPIC_TYPE_SHORT;
*(topicId.data.short_name) = *pub.topic; *(topicId.data.short_name) = *pub.topic;
*(topicId.data.short_name + 1) = *(pub.topic + 1); *(topicId.data.short_name + 1) = *(pub.topic + 1);
} }
else else
{ {
topicId.data.long_.len = pub.topiclen; topicId.data.long_.len = pub.topiclen;
topicId.data.long_.name = pub.topic; topicId.data.long_.name = pub.topic;
Topic* tp = client->getTopics()->getTopicByName(&topicId); Topic* tp = client->getTopics()->getTopicByName(&topicId);
if ( tp ) if (tp)
{ {
topicId.type = tp->getType(); topicId.type = tp->getType();
topicId.data.long_.len = pub.topiclen; topicId.data.long_.len = pub.topiclen;
topicId.data.long_.name = pub.topic; topicId.data.long_.name = pub.topic;
topicId.data.id = tp->getTopicId();
} }
else 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; topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
Topic* topic = client->getTopics()->match(&topicId); Topic* topic = client->getTopics()->match(&topicId);
if (topic == nullptr)
{
WRITELOG(" Invalid Topic. PUBLISH message is canceled.\n");
if (pub.header.bits.qos == 1)
{
replyACK(client, &pub, PUBACK);
}
else if ( pub.header.bits.qos == 2 )
{
replyACK(client, &pub, PUBREC);
}
delete snPacket; if (topic == nullptr && client->isCleanSession())
return; {
} 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)
{
replyACK(client, &pub, PUBREC);
}
/* add the Topic and get a TopicId */ delete snPacket;
topic = client->getTopics()->add(&topicId); return;
id = topic->getTopicId(); }
if (id > 0) if (topic == nullptr)
{ {
/* create REGISTER */ topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
MQTTSNPacket* regPacket = new MQTTSNPacket(); topicId.data.long_.len = pub.topiclen;
topicId.data.long_.name = pub.topic;
topicId.data.id = 0;
}
MQTTSNString topicName = MQTTSNString_initializer; /* add the Topic and get a TopicId */
topicName.lenstring.len = topicId.data.long_.len; topic = client->getTopics()->add(&topicId);
topicName.lenstring.data = topicId.data.long_.name; 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 */
MQTTSNPacket* regPacket = new MQTTSNPacket();
uint16_t regackMsgId = client->getNextSnMsgId(); MQTTSNString topicName = MQTTSNString_initializer;
regPacket->setREGISTER(id, regackMsgId, &topicName); topicName.lenstring.len = topicId.data.long_.len;
topicName.lenstring.data = topicId.data.long_.name;
/* send REGISTER */ uint16_t regackMsgId = client->getNextSnMsgId();
Event* evrg = new Event(); regPacket->setREGISTER(id, regackMsgId, &topicName);
evrg->setClientSendEvent(client, regPacket);
_gateway->getClientSendQue()->post(evrg);
/* send PUBLISH */ /* send REGISTER */
topicId.data.id = id; Event* evrg = new Event();
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, evrg->setClientSendEvent(client, regPacket);
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, _gateway->getClientSendQue()->post(evrg);
pub.payloadlen);
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
return;
}
else
{
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
delete snPacket;
return;
}
}
}
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain, /* send PUBLISH */
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen); topicId.data.id = id;
Event* ev1 = new Event(); snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
ev1->setClientSendEvent(client, snPacket); (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
_gateway->getClientSendQue()->post(ev1); client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
return;
}
else
{
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
ERRMSG_HEADER, ERRMSG_FOOTER);
delete snPacket;
return;
}
}
}
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);
Event* ev1 = new Event();
ev1->setClientSendEvent(client, snPacket);
_gateway->getClientSendQue()->post(ev1);
} }
void MQTTGWPublishHandler::replyACK(Client* client, Publish* pub, int type) void MQTTGWPublishHandler::replyACK(Client* client, Publish* pub, int type)
{ {
MQTTGWPacket* pubAck = new MQTTGWPacket(); MQTTGWPacket* pubAck = new MQTTGWPacket();
pubAck->setAck(type, (uint16_t)pub->msgId); pubAck->setAck(type, (uint16_t) pub->msgId);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, pubAck); ev1->setBrokerSendEvent(client, pubAck);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
} }
void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet) void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t)ack.msgId); TopicIdMapElement* topicId = client->getWaitedPubTopicId((uint16_t) ack.msgId);
if (topicId) if (topicId)
{ {
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket(); 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(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, mqttsnPacket); ev1->setClientSendEvent(client, mqttsnPacket);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
return; 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) void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int type)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
if ( client->isActive() || client->isAwake() ) if (client->isActive() || client->isAwake())
{ {
MQTTSNPacket* mqttsnPacket = new MQTTSNPacket(); MQTTSNPacket* mqttsnPacket = new MQTTSNPacket();
if (type == PUBREC) if (type == PUBREC)
{ {
mqttsnPacket->setPUBREC((uint16_t) ack.msgId); mqttsnPacket->setPUBREC((uint16_t) ack.msgId);
} }
else if (type == PUBREL) else if (type == PUBREL)
{ {
mqttsnPacket->setPUBREL((uint16_t) ack.msgId); mqttsnPacket->setPUBREL((uint16_t) ack.msgId);
} }
else if (type == PUBCOMP) else if (type == PUBCOMP)
{ {
mqttsnPacket->setPUBCOMP((uint16_t) ack.msgId); mqttsnPacket->setPUBCOMP((uint16_t) ack.msgId);
} }
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, mqttsnPacket); ev1->setClientSendEvent(client, mqttsnPacket);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
else if ( client->isSleep() ) else if (client->isSleep())
{ {
if (type == PUBREL) if (type == PUBREL)
{ {
MQTTGWPacket* pubComp = new MQTTGWPacket(); MQTTGWPacket* pubComp = new MQTTGWPacket();
pubComp->setAck(PUBCOMP, (uint16_t)ack.msgId); pubComp->setAck(PUBCOMP, (uint16_t) ack.msgId);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, pubComp); ev1->setBrokerSendEvent(client, pubComp);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
} }
} }
} }
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet) void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId); Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
if ( newClient != nullptr ) if (newClient != nullptr)
{ {
packet->setMsgId((int)clientMsgId); packet->setMsgId((int) clientMsgId);
handlePuback(newClient, packet); handlePuback(newClient, packet);
} }
} }
void MQTTGWPublishHandler::handleAggregateAck(Client* client, MQTTGWPacket* packet, int type) void MQTTGWPublishHandler::handleAggregateAck(Client* client, MQTTGWPacket* packet, int type)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId); Client* newClient = _gateway->getAdapterManager()->convertClient(msgId, &clientMsgId);
if ( newClient != nullptr ) if (newClient != nullptr)
{ {
packet->setMsgId((int)clientMsgId); packet->setMsgId((int) clientMsgId);
handleAck(newClient, packet,type); handleAck(newClient, packet, type);
} }
} }
void MQTTGWPublishHandler::handleAggregatePubrel(Client* client, MQTTGWPacket* packet) void MQTTGWPublishHandler::handleAggregatePubrel(Client* client, MQTTGWPacket* packet)
{ {
Publish pub; Publish pub;
packet->getPUBLISH(&pub); packet->getPUBLISH(&pub);
replyACK(client, &pub, PUBCOMP); replyACK(client, &pub, PUBCOMP);
} }
void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket* packet) void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket* packet)
{ {
Publish pub; Publish pub;
packet->getPUBLISH(&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);
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted // ToDo: need to refactor
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic);
// ToDo: need to refactor while (elm != nullptr)
ClientTopicElement* elm = _gateway->getAdapterManager()->getAggregater()->getClientElement(&topic); {
Client* devClient = elm->getClient();
MQTTGWPacket* msg = new MQTTGWPacket();
*msg = *packet;
while ( elm != nullptr ) if (msg->getType() == 0)
{ {
Client* devClient = elm->getClient(); WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
MQTTGWPacket* msg = new MQTTGWPacket(); ERRMSG_HEADER, ERRMSG_FOOTER);
*msg = *packet; delete msg;
break;
}
if ( msg->getType() == 0 ) Event* ev = new Event();
{ ev->setBrokerRecvEvent(devClient, msg);
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER); _gateway->getPacketEventQue()->post(ev);
delete msg;
break;
}
Event* ev = new Event(); elm = elm->getNextClientElement();
ev->setBrokerRecvEvent(devClient, msg); }
_gateway->getPacketEventQue()->post(ev);
elm = elm->getNextClientElement();
}
} }

View File

@@ -26,25 +26,23 @@ namespace MQTTSNGW
class MQTTGWPublishHandler class MQTTGWPublishHandler
{ {
public: public:
MQTTGWPublishHandler(Gateway* gateway); MQTTGWPublishHandler(Gateway* gateway);
~MQTTGWPublishHandler(); ~MQTTGWPublishHandler();
void handlePublish(Client* client, MQTTGWPacket* packet); void handlePublish(Client* client, MQTTGWPacket* packet);
void handlePuback(Client* client, MQTTGWPacket* packet); void handlePuback(Client* client, MQTTGWPacket* packet);
void handleAck(Client* client, MQTTGWPacket* packet, int type); void handleAck(Client* client, MQTTGWPacket* packet, int type);
void handleAggregatePublish(Client* client, MQTTGWPacket* packet); void handleAggregatePublish(Client* client, MQTTGWPacket* packet);
void handleAggregatePuback(Client* client, MQTTGWPacket* packet); void handleAggregatePuback(Client* client, MQTTGWPacket* packet);
void handleAggregateAck(Client* client, MQTTGWPacket* packet, int type); void handleAggregateAck(Client* client, MQTTGWPacket* packet, int type);
void handleAggregatePubrel(Client* client, MQTTGWPacket* packet); void handleAggregatePubrel(Client* client, MQTTGWPacket* packet);
private: private:
void replyACK(Client* client, Publish* pub, int type); void replyACK(Client* client, Publish* pub, int type);
Gateway* _gateway; Gateway* _gateway;
}; };
} }
#endif /* MQTTGWPUBLISHHANDLER_H_ */ #endif /* MQTTGWPUBLISHHANDLER_H_ */

View File

@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
MQTTGWSubscribeHandler::MQTTGWSubscribeHandler(Gateway* gateway) MQTTGWSubscribeHandler::MQTTGWSubscribeHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTGWSubscribeHandler::~MQTTGWSubscribeHandler() MQTTGWSubscribeHandler::~MQTTGWSubscribeHandler()
@@ -32,68 +32,67 @@ MQTTGWSubscribeHandler::~MQTTGWSubscribeHandler()
void MQTTGWSubscribeHandler::handleSuback(Client* client, MQTTGWPacket* packet) void MQTTGWSubscribeHandler::handleSuback(Client* client, MQTTGWPacket* packet)
{ {
uint16_t msgId; uint16_t msgId;
uint8_t rc; uint8_t rc;
uint8_t returnCode; uint8_t returnCode;
int qos = 0; int qos = 0;
packet->getSUBACK(&msgId, &rc); packet->getSUBACK(&msgId, &rc);
TopicIdMapElement* topicId = client->getWaitedSubTopicId(msgId); TopicIdMapElement* topicId = client->getWaitedSubTopicId(msgId);
if (topicId) if (topicId)
{ {
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
if (rc == 0x80) if (rc == 0x80)
{ {
returnCode = MQTTSN_RC_REJECTED_INVALID_TOPIC_ID; returnCode = MQTTSN_RC_REJECTED_INVALID_TOPIC_ID;
} }
else else
{ {
returnCode = MQTTSN_RC_ACCEPTED; returnCode = MQTTSN_RC_ACCEPTED;
qos = rc; qos = rc;
} }
snPacket->setSUBACK(qos, topicId->getTopicId(), msgId, returnCode); snPacket->setSUBACK(qos, topicId->getTopicId(), msgId, returnCode);
Event* evt = new Event(); Event* evt = new Event();
evt->setClientSendEvent(client, snPacket); evt->setClientSendEvent(client, snPacket);
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
client->eraseWaitedSubTopicId(msgId); client->eraseWaitedSubTopicId(msgId);
} }
} }
void MQTTGWSubscribeHandler::handleUnsuback(Client* client, MQTTGWPacket* packet) void MQTTGWSubscribeHandler::handleUnsuback(Client* client, MQTTGWPacket* packet)
{ {
Ack ack; Ack ack;
packet->getAck(&ack); packet->getAck(&ack);
MQTTSNPacket* snPacket = new MQTTSNPacket(); MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setUNSUBACK(ack.msgId); snPacket->setUNSUBACK(ack.msgId);
Event* evt = new Event(); Event* evt = new Event();
evt->setClientSendEvent(client, snPacket); evt->setClientSendEvent(client, snPacket);
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
} }
void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, MQTTGWPacket* packet) void MQTTGWSubscribeHandler::handleAggregateSuback(Client* client, MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId); 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); handleSuback(newClient, packet);
} }
} }
void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacket* packet) void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacket* packet)
{ {
uint16_t msgId = packet->getMsgId(); uint16_t msgId = packet->getMsgId();
uint16_t clientMsgId = 0; uint16_t clientMsgId = 0;
Client* newClient = _gateway->getAdapterManager()->getAggregater()->convertClient(msgId, &clientMsgId); 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); handleUnsuback(newClient, packet);
} }
} }

View File

@@ -27,15 +27,15 @@ namespace MQTTSNGW
class MQTTGWSubscribeHandler class MQTTGWSubscribeHandler
{ {
public: public:
MQTTGWSubscribeHandler(Gateway* gateway); MQTTGWSubscribeHandler(Gateway* gateway);
~MQTTGWSubscribeHandler(); ~MQTTGWSubscribeHandler();
void handleSuback(Client* clnode, MQTTGWPacket* packet); void handleSuback(Client* clnode, MQTTGWPacket* packet);
void handleUnsuback(Client* clnode, MQTTGWPacket* packet); void handleUnsuback(Client* clnode, MQTTGWPacket* packet);
void handleAggregateSuback(Client* client, MQTTGWPacket* packet); void handleAggregateSuback(Client* client, MQTTGWPacket* packet);
void handleAggregateUnsuback(Client* client, MQTTGWPacket* packet); void handleAggregateUnsuback(Client* client, MQTTGWPacket* packet);
private: private:
Gateway* _gateway; Gateway* _gateway;
}; };
} }

View File

@@ -28,7 +28,7 @@ using namespace MQTTSNGW;
=====================================*/ =====================================*/
MQTTSNAggregateConnectionHandler::MQTTSNAggregateConnectionHandler(Gateway* gateway) MQTTSNAggregateConnectionHandler::MQTTSNAggregateConnectionHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler() MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
@@ -36,124 +36,121 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
} }
/* /*
* CONNECT * CONNECT
*/ */
void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet) void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
{ {
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
if ( packet->getCONNECT(&data) == 0 ) if (packet->getCONNECT(&data) == 0)
{ {
return; return;
} }
/* return CONNACK when the client is sleeping */ /* return CONNACK when the client is sleeping */
if ( client->isSleep() || client->isAwake() ) if (client->isSleep() || client->isAwake())
{ {
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
packet->setCONNACK(MQTTSN_RC_ACCEPTED); packet->setCONNACK(MQTTSN_RC_ACCEPTED);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, packet); ev->setClientSendEvent(client, packet);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
sendStoredPublish(client); sendStoredPublish(client);
return; return;
} }
//* clear ConnectData of Client */ //* clear ConnectData of Client */
Connect* connectData = client->getConnectData(); Connect* connectData = client->getConnectData();
memset(connectData, 0, sizeof(Connect)); memset(connectData, 0, sizeof(Connect));
client->disconnected(); client->disconnected();
Topics* topics = client->getTopics(); Topics* topics = client->getTopics();
/* CONNECT was not sent yet. prepare Connect data */ /* CONNECT was not sent yet. prepare Connect data */
client->setSessionStatus(false);
if (data.cleansession)
{
/* reset the table of msgNo and TopicId pare */
client->clearWaitedPubTopicId();
client->clearWaitedSubTopicId();
client->setSessionStatus(false); /* renew the TopicList */
if (data.cleansession) if (topics)
{ {
/* reset the table of msgNo and TopicId pare */ Topic* tp = topics->getFirstTopic();
client->clearWaitedPubTopicId(); while (tp != nullptr)
client->clearWaitedSubTopicId(); {
if (tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL)
{
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
}
tp = topics->getNextTopic(tp);
}
topics->eraseNormal();
}
client->setSessionStatus(true);
}
/* renew the TopicList */ if (data.willFlag)
if (topics) {
{ /* create & send WILLTOPICREQ message to the client */
Topic* tp = topics->getFirstTopic(); MQTTSNPacket* reqTopic = new MQTTSNPacket();
while( tp != nullptr ) reqTopic->setWILLTOPICREQ();
{ Event* evwr = new Event();
if ( tp->getType() == MQTTSN_TOPIC_TYPE_NORMAL ) evwr->setClientSendEvent(client, reqTopic);
{
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(tp, client);
}
tp = topics->getNextTopic(tp);
}
topics->eraseNormal();
}
client->setSessionStatus(true);
}
if (data.willFlag) /* Send WILLTOPICREQ to the client */
{ _gateway->getClientSendQue()->post(evwr);
/* create & send WILLTOPICREQ message to the client */ }
MQTTSNPacket* reqTopic = new MQTTSNPacket(); else
reqTopic->setWILLTOPICREQ(); {
Event* evwr = new Event(); /* create CONNACK & send it to the client */
evwr->setClientSendEvent(client, reqTopic); MQTTSNPacket* packet = new MQTTSNPacket();
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
/* Send WILLTOPICREQ to the client */ Event* ev = new Event();
_gateway->getClientSendQue()->post(evwr); ev->setClientSendEvent(client, packet);
} _gateway->getClientSendQue()->post(ev);
else client->connackSended(MQTTSN_RC_ACCEPTED);
{ sendStoredPublish(client);
/* create CONNACK & send it to the client */ return;
MQTTSNPacket* packet = new MQTTSNPacket(); }
packet->setCONNACK(MQTTSN_RC_ACCEPTED);
Event* ev = new Event();
ev->setClientSendEvent(client, packet);
_gateway->getClientSendQue()->post(ev);
client->connackSended(MQTTSN_RC_ACCEPTED);
sendStoredPublish(client);
return;
}
} }
/* /*
* WILLMSG * WILLMSG
*/ */
void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet) void MQTTSNAggregateConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
{ {
if ( !client->isWaitWillMsg() ) if (!client->isWaitWillMsg())
{ {
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n"); DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
return; return;
} }
MQTTSNString willmsg = MQTTSNString_initializer; MQTTSNString willmsg = MQTTSNString_initializer;
//Connect* connectData = client->getConnectData(); //Connect* connectData = client->getConnectData();
if( client->isConnectSendable() ) if (client->isConnectSendable())
{ {
/* save WillMsg in the client */ /* save WillMsg in the client */
if ( packet->getWILLMSG(&willmsg) == 0 ) if (packet->getWILLMSG(&willmsg) == 0)
{ {
return; return;
} }
client->setWillMsg(willmsg); client->setWillMsg(willmsg);
/* Send CONNACK to the client */ /* Send CONNACK to the client */
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
packet->setCONNACK(MQTTSN_RC_ACCEPTED); packet->setCONNACK(MQTTSN_RC_ACCEPTED);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, packet); ev->setClientSendEvent(client, packet);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
sendStoredPublish(client); sendStoredPublish(client);
return; return;
} }
} }
/* /*
@@ -173,31 +170,31 @@ void MQTTSNAggregateConnectionHandler::handleDisconnect(Client* client, MQTTSNPa
*/ */
void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet) void MQTTSNAggregateConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
{ {
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() ) if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
{ {
sendStoredPublish(client); sendStoredPublish(client);
client->holdPingRequest(); client->holdPingRequest();
} }
/* create and send PINGRESP to the PacketHandler */ /* create and send PINGRESP to the PacketHandler */
client->resetPingRequest(); client->resetPingRequest();
MQTTGWPacket* pingresp = new MQTTGWPacket(); MQTTGWPacket* pingresp = new MQTTGWPacket();
pingresp->setHeader(PINGRESP); pingresp->setHeader(PINGRESP);
Event* evt = new Event(); Event* evt = new Event();
evt->setBrokerRecvEvent(client, pingresp); evt->setBrokerRecvEvent(client, pingresp);
_gateway->getPacketEventQue()->post(evt); _gateway->getPacketEventQue()->post(evt);
} }
void MQTTSNAggregateConnectionHandler::sendStoredPublish(Client* client) void MQTTSNAggregateConnectionHandler::sendStoredPublish(Client* client)
{ {
MQTTGWPacket* msg = nullptr; MQTTGWPacket* msg = nullptr;
while ( ( msg = client->getClientSleepPacket() ) != nullptr ) while ((msg = client->getClientSleepPacket()) != nullptr)
{ {
client->deleteFirstClientSleepPacket(); // pop the que to delete element. client->deleteFirstClientSleepPacket(); // pop the que to delete element.
Event* ev = new Event(); Event* ev = new Event();
ev->setBrokerRecvEvent(client, msg); ev->setBrokerRecvEvent(client, msg);

View File

@@ -28,18 +28,18 @@ class MQTTSNPacket;
class MQTTSNAggregateConnectionHandler class MQTTSNAggregateConnectionHandler
{ {
public: public:
MQTTSNAggregateConnectionHandler(Gateway* gateway); MQTTSNAggregateConnectionHandler(Gateway* gateway);
~MQTTSNAggregateConnectionHandler(void); ~MQTTSNAggregateConnectionHandler(void);
void handleConnect(Client* client, MQTTSNPacket* packet); void handleConnect(Client* client, MQTTSNPacket* packet);
void handleWillmsg(Client* client, MQTTSNPacket* packet); void handleWillmsg(Client* client, MQTTSNPacket* packet);
void handleDisconnect(Client* client, MQTTSNPacket* packet); void handleDisconnect(Client* client, MQTTSNPacket* packet);
void handlePingreq(Client* client, MQTTSNPacket* packet); void handlePingreq(Client* client, MQTTSNPacket* packet);
private: private:
void sendStoredPublish(Client* client); void sendStoredPublish(Client* client);
Gateway* _gateway; Gateway* _gateway;
}; };
} }

View File

@@ -24,116 +24,114 @@
#include <string.h> #include <string.h>
using namespace MQTTSNGW; using namespace MQTTSNGW;
/*===================================== /*=====================================
Class Adapter Class Adapter
=====================================*/ =====================================*/
Adapter:: Adapter(Gateway* gw) Adapter::Adapter(Gateway* gw)
{ {
_gateway = gw; _gateway = gw;
_proxy = new Proxy(gw); _proxy = new Proxy(gw);
_proxySecure = new Proxy(gw); _proxySecure = new Proxy(gw);
} }
Adapter::~Adapter(void) Adapter::~Adapter(void)
{ {
if ( _proxy ) if (_proxy)
{ {
delete _proxy; delete _proxy;
} }
if ( _proxySecure ) if (_proxySecure)
{ {
delete _proxySecure; delete _proxySecure;
} }
} }
void Adapter::setup(const char* adpterName, AdapterType adapterType) void Adapter::setup(const char* adpterName, AdapterType adapterType)
{ {
_isSecure = false; _isSecure = false;
if ( _gateway->hasSecureConnection() ) if (_gateway->hasSecureConnection())
{ {
_isSecure = true; _isSecure = true;
} }
MQTTSNString id = MQTTSNString_initializer; MQTTSNString id = MQTTSNString_initializer;
MQTTSNString idSecure = MQTTSNString_initializer; MQTTSNString idSecure = MQTTSNString_initializer;
string name = string(adpterName); string name = string(adpterName);
id.cstring = const_cast<char*>(name.c_str()); id.cstring = const_cast<char*>(name.c_str());
string nameSecure = string(adpterName) + "-S"; string nameSecure = string(adpterName) + "-S";
idSecure.cstring = const_cast<char*>(nameSecure.c_str()); idSecure.cstring = const_cast<char*>(nameSecure.c_str());
Client* client = _gateway->getClientList()->createClient(0, &id, true, false, TRANSPEARENT_TYPE); Client* client = _gateway->getClientList()->createClient(0, &id, true, false, TRANSPEARENT_TYPE);
setClient(client, false); setClient(client, false);
client->setAdapterType(adapterType); client->setAdapterType(adapterType);
client = _gateway->getClientList()->createClient(0, &idSecure, true, true, TRANSPEARENT_TYPE); client = _gateway->getClientList()->createClient(0, &idSecure, true, true,
setClient(client, true); TRANSPEARENT_TYPE);
client->setAdapterType(adapterType); setClient(client, true);
client->setAdapterType(adapterType);
} }
Client* Adapter::getClient(SensorNetAddress* addr) Client* Adapter::getClient(SensorNetAddress* addr)
{ {
Client* client = _gateway->getClientList()->getClient(addr); Client* client = _gateway->getClientList()->getClient(addr);
if ( !client ) if (!client)
{
return nullptr;
}
else if ( client->isQoSm1() )
{
return client;
}
else
{
return nullptr;
}
}
const char* Adapter::getClientId(SensorNetAddress* addr)
{
Client* client = getClient(addr);
if ( !client )
{ {
return nullptr; return nullptr;
} }
else if ( client->isQoSm1() ) else if (client->isQoSm1())
{ {
return client->getClientId(); return client;
} }
else else
{ {
return nullptr; return nullptr;
}
}
const char* Adapter::getClientId(SensorNetAddress* addr)
{
Client* client = getClient(addr);
if (!client)
{
return nullptr;
}
else if (client->isQoSm1())
{
return client->getClientId();
}
else
{
return nullptr;
} }
} }
bool Adapter::isSecure(SensorNetAddress* addr) bool Adapter::isSecure(SensorNetAddress* addr)
{ {
Client* client = getClient(addr); Client* client = getClient(addr);
if ( !client ) if (!client)
{ {
return false; return false;
} }
else if ( client->isSecureNetwork() ) else if (client->isSecureNetwork())
{ {
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
bool Adapter::isSecure(void) bool Adapter::isSecure(void)
{ {
return _isSecure; return _isSecure;
} }
void Adapter::setClient(Client* client, bool secure) void Adapter::setClient(Client* client, bool secure)
{ {
if ( secure ) if (secure)
{ {
_clientSecure = client; _clientSecure = client;
} }
@@ -157,7 +155,7 @@ void Adapter::checkConnection(void)
{ {
_proxy->checkConnection(_client); _proxy->checkConnection(_client);
if ( _isSecure ) if (_isSecure)
{ {
_proxySecure->checkConnection(_clientSecure); _proxySecure->checkConnection(_clientSecure);
} }
@@ -166,15 +164,16 @@ void Adapter::checkConnection(void)
void Adapter::send(MQTTSNPacket* packet, Client* client) void Adapter::send(MQTTSNPacket* packet, Client* client)
{ {
Proxy* proxy = _proxy; Proxy* proxy = _proxy;
if ( client->isSecureNetwork() && !_isSecure ) if (client->isSecureNetwork() && !_isSecure)
{ {
if ( _isSecure ) if (_isSecure)
{ {
proxy = _proxySecure; proxy = _proxySecure;
} }
else 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; return;
} }
} }
@@ -185,13 +184,13 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
void Adapter::resetPingTimer(bool secure) void Adapter::resetPingTimer(bool secure)
{ {
if ( secure ) if (secure)
{ {
_proxySecure->resetPingTimer(); _proxySecure->resetPingTimer();
} }
else else
{ {
_proxy->resetPingTimer(); _proxy->resetPingTimer();
} }
} }
@@ -202,48 +201,47 @@ bool Adapter::isActive(void)
void Adapter::savePacket(Client* client, MQTTSNPacket* packet) void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
{ {
if ( client->isSecureNetwork()) if (client->isSecureNetwork())
{ {
_proxySecure->savePacket(client, packet); _proxySecure->savePacket(client, packet);
} }
else else
{ {
_proxy->savePacket(client, packet); _proxy->savePacket(client, packet);
} }
} }
Client* Adapter::getAdapterClient(Client* client) Client* Adapter::getAdapterClient(Client* client)
{ {
if ( client->isSecureNetwork() ) if (client->isSecureNetwork())
{ {
return _clientSecure; return _clientSecure;
} }
else else
{ {
return _client; return _client;
} }
} }
/*===================================== /*=====================================
Class Proxy Class Proxy
=====================================*/ =====================================*/
Proxy::Proxy(Gateway* gw) Proxy::Proxy(Gateway* gw)
{ {
_gateway = gw; _gateway = gw;
_suspendedPacketEventQue = new EventQue(); _suspendedPacketEventQue = new EventQue();
} }
Proxy::~Proxy(void) Proxy::~Proxy(void)
{ {
if ( _suspendedPacketEventQue ) if (_suspendedPacketEventQue)
{ {
delete _suspendedPacketEventQue; delete _suspendedPacketEventQue;
} }
} }
void Proxy::checkConnection(Client* client) void Proxy::checkConnection(Client* client)
{ {
if ( client->isDisconnect() || ( client->isConnecting() && _responseTimer.isTimeup()) ) if (client->isDisconnect() || (client->isConnecting() && _responseTimer.isTimeup()))
{ {
client->connectSended(); client->connectSended();
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL); _responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
@@ -257,26 +255,25 @@ void Proxy::checkConnection(Client* client)
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
_gateway->getPacketEventQue()->post(ev); _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(); MQTTSNPacket* packet = new MQTTSNPacket();
MQTTSNString clientId = MQTTSNString_initializer; MQTTSNString clientId = MQTTSNString_initializer;
packet->setPINGREQ(&clientId); packet->setPINGREQ(&clientId);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
_gateway->getPacketEventQue()->post(ev); _gateway->getPacketEventQue()->post(ev);
_responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL); _responseTimer.start(PROXY_RESPONSE_DURATION * 1000UL);
_isWaitingResp = true; _isWaitingResp = true;
if ( ++_retryCnt > PROXY_MAX_RETRY_CNT ) if (++_retryCnt > PROXY_MAX_RETRY_CNT)
{ {
client->disconnected(); client->disconnected();
} }
resetPingTimer(); resetPingTimer();
} }
} }
void Proxy::resetPingTimer(void) void Proxy::resetPingTimer(void)
{ {
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL); _keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
@@ -284,24 +281,24 @@ void Proxy::resetPingTimer(void)
void Proxy::recv(MQTTSNPacket* packet, Client* client) 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(); _responseTimer.stop();
_retryCnt = 0; _retryCnt = 0;
resetPingTimer(); resetPingTimer();
sendSuspendedPacket(); sendSuspendedPacket();
} }
} }
else if ( packet->getType() == MQTTSN_PINGRESP ) else if (packet->getType() == MQTTSN_PINGRESP)
{ {
_isWaitingResp = false; _isWaitingResp = false;
_responseTimer.stop(); _responseTimer.stop();
_retryCnt = 0; _retryCnt = 0;
resetPingTimer(); resetPingTimer();
} }
else if ( packet->getType() == MQTTSN_DISCONNECT ) else if (packet->getType() == MQTTSN_DISCONNECT)
{ {
// blank // blank
} }
@@ -309,18 +306,18 @@ void Proxy::recv(MQTTSNPacket* packet, Client* client)
void Proxy::savePacket(Client* client, MQTTSNPacket* packet) void Proxy::savePacket(Client* client, MQTTSNPacket* packet)
{ {
MQTTSNPacket* pk = new MQTTSNPacket(*packet); MQTTSNPacket* pk = new MQTTSNPacket(*packet);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientRecvEvent(client, pk); ev->setClientRecvEvent(client, pk);
_suspendedPacketEventQue->post(ev); _suspendedPacketEventQue->post(ev);
} }
void Proxy::sendSuspendedPacket(void) void Proxy::sendSuspendedPacket(void)
{ {
while ( _suspendedPacketEventQue->size() ) while (_suspendedPacketEventQue->size())
{ {
Event* ev = _suspendedPacketEventQue->wait(); Event* ev = _suspendedPacketEventQue->wait();
_gateway->getPacketEventQue()->post(ev); _gateway->getPacketEventQue()->post(ev);
} }
} }

View File

@@ -31,17 +31,18 @@ class EventQue;
class Timer; class Timer;
/* When you add a new type, Client::setAdapterType() and Client::isAdapter() functions must be modified. */ /* When you add a new type, Client::setAdapterType() and Client::isAdapter() functions must be modified. */
typedef enum{ typedef enum
Atype_QoSm1Proxy, Atype_Aggregater {
}AdapterType; Atype_QoSm1Proxy, Atype_Aggregater
} AdapterType;
/*===================================== /*=====================================
Class Adapter Class Adapter
=====================================*/ =====================================*/
class Adapter class Adapter
{ {
public: public:
Adapter(Gateway* gw); Adapter(Gateway* gw);
~Adapter(void); ~Adapter(void);
void setup(const char* adpterName, AdapterType adapterType); void setup(const char* adpterName, AdapterType adapterType);
@@ -60,18 +61,17 @@ public:
void savePacket(Client* client, MQTTSNPacket* packet); void savePacket(Client* client, MQTTSNPacket* packet);
private: private:
Gateway* _gateway {nullptr}; Gateway* _gateway { nullptr };
Proxy* _proxy {nullptr}; Proxy* _proxy { nullptr };
Proxy* _proxySecure {nullptr}; Proxy* _proxySecure { nullptr };
Client* _client {nullptr}; Client* _client { nullptr };
Client* _clientSecure {nullptr}; Client* _clientSecure { nullptr };
bool _isActive {false}; bool _isActive { false };
bool _isSecure{false}; bool _isSecure { false };
}; };
/*===================================== /*=====================================
Class Proxy Class Proxy
=====================================*/ =====================================*/
class Proxy class Proxy
{ {
@@ -88,11 +88,12 @@ public:
private: private:
void sendSuspendedPacket(void); void sendSuspendedPacket(void);
Gateway* _gateway; Gateway* _gateway;
EventQue* _suspendedPacketEventQue {nullptr}; EventQue* _suspendedPacketEventQue
Timer _keepAliveTimer; { nullptr };
Timer _responseTimer; Timer _keepAliveTimer;
bool _isWaitingResp {false}; Timer _responseTimer;
int _retryCnt {0}; bool _isWaitingResp { false };
int _retryCnt { 0 };
}; };
} }

View File

@@ -33,42 +33,41 @@ char* currentDateTime(void);
=====================================*/ =====================================*/
AdapterManager::AdapterManager(Gateway* gw) AdapterManager::AdapterManager(Gateway* gw)
{ {
_gateway = gw; _gateway = gw;
_forwarders = new ForwarderList(); _forwarders = new ForwarderList();
_qosm1Proxy = new QoSm1Proxy(gw); _qosm1Proxy = new QoSm1Proxy(gw);
_aggregater = new Aggregater(gw); _aggregater = new Aggregater(gw);
} }
void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1) void AdapterManager::initialize(char* gwName, bool aggregate, bool forwarder, bool qosM1)
{ {
if ( aggregate ) if (aggregate)
{ {
_aggregater->initialize(gwName); _aggregater->initialize(gwName);
} }
if ( qosM1 ) if (qosM1)
{ {
_qosm1Proxy->initialize(gwName); _qosm1Proxy->initialize(gwName);
} }
if ( forwarder ) if (forwarder)
{ {
_forwarders->initialize(_gateway); _forwarders->initialize(_gateway);
} }
} }
AdapterManager::~AdapterManager(void) AdapterManager::~AdapterManager(void)
{ {
if ( _forwarders ) if (_forwarders)
{ {
delete _forwarders; delete _forwarders;
} }
if ( _qosm1Proxy ) if (_qosm1Proxy)
{ {
delete _qosm1Proxy; delete _qosm1Proxy;
} }
if ( _aggregater ) if (_aggregater)
{ {
delete _aggregater; delete _aggregater;
} }
@@ -91,119 +90,119 @@ Aggregater* AdapterManager::getAggregater(void)
bool AdapterManager::isAggregatedClient(Client* client) 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; return false;
} }
else else
{ {
return true; return true;
} }
} }
Client* AdapterManager::getClient(Client* client) Client* AdapterManager::getClient(Client* client)
{ {
bool secure = client->isSecureNetwork(); bool secure = client->isSecureNetwork();
Client* newClient = client; Client* newClient = client;
if ( client->isQoSm1() ) if (client->isQoSm1())
{ {
newClient = _qosm1Proxy->getAdapterClient(client); newClient = _qosm1Proxy->getAdapterClient(client);
_qosm1Proxy->resetPingTimer(secure); _qosm1Proxy->resetPingTimer(secure);
} }
else if ( client->isAggregated() ) else if (client->isAggregated())
{ {
newClient = _aggregater->getAdapterClient(client); newClient = _aggregater->getAdapterClient(client);
_aggregater->resetPingTimer(secure); _aggregater->resetPingTimer(secure);
} }
else if ( client->isQoSm1Proxy() ) else if (client->isQoSm1Proxy())
{ {
_qosm1Proxy->resetPingTimer(secure); _qosm1Proxy->resetPingTimer(secure);
} }
else if ( client->isAggregater() ) else if (client->isAggregater())
{ {
_aggregater->resetPingTimer(secure); _aggregater->resetPingTimer(secure);
} }
return newClient; return newClient;
} }
int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task) int AdapterManager::unicastToClient(Client* client, MQTTSNPacket* packet, ClientSendTask* task)
{ {
char pbuf[SIZE_OF_LOG_PACKET * 3]; char pbuf[SIZE_OF_LOG_PACKET * 3];
Forwarder* fwd = client->getForwarder(); Forwarder* fwd = client->getForwarder();
int rc = 0; int rc = 0;
if ( fwd ) if (fwd)
{ {
MQTTSNGWEncapsulatedPacket encap(packet); MQTTSNGWEncapsulatedPacket encap(packet);
WirelessNodeId* wnId = fwd->getWirelessNodeId(client); WirelessNodeId* wnId = fwd->getWirelessNodeId(client);
encap.setWirelessNodeId(wnId); encap.setWirelessNodeId(wnId);
task->log(client, packet); task->log(client, packet);
WRITELOG(FORMAT_Y_W_G, currentDateTime(), encap.getName(), RIGHTARROW, fwd->getId(), encap.print(pbuf)); 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 else
{ {
task->log(client, packet); task->log(client, packet);
if ( client->isQoSm1Proxy() ) if (client->isQoSm1Proxy())
{ {
_qosm1Proxy->send(packet, client); _qosm1Proxy->send(packet, client);
} }
else if ( client->isAggregater() ) else if (client->isAggregater())
{ {
_aggregater->send(packet, client); _aggregater->send(packet, client);
} }
else else
{ {
rc = packet->unicast(_gateway->getSensorNetwork(), client->getSensorNetAddress()); rc = packet->unicast(_gateway->getSensorNetwork(), client->getSensorNetAddress());
} }
} }
return rc; return rc;
} }
void AdapterManager::checkConnection(void) void AdapterManager::checkConnection(void)
{ {
if ( _aggregater->isActive()) if (_aggregater->isActive())
{ {
_aggregater->checkConnection(); _aggregater->checkConnection();
} }
if ( _qosm1Proxy->isActive()) if (_qosm1Proxy->isActive())
{ {
_qosm1Proxy->checkConnection(); _qosm1Proxy->checkConnection();
} }
} }
Client* AdapterManager::convertClient(uint16_t msgId, uint16_t* clientMsgId) Client* AdapterManager::convertClient(uint16_t msgId, uint16_t* clientMsgId)
{ {
return _aggregater->convertClient(msgId, clientMsgId); return _aggregater->convertClient(msgId, clientMsgId);
} }
bool AdapterManager::isAggregaterActive(void) bool AdapterManager::isAggregaterActive(void)
{ {
return _aggregater->isActive(); return _aggregater->isActive();
} }
/* /*
AggregateTopicElement* AdapterManager::findTopic(Topic* topic) AggregateTopicElement* AdapterManager::findTopic(Topic* topic)
{ {
return _aggregater->findTopic(topic); return _aggregater->findTopic(topic);
} }
AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client) AggregateTopicElement* AdapterManager::addAggregateTopic(Topic* topic, Client* client)
{ {
return _aggregater->addAggregateTopic(topic, client); return _aggregater->addAggregateTopic(topic, client);
} }
void AdapterManager::removeAggregateTopic(Topic* topic, Client* client) void AdapterManager::removeAggregateTopic(Topic* topic, Client* client)
{ {
//_aggregater->removeAggregateTopic(topic, client); //_aggregater->removeAggregateTopic(topic, client);
} }
void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client) void AdapterManager::removeAggregateTopicList(Topics* topics, Client* client)
{ {
} }
*/ */

View File

@@ -33,12 +33,12 @@ class ClientRecvTask;
class ClientSendTask; class ClientSendTask;
/*===================================== /*=====================================
Class AdapterManager Class AdapterManager
=====================================*/ =====================================*/
class AdapterManager class AdapterManager
{ {
public: public:
AdapterManager(Gateway* gw); AdapterManager(Gateway* gw);
~AdapterManager(void); ~AdapterManager(void);
void initialize(char* gwName, bool aggregater, bool fowarder, bool qosM1); void initialize(char* gwName, bool aggregater, bool fowarder, bool qosM1);
ForwarderList* getForwarderList(void); ForwarderList* getForwarderList(void);
@@ -49,18 +49,16 @@ public:
bool isAggregatedClient(Client* client); bool isAggregatedClient(Client* client);
Client* getClient(Client* client); Client* getClient(Client* client);
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId); 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); bool isAggregaterActive(void);
private: private:
Gateway* _gateway {nullptr}; Gateway* _gateway { nullptr };
ForwarderList* _forwarders {nullptr}; ForwarderList* _forwarders { nullptr };
QoSm1Proxy* _qosm1Proxy {nullptr}; QoSm1Proxy* _qosm1Proxy { nullptr };
Aggregater* _aggregater {nullptr}; Aggregater* _aggregater { nullptr };
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */

View File

@@ -21,7 +21,7 @@
=====================================*/ =====================================*/
ClientTopicElement::ClientTopicElement(Client* client) ClientTopicElement::ClientTopicElement(Client* client)
{ {
_client = client; _client = client;
} }
ClientTopicElement::~ClientTopicElement() ClientTopicElement::~ClientTopicElement()
@@ -31,12 +31,12 @@ ClientTopicElement::~ClientTopicElement()
Client* ClientTopicElement::getClient(void) Client* ClientTopicElement::getClient(void)
{ {
return _client; return _client;
} }
ClientTopicElement* ClientTopicElement::getNextClientElement(void) ClientTopicElement* ClientTopicElement::getNextClientElement(void)
{ {
return _next; return _next;
} }
/*===================================== /*=====================================
@@ -49,122 +49,122 @@ AggregateTopicElement::AggregateTopicElement(void)
AggregateTopicElement::AggregateTopicElement(Topic* topic, Client* client) AggregateTopicElement::AggregateTopicElement(Topic* topic, Client* client)
{ {
_topic = topic; _topic = topic;
ClientTopicElement* elm = new ClientTopicElement(client); ClientTopicElement* elm = new ClientTopicElement(client);
if ( elm != nullptr ) if (elm != nullptr)
{ {
_head = elm; _head = elm;
_tail = elm; _tail = elm;
} }
} }
AggregateTopicElement::~AggregateTopicElement(void) AggregateTopicElement::~AggregateTopicElement(void)
{ {
_mutex.lock(); _mutex.lock();
if ( _head != nullptr ) if (_head != nullptr)
{ {
ClientTopicElement* p = _tail; ClientTopicElement* p = _tail;
while ( p ) while (p)
{ {
ClientTopicElement* pPrev = p; ClientTopicElement* pPrev = p;
delete p; delete p;
p = pPrev->_prev; p = pPrev->_prev;
} }
_head = _tail = nullptr; _head = _tail = nullptr;
} }
_mutex.unlock(); _mutex.unlock();
} }
ClientTopicElement* AggregateTopicElement::add(Client* client) ClientTopicElement* AggregateTopicElement::add(Client* client)
{ {
ClientTopicElement* elm = new ClientTopicElement(client); ClientTopicElement* elm = new ClientTopicElement(client);
if ( elm == nullptr ) if (elm == nullptr)
{ {
return nullptr; return nullptr;
} }
_mutex.lock(); _mutex.lock();
if ( _head == nullptr ) if (_head == nullptr)
{ {
_head = elm; _head = elm;
_tail = elm; _tail = elm;
} }
else else
{ {
ClientTopicElement* p = find(client); ClientTopicElement* p = find(client);
if ( p == nullptr ) if (p == nullptr)
{ {
p = _tail; p = _tail;
_tail = elm; _tail = elm;
elm->_prev = p; elm->_prev = p;
p->_next = elm; p->_next = elm;
} }
else else
{ {
delete elm; delete elm;
elm = p; elm = p;
} }
} }
_mutex.unlock(); _mutex.unlock();
return elm; return elm;
} }
ClientTopicElement* AggregateTopicElement::find(Client* client) ClientTopicElement* AggregateTopicElement::find(Client* client)
{ {
ClientTopicElement* p = _head; ClientTopicElement* p = _head;
while ( p != nullptr ) while (p != nullptr)
{ {
if ( p->_client == client) if (p->_client == client)
{ {
break; break;
} }
p = p->_next; p = p->_next;
} }
return p; return p;
} }
ClientTopicElement* AggregateTopicElement::getFirstClientTopicElement(void) ClientTopicElement* AggregateTopicElement::getFirstClientTopicElement(void)
{ {
return _head; return _head;
} }
ClientTopicElement* AggregateTopicElement::getNextClientTopicElement(ClientTopicElement* elmClient) ClientTopicElement* AggregateTopicElement::getNextClientTopicElement(ClientTopicElement* elmClient)
{ {
return elmClient->_next; return elmClient->_next;
} }
void AggregateTopicElement::eraseClient(Client* client) void AggregateTopicElement::eraseClient(Client* client)
{ {
_mutex.lock(); _mutex.lock();
ClientTopicElement* p = find(client); 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; _head = p->_next;
if ( p->_next == nullptr ) // head & only one if (p->_next == nullptr) // head & only one
{ {
_tail = nullptr; _tail = nullptr;
} }
else else
{ {
p->_next->_prev = nullptr; // head & midle p->_next->_prev = nullptr; // head & midle
} }
} }
else if ( p->_next != nullptr ) // middle else if (p->_next != nullptr) // middle
{ {
p->_prev->_next = p->_next; p->_prev->_next = p->_next;
} }
else // tail else // tail
{ {
p->_prev->_next = nullptr; p->_prev->_next = nullptr;
_tail = p->_prev; _tail = p->_prev;
} }
delete p; delete p;
} }
_mutex.unlock(); _mutex.unlock();
} }
/*===================================== /*=====================================
@@ -183,138 +183,138 @@ AggregateTopicTable::~AggregateTopicTable()
AggregateTopicElement* AggregateTopicTable::add(Topic* topic, Client* client) AggregateTopicElement* AggregateTopicTable::add(Topic* topic, Client* client)
{ {
AggregateTopicElement* elm = nullptr; AggregateTopicElement* elm = nullptr;
_mutex.lock(); _mutex.lock();
elm = getAggregateTopicElement(topic); elm = getAggregateTopicElement(topic);
if ( elm != nullptr ) if (elm != nullptr)
{ {
if ( elm->find(client) == nullptr ) if (elm->find(client) == nullptr)
{ {
elm->add(client); elm->add(client);
} }
} }
else else
{ {
Topic* newTopic = topic->duplicate(); Topic* newTopic = topic->duplicate();
elm = new AggregateTopicElement(newTopic, client); elm = new AggregateTopicElement(newTopic, client);
if ( _head == nullptr ) if (_head == nullptr)
{ {
_head = elm; _head = elm;
_tail = elm; _tail = elm;
} }
else else
{ {
elm->_prev = _tail; elm->_prev = _tail;
_tail->_next = elm; _tail->_next = elm;
_tail = elm; _tail = elm;
} }
} }
_mutex.unlock(); _mutex.unlock();
return elm; return elm;
} }
void AggregateTopicTable::erase(Topic* topic, Client* client) void AggregateTopicTable::erase(Topic* topic, Client* client)
{ {
AggregateTopicElement* elm = nullptr; AggregateTopicElement* elm = nullptr;
_mutex.lock(); _mutex.lock();
elm = getAggregateTopicElement(topic); elm = getAggregateTopicElement(topic);
if ( elm != nullptr ) if (elm != nullptr)
{ {
elm->eraseClient(client); elm->eraseClient(client);
} }
if ( elm->_head == nullptr ) if (elm->_head == nullptr)
{ {
erase(elm); erase(elm);
} }
_mutex.unlock(); _mutex.unlock();
return; return;
} }
void AggregateTopicTable::erase(AggregateTopicElement* elmTopic) 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; _head = elmTopic->_next;
if ( elmTopic->_next == nullptr ) // head & only one if (elmTopic->_next == nullptr) // head & only one
{ {
_tail = nullptr; _tail = nullptr;
} }
else else
{ {
elmTopic->_next->_prev = nullptr; // head & midle elmTopic->_next->_prev = nullptr; // head & midle
} }
} }
else if ( elmTopic->_next != nullptr ) // middle else if (elmTopic->_next != nullptr) // middle
{ {
elmTopic->_prev->_next = elmTopic->_next; elmTopic->_prev->_next = elmTopic->_next;
} }
else // tail else // tail
{ {
elmTopic->_prev->_next = nullptr; elmTopic->_prev->_next = nullptr;
_tail = elmTopic->_prev; _tail = elmTopic->_prev;
} }
delete elmTopic; delete elmTopic;
} }
} }
AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topic) AggregateTopicElement* AggregateTopicTable::getAggregateTopicElement(Topic* topic)
{ {
AggregateTopicElement* elm = _head; AggregateTopicElement* elm = _head;
while( elm != nullptr ) while (elm != nullptr)
{ {
if ( elm->_topic->isMatch(topic->_topicName) ) if (elm->_topic->isMatch(topic->_topicName))
{ {
break; break;
} }
elm = elm->_next; elm = elm->_next;
} }
return elm; return elm;
} }
ClientTopicElement* AggregateTopicTable::getClientElement(Topic* topic) ClientTopicElement* AggregateTopicTable::getClientElement(Topic* topic)
{ {
AggregateTopicElement* elm = getAggregateTopicElement(topic); AggregateTopicElement* elm = getAggregateTopicElement(topic);
if ( elm != nullptr ) if (elm != nullptr)
{ {
return elm->_head; return elm->_head;
} }
else else
{ {
return nullptr; return nullptr;
} }
} }
void AggregateTopicTable::print(void) void AggregateTopicTable::print(void)
{ {
AggregateTopicElement* elm = _head; AggregateTopicElement* elm = _head;
printf("Beginning of AggregateTopicTable\n"); printf("Beginning of AggregateTopicTable\n");
while( elm != nullptr ) while (elm != nullptr)
{ {
printf("%s\n", elm->_topic->getTopicName()->c_str()); printf("%s\n", elm->_topic->getTopicName()->c_str());
ClientTopicElement* clElm = elm->getFirstClientTopicElement(); ClientTopicElement* clElm = elm->getFirstClientTopicElement();
Client* client = clElm->getClient(); Client* client = clElm->getClient();
while ( client != nullptr ) while (client != nullptr)
{ {
printf(" %s\n", client->getClientId()); printf(" %s\n", client->getClientId());
clElm = clElm->getNextClientElement(); clElm = clElm->getNextClientElement();
if ( clElm != nullptr ) if (clElm != nullptr)
{ {
client = clElm->getClient(); client = clElm->getClient();
} }
else else
{ {
client = nullptr; client = nullptr;
} }
} }
elm = elm->_next; elm = elm->_next;
} }
printf("End of AggregateTopicTable\n"); printf("End of AggregateTopicTable\n");
} }

View File

@@ -35,24 +35,24 @@ class Mutex;
class AggregateTopicTable class AggregateTopicTable
{ {
public: public:
AggregateTopicTable(); AggregateTopicTable();
~AggregateTopicTable(); ~AggregateTopicTable();
AggregateTopicElement* add(Topic* topic, Client* client); AggregateTopicElement* add(Topic* topic, Client* client);
AggregateTopicElement* getAggregateTopicElement(Topic* topic); AggregateTopicElement* getAggregateTopicElement(Topic* topic);
ClientTopicElement* getClientElement(Topic* topic); ClientTopicElement* getClientElement(Topic* topic);
void erase(Topic* topic, Client* client); void erase(Topic* topic, Client* client);
void clear(void); void clear(void);
void print(void); void print(void);
private: private:
void erase(AggregateTopicElement* elmTopic); void erase(AggregateTopicElement* elmTopic);
Mutex _mutex; Mutex _mutex;
AggregateTopicElement* _head {nullptr}; AggregateTopicElement* _head { nullptr };
AggregateTopicElement* _tail {nullptr}; AggregateTopicElement* _tail { nullptr };
int _cnt {0}; int _cnt { 0 };
int _maxSize {MAX_MESSAGEID_TABLE_SIZE}; int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
}; };
/*===================================== /*=====================================
@@ -68,17 +68,18 @@ public:
ClientTopicElement* add(Client* client); ClientTopicElement* add(Client* client);
ClientTopicElement* getFirstClientTopicElement(void); ClientTopicElement* getFirstClientTopicElement(void);
ClientTopicElement* getNextClientTopicElement(ClientTopicElement* elmClient); ClientTopicElement* getNextClientTopicElement(
ClientTopicElement* elmClient);
void eraseClient(Client* client); void eraseClient(Client* client);
ClientTopicElement* find(Client* client); ClientTopicElement* find(Client* client);
private: private:
Mutex _mutex; Mutex _mutex;
Topic* _topic {nullptr}; Topic* _topic { nullptr };
AggregateTopicElement* _next {nullptr}; AggregateTopicElement* _next { nullptr };
AggregateTopicElement* _prev {nullptr}; AggregateTopicElement* _prev { nullptr };
ClientTopicElement* _head {nullptr}; ClientTopicElement* _head { nullptr };
ClientTopicElement* _tail {nullptr}; ClientTopicElement* _tail { nullptr };
}; };
/*===================================== /*=====================================
@@ -96,13 +97,11 @@ public:
Client* getClient(void); Client* getClient(void);
private: private:
Client* _client {nullptr}; Client* _client { nullptr };
ClientTopicElement* _next {nullptr}; ClientTopicElement* _next { nullptr };
ClientTopicElement* _prev {nullptr}; ClientTopicElement* _prev { nullptr };
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */

View File

@@ -26,9 +26,10 @@
using namespace MQTTSNGW; using namespace MQTTSNGW;
Aggregater::Aggregater(Gateway* gw) : Adapter(gw) Aggregater::Aggregater(Gateway* gw) :
Adapter(gw)
{ {
_gateway = gw; _gateway = gw;
} }
Aggregater::~Aggregater(void) Aggregater::~Aggregater(void)
@@ -38,10 +39,10 @@ Aggregater::~Aggregater(void)
void Aggregater::initialize(char* gwName) void Aggregater::initialize(char* gwName)
{ {
/* Create Aggregater Client */ /* Create Aggregater Client */
string name = string(gwName) + string("_Aggregater"); string name = string(gwName) + string("_Aggregater");
setup(name.c_str(), Atype_Aggregater); setup(name.c_str(), Atype_Aggregater);
_isActive = true; _isActive = true;
//testMessageIdTable(); //testMessageIdTable();
@@ -49,100 +50,98 @@ void Aggregater::initialize(char* gwName)
bool Aggregater::isActive(void) bool Aggregater::isActive(void)
{ {
return _isActive; return _isActive;
} }
uint16_t Aggregater::msgId(void) uint16_t Aggregater::msgId(void)
{ {
// Only SecureClient generates msgId to avoid duplication of msgId. Client does not generate it. // Only SecureClient generates msgId to avoid duplication of msgId. Client does not generate it.
return Adapter::getSecureClient()->getNextPacketId(); return Adapter::getSecureClient()->getNextPacketId();
} }
Client* Aggregater::convertClient(uint16_t msgId, uint16_t* clientMsgId) Client* Aggregater::convertClient(uint16_t msgId, uint16_t* clientMsgId)
{ {
return _msgIdTable.getClientMsgId(msgId, clientMsgId); return _msgIdTable.getClientMsgId(msgId, clientMsgId);
} }
uint16_t Aggregater::addMessageIdTable(Client* client, uint16_t msgId) uint16_t Aggregater::addMessageIdTable(Client* client, uint16_t msgId)
{ {
/* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/ /* set Non secure client`s nextMsgId. otherwise Id is duplicated.*/
MessageIdElement* elm = _msgIdTable.add(this, client, msgId); MessageIdElement* elm = _msgIdTable.add(this, client, msgId);
if ( elm == nullptr ) if (elm == nullptr)
{ {
return 0; return 0;
} }
else else
{ {
return elm->_msgId; return elm->_msgId;
} }
} }
uint16_t Aggregater::getMsgId(Client* client, uint16_t clientMsgId) uint16_t Aggregater::getMsgId(Client* client, uint16_t clientMsgId)
{ {
return _msgIdTable.getMsgId(client, clientMsgId); return _msgIdTable.getMsgId(client, clientMsgId);
} }
AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* client) AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* client)
{ {
return _topicTable.add(topic, client); return _topicTable.add(topic, client);
} }
void Aggregater::removeAggregateTopic(Topic* topic, Client* client) void Aggregater::removeAggregateTopic(Topic* topic, Client* client)
{ {
_topicTable.erase(topic, client); _topicTable.erase(topic, client);
} }
AggregateTopicElement* Aggregater::findTopic(Topic* topic) AggregateTopicElement* Aggregater::findTopic(Topic* topic)
{ {
return _topicTable.getAggregateTopicElement(topic); return _topicTable.getAggregateTopicElement(topic);
} }
ClientTopicElement* Aggregater::getClientElement(Topic* topic) ClientTopicElement* Aggregater::getClientElement(Topic* topic)
{ {
AggregateTopicElement* elm = findTopic(topic); AggregateTopicElement* elm = findTopic(topic);
if ( elm != nullptr ) if (elm != nullptr)
{ {
return elm->getFirstClientTopicElement(); return elm->getFirstClientTopicElement();
} }
else else
{ {
return nullptr; return nullptr;
} }
} }
void Aggregater::printAggregateTopicTable(void) void Aggregater::printAggregateTopicTable(void)
{ {
_topicTable.print(); _topicTable.print();
} }
bool Aggregater::testMessageIdTable(void) bool Aggregater::testMessageIdTable(void)
{ {
Client* client = new Client(); Client* client = new Client();
uint16_t msgId = 0; uint16_t msgId = 0;
printf("msgId=%d\n", addMessageIdTable(client,1)); printf("msgId=%d\n", addMessageIdTable(client, 1));
printf("msgId=%d\n", addMessageIdTable(client,2)); printf("msgId=%d\n", addMessageIdTable(client, 2));
printf("msgId=%d\n", addMessageIdTable(client,3)); printf("msgId=%d\n", addMessageIdTable(client, 3));
printf("msgId=%d\n", addMessageIdTable(client,1)); printf("msgId=%d\n", addMessageIdTable(client, 1));
printf("msgId=%d\n", addMessageIdTable(client,2)); printf("msgId=%d\n", addMessageIdTable(client, 2));
printf("msgId=%d\n", addMessageIdTable(client,3)); 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, 4));
printf("msgId=%d\n", addMessageIdTable(client,4)); printf("msgId=%d\n", addMessageIdTable(client, 4));
convertClient(1,&msgId); convertClient(1, &msgId);
printf("msgId=%d\n",msgId); printf("msgId=%d\n", msgId);
convertClient(2,&msgId); convertClient(2, &msgId);
printf("msgId=%d\n",msgId); printf("msgId=%d\n", msgId);
convertClient(5,&msgId); convertClient(5, &msgId);
printf("msgId=%d\n",msgId); printf("msgId=%d\n", msgId);
convertClient(4,&msgId); convertClient(4, &msgId);
printf("msgId=%d\n",msgId); printf("msgId=%d\n", msgId);
convertClient(3,&msgId); convertClient(3, &msgId);
printf("msgId=%d\n",msgId); printf("msgId=%d\n", msgId);
return true; return true;
} }

View File

@@ -32,11 +32,11 @@ class AggregateTopicTable;
class Topics; class Topics;
/*===================================== /*=====================================
Class Aggregater Class Aggregater
=====================================*/ =====================================*/
class Aggregater : public Adapter class Aggregater: public Adapter
{ {
friend class MessageIdTable; friend class MessageIdTable;
public: public:
Aggregater(Gateway* gw); Aggregater(Gateway* gw);
~Aggregater(void); ~Aggregater(void);
@@ -44,39 +44,35 @@ public:
void initialize(char* gwName); void initialize(char* gwName);
const char* getClientId(SensorNetAddress* addr); const char* getClientId(SensorNetAddress* addr);
Client* getClient(SensorNetAddress* addr); Client* getClient(SensorNetAddress* addr);
Client* convertClient(uint16_t msgId, uint16_t* clientMsgId); Client* convertClient(uint16_t msgId, uint16_t* clientMsgId);
uint16_t addMessageIdTable(Client* client, uint16_t msgId); uint16_t addMessageIdTable(Client* client, uint16_t msgId);
uint16_t getMsgId(Client* client, uint16_t clientMsgId); uint16_t getMsgId(Client* client, uint16_t clientMsgId);
ClientTopicElement* getClientElement(Topic* topic); ClientTopicElement* getClientElement(Topic* topic);
ClientTopicElement* getNextClientElement(ClientTopicElement* clientElement); ClientTopicElement* getNextClientElement(ClientTopicElement* clientElement);
Client* getClient(ClientTopicElement* clientElement); Client* getClient(ClientTopicElement* clientElement);
AggregateTopicElement* findTopic(Topic* topic); AggregateTopicElement* findTopic(Topic* topic);
AggregateTopicElement* addAggregateTopic(Topic* topic, Client* client); AggregateTopicElement* addAggregateTopic(Topic* topic, Client* client);
void removeAggregateTopic(Topic* topic, Client* client); void removeAggregateTopic(Topic* topic, Client* client);
void removeAggregateAllTopic(Client* client); void removeAggregateAllTopic(Client* client);
bool isActive(void); bool isActive(void);
void printAggregateTopicTable(void); void printAggregateTopicTable(void);
bool testMessageIdTable(void); bool testMessageIdTable(void);
private: private:
uint16_t msgId(void); uint16_t msgId(void);
Gateway* _gateway {nullptr}; Gateway* _gateway { nullptr };
MessageIdTable _msgIdTable; MessageIdTable _msgIdTable;
AggregateTopicTable _topicTable; AggregateTopicTable _topicTable;
bool _isActive {false}; bool _isActive { false };
bool _isSecure {false}; bool _isSecure { false };
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */

View File

@@ -17,6 +17,7 @@
#include "MQTTSNGWBrokerRecvTask.h" #include "MQTTSNGWBrokerRecvTask.h"
#include "MQTTSNGWClient.h" #include "MQTTSNGWClient.h"
#include "MQTTSNGWClientList.h" #include "MQTTSNGWClientList.h"
#include "MQTTSNGateway.h"
#include <unistd.h> #include <unistd.h>
using namespace std; using namespace std;
@@ -29,14 +30,14 @@ char* currentDateTime(void);
=====================================*/ =====================================*/
BrokerRecvTask::BrokerRecvTask(Gateway* gateway) BrokerRecvTask::BrokerRecvTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*)this); _gateway->attach((Thread*) this);
_light = nullptr; _light = nullptr;
setTaskName("BrokerRecvTask");
} }
BrokerRecvTask::~BrokerRecvTask() BrokerRecvTask::~BrokerRecvTask()
{ {
} }
/** /**
@@ -44,7 +45,7 @@ BrokerRecvTask::~BrokerRecvTask()
*/ */
void BrokerRecvTask::initialize(int argc, char** argv) void BrokerRecvTask::initialize(int argc, char** argv)
{ {
_light = _gateway->getLightIndicator(); _light = _gateway->getLightIndicator();
} }
/** /**
@@ -52,133 +53,130 @@ void BrokerRecvTask::initialize(int argc, char** argv)
*/ */
void BrokerRecvTask::run(void) void BrokerRecvTask::run(void)
{ {
struct timeval timeout; struct timeval timeout;
MQTTGWPacket* packet = nullptr; MQTTGWPacket* packet = nullptr;
int rc; int rc;
Event* ev = nullptr; Event* ev = nullptr;
fd_set rset; fd_set rset;
fd_set wset; fd_set wset;
while (true) while (true)
{ {
_light->blueLight(false); _light->blueLight(false);
if (CHK_SIGINT) if (CHK_SIGINT)
{ {
WRITELOG("\n%s BrokerRecvTask stopped.", currentDateTime()); WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
return; return;
} }
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 500000; // 500 msec timeout.tv_usec = 500000; // 500 msec
FD_ZERO(&rset); FD_ZERO(&rset);
FD_ZERO(&wset); FD_ZERO(&wset);
int maxSock = 0; int maxSock = 0;
int sockfd = 0; int sockfd = 0;
/* Prepare sockets list to read */ /* Prepare sockets list to read */
Client* client = _gateway->getClientList()->getClient(0); Client* client = _gateway->getClientList()->getClient(0);
while ( client ) while (client)
{ {
if (client->getNetwork()->isValid()) if (client->getNetwork()->isValid())
{ {
sockfd = client->getNetwork()->getSock(); sockfd = client->getNetwork()->getSock();
FD_SET(sockfd, &rset); FD_SET(sockfd, &rset);
FD_SET(sockfd, &wset); FD_SET(sockfd, &wset);
if (sockfd > maxSock) if (sockfd > maxSock)
{ {
maxSock = sockfd; maxSock = sockfd;
} }
} }
client = client->getNextClient(); client = client->getNextClient();
} }
if (maxSock == 0) if (maxSock == 0)
{ {
usleep(500 * 1000); usleep(500 * 1000);
} }
else else
{ {
/* Check sockets is ready to read */ /* Check sockets is ready to read */
int activity = select(maxSock + 1, &rset, 0, 0, &timeout); int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
if (activity > 0)
{
client = _gateway->getClientList()->getClient(0);
while ( client ) if (activity > 0)
{ {
_light->blueLight(false); client = _gateway->getClientList()->getClient(0);
if (client->getNetwork()->isValid())
{
int sockfd = client->getNetwork()->getSock();
if (FD_ISSET(sockfd, &rset))
{
packet = new MQTTGWPacket();
rc = 0;
/* read sockets */
_light->blueLight(true);
rc = packet->recv(client->getNetwork());
if ( rc > 0 )
{
if ( log(client, packet) == -1 )
{
delete packet;
goto nextClient;
}
/* post a BrokerRecvEvent */ while (client)
ev = new Event(); {
ev->setBrokerRecvEvent(client, packet); _light->blueLight(false);
_gateway->getPacketEventQue()->post(ev); if (client->getNetwork()->isValid())
} {
else int sockfd = client->getNetwork()->getSock();
{ if (FD_ISSET(sockfd, &rset))
if ( rc == 0 ) // Disconnected {
{ packet = new MQTTGWPacket();
client->getNetwork()->close(); rc = 0;
delete packet; /* read sockets */
_light->blueLight(true);
rc = packet->recv(client->getNetwork());
if (rc > 0)
{
if (log(client, packet) == -1)
{
delete packet;
goto nextClient;
}
/* delete client when the client is not authorized & session is clean */ /* post a BrokerRecvEvent */
_gateway->getClientList()->erase(client); ev = new Event();
ev->setBrokerRecvEvent(client, packet);
_gateway->getPacketEventQue()->post(ev);
}
else
{
if (rc == 0) // Disconnected
{
WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
ERRMSG_HEADER, client->getClientId(),
ERRMSG_FOOTER);
client->getNetwork()->close();
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);
}
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);
}
else if (rc == -3)
{
WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
ERRMSG_HEADER, client->getClientId(),
ERRMSG_FOOTER);
}
if ( client ) delete packet;
{
client = client->getNextClient();
}
continue;
}
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);
}
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);
}
else if ( rc == -3 )
{
WRITELOG("%s BrokerRecvTask can't get 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() )) client->getNetwork()->close();
{ client->disconnected();
/* disconnect the client */ }
packet = new MQTTGWPacket(); }
packet->setHeader(DISCONNECT); }
ev = new Event(); }
ev->setBrokerRecvEvent(client, packet); nextClient: client = client->getNextClient();
_gateway->getPacketEventQue()->post(ev); }
} }
} }
} }
}
nextClient:
client = client->getNextClient();
}
}
}
}
} }
/** /**
@@ -186,35 +184,38 @@ void BrokerRecvTask::run(void)
*/ */
int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet) 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]; char msgId[6];
int rc = 0; int rc = 0;
switch (packet->getType()) switch (packet->getType())
{ {
case CONNACK: case CONNACK:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf)); WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
break; break;
case PUBLISH: 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,
break; client->getClientId(), packet->print(pbuf));
case PUBACK: break;
case PUBREC: case PUBACK:
case PUBREL: case PUBREC:
case PUBCOMP: case PUBREL:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf)); case PUBCOMP:
break; WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
case SUBACK: client->getClientId(), packet->print(pbuf));
case UNSUBACK: break;
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf)); case SUBACK:
break; case UNSUBACK:
case PINGRESP: WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf)); client->getClientId(), packet->print(pbuf));
break; break;
default: case PINGRESP:
WRITELOG("Type=%x\n", packet->getType()); WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
rc = -1; break;
break; default:
} WRITELOG("Type=%x\n", packet->getType());
return rc; rc = -1;
break;
}
return rc;
} }

View File

@@ -28,21 +28,20 @@ namespace MQTTSNGW
class BrokerRecvTask: public Thread class BrokerRecvTask: public Thread
{ {
MAGIC_WORD_FOR_THREAD; MAGIC_WORD_FOR_THREAD;
;
public: public:
BrokerRecvTask(Gateway* gateway); BrokerRecvTask(Gateway* gateway);
~BrokerRecvTask(); ~BrokerRecvTask();
void initialize(int argc, char** argv); void initialize(int argc, char** argv);
void run(void); void run(void);
private: private:
int log(Client*, MQTTGWPacket*); int log(Client*, MQTTGWPacket*);
Gateway* _gateway; Gateway* _gateway;
LightIndicator* _light; LightIndicator* _light;
}; };
} }
#endif /* MQTTSNGWBROKERRECVTASK_H_ */ #endif /* MQTTSNGWBROKERRECVTASK_H_ */

View File

@@ -33,15 +33,15 @@ char* currentDateTime();
=====================================*/ =====================================*/
BrokerSendTask::BrokerSendTask(Gateway* gateway) BrokerSendTask::BrokerSendTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*)this); _gateway->attach((Thread*) this);
_gwparams = nullptr; _gwparams = nullptr;
_light = nullptr; _light = nullptr;
setTaskName("BrokerSendTask");
} }
BrokerSendTask::~BrokerSendTask() BrokerSendTask::~BrokerSendTask()
{ {
// WRITELOG("BrokerSendTask is deleted normally.\r\n");
} }
/** /**
@@ -49,8 +49,8 @@ BrokerSendTask::~BrokerSendTask()
*/ */
void BrokerSendTask::initialize(int argc, char** argv) void BrokerSendTask::initialize(int argc, char** argv)
{ {
_gwparams = _gateway->getGWParams(); _gwparams = _gateway->getGWParams();
_light = _gateway->getLightIndicator(); _light = _gateway->getLightIndicator();
} }
/** /**
@@ -58,132 +58,137 @@ void BrokerSendTask::initialize(int argc, char** argv)
*/ */
void BrokerSendTask::run() void BrokerSendTask::run()
{ {
Event* ev = nullptr; Event* ev = nullptr;
MQTTGWPacket* packet = nullptr; MQTTGWPacket* packet = nullptr;
Client* client = nullptr; Client* client = nullptr;
AdapterManager* adpMgr = _gateway->getAdapterManager(); AdapterManager* adpMgr = _gateway->getAdapterManager();
int rc = 0; int rc = 0;
while (true) while (true)
{ {
ev = _gateway->getBrokerSendQue()->wait(); 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; delete ev;
return; return;
} }
if ( ev->getEventType() == EtBrokerSend) if (ev->getEventType() == EtBrokerSend)
{ {
client = ev->getClient(); client = ev->getClient();
packet = ev->getMQTTGWPacket(); packet = ev->getMQTTGWPacket();
/* Check Client is managed by Adapters */ /* Check Client is managed by Adapters */
client = adpMgr->getClient(client); client = adpMgr->getClient(client);
if ( packet->getType() == CONNECT && client->getNetwork()->isValid() ) if (packet->getType() == CONNECT && client->getNetwork()->isValid())
{ {
client->getNetwork()->close(); client->getNetwork()->close();
} }
if ( !client->getNetwork()->isValid() ) if (!client->getNetwork()->isValid())
{ {
/* connect to the broker and send a packet */ /* connect to the broker and send a packet */
if (client->isSecureNetwork()) if (client->isSecureNetwork())
{ {
rc = client->getNetwork()->connect((const char*)_gwparams->brokerName, (const char*)_gwparams->portSecure, (const char*)_gwparams->rootCApath, rc = client->getNetwork()->connect((const char*) _gwparams->brokerName, (const char*) _gwparams->portSecure,
(const char*)_gwparams->rootCAfile, (const char*)_gwparams->certKey, (const char*)_gwparams->privateKey); (const char*) _gwparams->rootCApath, (const char*) _gwparams->rootCAfile,
} (const char*) _gwparams->certKey, (const char*) _gwparams->privateKey);
else }
{ 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 */ /* disconnect the broker and the client */
WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n", WRITELOG("%s BrokerSendTask: %s can't connect to the broker. errno=%d %s %s\n",
ERRMSG_HEADER, client->getClientId(), errno, strerror(errno), ERRMSG_FOOTER); ERRMSG_HEADER, client->getClientId(), errno, strerror(errno), ERRMSG_FOOTER);
delete ev; delete ev;
client->getNetwork()->close(); client->getNetwork()->close();
continue; continue;
} }
} }
/* send a packet */ /* send a packet */
_light->blueLight(true); _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(); client->connectSended();
} }
else if ( packet->getType() == DISCONNECT ) else if (packet->getType() == DISCONNECT)
{ {
client->getNetwork()->close(); client->getNetwork()->close();
client->disconnected(); client->disconnected();
} }
log(client, packet); log(client, packet);
} }
else else
{ {
WRITELOG("%s BrokerSendTask: %s can't send a packet to the broker. errno=%d %s %s\n", 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); ERRMSG_HEADER, client->getClientId(), rc == -1 ? errno : 0, strerror(errno), ERRMSG_FOOTER);
if ( errno != EBADF ) if ( errno != EBADF)
{ {
client->getNetwork()->close(); client->getNetwork()->close();
} }
/* Disconnect the client */ /* Disconnect the client */
packet = new MQTTGWPacket(); packet = new MQTTGWPacket();
packet->setHeader(DISCONNECT); packet->setHeader(DISCONNECT);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerRecvEvent(client, packet); ev1->setBrokerRecvEvent(client, packet);
_gateway->getPacketEventQue()->post(ev1); _gateway->getPacketEventQue()->post(ev1);
} }
_light->blueLight(false); _light->blueLight(false);
} }
delete ev; delete ev;
} }
} }
/** /**
* write message content into stdout or Ringbuffer * write message content into stdout or Ringbuffer
*/ */
void BrokerSendTask::log(Client* client, MQTTGWPacket* packet) 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]; char msgId[6];
switch (packet->getType()) switch (packet->getType())
{ {
case CONNECT: case CONNECT:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf)); WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
break; RIGHTARROWB, client->getClientId(), packet->print(pbuf));
case PUBLISH: break;
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf)); case PUBLISH:
break; WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
case SUBSCRIBE: client->getClientId(), packet->print(pbuf));
case UNSUBSCRIBE: break;
case PUBACK: case SUBSCRIBE:
case PUBREC: case UNSUBSCRIBE:
case PUBREL: case PUBACK:
case PUBCOMP: case PUBREC:
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf)); case PUBREL:
break; case PUBCOMP:
case PINGREQ: WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf)); client->getClientId(), packet->print(pbuf));
break; break;
case DISCONNECT: case PINGREQ:
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf)); WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
break; RIGHTARROWB, client->getClientId(), packet->print(pbuf));
default: break;
break; case DISCONNECT:
} WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
break;
default:
break;
}
} }

View File

@@ -25,22 +25,22 @@ namespace MQTTSNGW
class Adapter; class Adapter;
/*===================================== /*=====================================
Class BrokerSendTask Class BrokerSendTask
=====================================*/ =====================================*/
class BrokerSendTask : public Thread class BrokerSendTask: public Thread
{ {
MAGIC_WORD_FOR_THREAD; MAGIC_WORD_FOR_THREAD;
friend AdapterManager; friend AdapterManager;
public: public:
BrokerSendTask(Gateway* gateway); BrokerSendTask(Gateway* gateway);
~BrokerSendTask(); ~BrokerSendTask();
void initialize(int argc, char** argv); void initialize(int argc, char** argv);
void run(); void run();
private: private:
void log(Client*, MQTTGWPacket*); void log(Client*, MQTTGWPacket*);
Gateway* _gateway; Gateway* _gateway;
GatewayParams* _gwparams; GatewayParams* _gwparams;
LightIndicator* _light; LightIndicator* _light;
}; };
} }

View File

@@ -28,104 +28,104 @@
using namespace MQTTSNGW; using namespace MQTTSNGW;
char* currentDateTime(void); char* currentDateTime(void);
/*===================================== /*=====================================
Class Client 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) Client::Client(bool secure)
{ {
_packetId = 0; _packetId = 0;
_snMsgId = 0; _snMsgId = 0;
_status = Cstat_Disconnected; _status = Cstat_Free;
_keepAliveMsec = 0; _keepAliveMsec = 0;
_topics = new Topics(); _topics = new Topics();
_clientId = nullptr; _clientId = nullptr;
_willTopic = nullptr; _willTopic = nullptr;
_willMsg = nullptr; _willMsg = nullptr;
_connectData = MQTTPacket_Connect_Initializer; _connectData = MQTTPacket_Connect_Initializer;
_network = new Network(secure); _network = new Network(secure);
_secureNetwork = secure; _secureNetwork = secure;
_sensorNetype = true; _sensorNetype = true;
_connAck = nullptr; _connAck = nullptr;
_waitWillMsgFlg = false; _waitWillMsgFlg = false;
_sessionStatus = false; _sessionStatus = false;
_prevClient = nullptr; _prevClient = nullptr;
_nextClient = nullptr; _nextClient = nullptr;
_clientSleepPacketQue.setMaxSize(MAX_SAVED_PUBLISH); _clientSleepPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
_proxyPacketQue.setMaxSize(MAX_SAVED_PUBLISH); _proxyPacketQue.setMaxSize(MAX_SAVED_PUBLISH);
_hasPredefTopic = false; _hasPredefTopic = false;
_holdPingRequest = false; _holdPingRequest = false;
_forwarder = nullptr; _forwarder = nullptr;
_clientType = Ctype_Regular; _clientType = Ctype_Normal;
} }
Client::~Client() Client::~Client()
{ {
if ( _topics ) if (_topics)
{ {
delete _topics; delete _topics;
} }
if ( _clientId ) if (_clientId)
{ {
free(_clientId); free(_clientId);
} }
if ( _willTopic ) if (_willTopic)
{ {
free(_willTopic); free(_willTopic);
} }
if ( _willMsg ) if (_willMsg)
{ {
free(_willMsg); free(_willMsg);
} }
if (_connAck) if (_connAck)
{ {
delete _connAck; delete _connAck;
} }
if (_network) if (_network)
{ {
delete _network; delete _network;
} }
} }
TopicIdMapElement* Client::getWaitedPubTopicId(uint16_t msgId) TopicIdMapElement* Client::getWaitedPubTopicId(uint16_t msgId)
{ {
return _waitedPubTopicIdMap.getElement(msgId); return _waitedPubTopicIdMap.getElement(msgId);
} }
TopicIdMapElement* Client::getWaitedSubTopicId(uint16_t msgId) TopicIdMapElement* Client::getWaitedSubTopicId(uint16_t msgId)
{ {
return _waitedSubTopicIdMap.getElement(msgId); return _waitedSubTopicIdMap.getElement(msgId);
} }
MQTTGWPacket* Client::getClientSleepPacket() MQTTGWPacket* Client::getClientSleepPacket()
{ {
return _clientSleepPacketQue.getPacket(); return _clientSleepPacketQue.getPacket();
} }
void Client::deleteFirstClientSleepPacket() void Client::deleteFirstClientSleepPacket()
{ {
_clientSleepPacketQue.pop(); _clientSleepPacketQue.pop();
} }
int Client::setClientSleepPacket(MQTTGWPacket* packet) int Client::setClientSleepPacket(MQTTGWPacket* packet)
{ {
int rc = _clientSleepPacketQue.post(packet); int rc = _clientSleepPacketQue.post(packet);
if ( rc ) if (rc)
{ {
WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId); WRITELOG("%s %s is sleeping. the packet was saved.\n", currentDateTime(), _clientId);
} }
else else
{ {
WRITELOG("%s %s is sleeping but discard the packet.\n", currentDateTime(), _clientId); WRITELOG("%s %s is sleeping but discard the packet.\n", currentDateTime(), _clientId);
} }
return rc; return rc;
} }
MQTTSNPacket* Client::getProxyPacket(void) MQTTSNPacket* Client::getProxyPacket(void)
@@ -141,7 +141,7 @@ void Client::deleteFirstProxyPacket()
int Client::setProxyPacket(MQTTSNPacket* packet) int Client::setProxyPacket(MQTTSNPacket* packet)
{ {
int rc = _proxyPacketQue.post(packet); int rc = _proxyPacketQue.post(packet);
if ( rc ) if (rc)
{ {
WRITELOG("%s %s is Disconnected. the packet was saved.\n", currentDateTime(), _clientId); WRITELOG("%s %s is Disconnected. the packet was saved.\n", currentDateTime(), _clientId);
} }
@@ -154,51 +154,52 @@ int Client::setProxyPacket(MQTTSNPacket* packet)
Connect* Client::getConnectData(void) Connect* Client::getConnectData(void)
{ {
return &_connectData; return &_connectData;
} }
void Client::eraseWaitedPubTopicId(uint16_t msgId) void Client::eraseWaitedPubTopicId(uint16_t msgId)
{ {
_waitedPubTopicIdMap.erase(msgId); _waitedPubTopicIdMap.erase(msgId);
} }
void Client::eraseWaitedSubTopicId(uint16_t msgId) void Client::eraseWaitedSubTopicId(uint16_t msgId)
{ {
_waitedSubTopicIdMap.erase(msgId); _waitedSubTopicIdMap.erase(msgId);
} }
void Client::clearWaitedPubTopicId(void) void Client::clearWaitedPubTopicId(void)
{ {
_waitedPubTopicIdMap.clear(); _waitedPubTopicIdMap.clear();
} }
void Client::clearWaitedSubTopicId(void) void Client::clearWaitedSubTopicId(void)
{ {
_waitedSubTopicIdMap.clear(); _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) bool Client::checkTimeover(void)
{ {
return (_status == Cstat_Active && _keepAliveTimer.isTimeup()); return (_status == Cstat_Active && _keepAliveTimer.isTimeup());
} }
void Client::setKeepAlive(MQTTSNPacket* packet) void Client::setKeepAlive(MQTTSNPacket* packet)
{ {
MQTTSNPacket_connectData param; MQTTSNPacket_connectData param;
if (packet->getCONNECT(&param)) if (packet->getCONNECT(&param))
{ {
_keepAliveMsec = param.duration * 1000UL; _keepAliveMsec = param.duration * 1000UL;
_keepAliveTimer.start(_keepAliveMsec * 1.5); _keepAliveTimer.start(_keepAliveMsec * 1.5);
} }
} }
void Client::setForwarder(Forwarder* forwarder) void Client::setForwarder(Forwarder* forwarder)
@@ -214,102 +215,101 @@ Forwarder* Client::getForwarder(void)
void Client::setSessionStatus(bool status) void Client::setSessionStatus(bool status)
{ {
_sessionStatus = status; _sessionStatus = status;
} }
bool Client::erasable(void) bool Client::erasable(void)
{ {
return _sessionStatus && !_hasPredefTopic && _forwarder == nullptr; return _sessionStatus && !_hasPredefTopic && _forwarder == nullptr;
} }
void Client::updateStatus(MQTTSNPacket* packet) void Client::updateStatus(MQTTSNPacket* packet)
{ {
if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && packet->getType() == MQTTSN_CONNECT) if (((_status == Cstat_Disconnected) || (_status == Cstat_Lost)) && packet->getType() == MQTTSN_CONNECT)
{ {
setKeepAlive(packet); setKeepAlive(packet);
} }
else if (_status == Cstat_Active) else if (_status == Cstat_Active)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_PINGREQ: case MQTTSN_PINGREQ:
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
if ( _clientType != Ctype_Proxy ) if (_clientType != Ctype_Proxy)
{ {
_keepAliveTimer.start(_keepAliveMsec * 1.5); _keepAliveTimer.start(_keepAliveMsec * 1.5);
} }
break; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
uint16_t duration; uint16_t duration;
packet->getDISCONNECT(&duration); packet->getDISCONNECT(&duration);
if (duration) if (duration)
{ {
_status = Cstat_Asleep; _status = Cstat_Asleep;
} }
else else
{ {
disconnected(); disconnected();
} }
break; break;
default: default:
break; break;
} }
} }
else if (_status == Cstat_Awake || _status == Cstat_Asleep) else if (_status == Cstat_Awake || _status == Cstat_Asleep)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_CONNECT: case MQTTSN_CONNECT:
_status = Cstat_Active; _status = Cstat_Active;
break; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
disconnected(); disconnected();
break; break;
case MQTTSN_PINGREQ: case MQTTSN_PINGREQ:
_status = Cstat_Awake; _status = Cstat_Awake;
break; break;
case MQTTSN_PINGRESP: case MQTTSN_PINGRESP:
_status = Cstat_Asleep; _status = Cstat_Asleep;
break; break;
default: default:
break; break;
} }
} }DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
DEBUGLOG("Client Status = %s\n", theClientStatus[_status]);
} }
void Client::updateStatus(ClientStatus stat) void Client::updateStatus(ClientStatus stat)
{ {
_status = stat; _status = stat;
} }
void Client::connectSended() void Client::connectSended()
{ {
_status = Cstat_Connecting; _status = Cstat_Connecting;
} }
void Client::connackSended(int rc) void Client::connackSended(int rc)
{ {
if (rc == MQTTSN_RC_ACCEPTED) if (rc == MQTTSN_RC_ACCEPTED)
{ {
_status = Cstat_Active; _status = Cstat_Active;
} }
else else
{ {
disconnected(); disconnected();
} }
} }
void Client::disconnected(void) void Client::disconnected(void)
{ {
_status = Cstat_Disconnected; _status = Cstat_Disconnected;
_waitWillMsgFlg = false; _waitWillMsgFlg = false;
} }
void Client::tryConnect(void) void Client::tryConnect(void)
@@ -317,66 +317,71 @@ void Client::tryConnect(void)
_status = Cstat_TryConnecting; _status = Cstat_TryConnecting;
} }
bool Client::isCleanSession(void)
{
return _sessionStatus;
}
bool Client::isConnectSendable(void) bool Client::isConnectSendable(void)
{ {
if ( _status == Cstat_Lost || _status == Cstat_TryConnecting ) if (_status == Cstat_Lost || _status == Cstat_TryConnecting)
{ {
return false; return false;
} }
else else
{ {
return true; return true;
} }
} }
uint16_t Client::getNextPacketId(void) uint16_t Client::getNextPacketId(void)
{ {
_packetId++; _packetId++;
if ( _packetId == 0xffff ) if (_packetId == 0xffff)
{ {
_packetId = 1; _packetId = 1;
} }
return _packetId; return _packetId;
} }
uint8_t Client::getNextSnMsgId(void) uint8_t Client::getNextSnMsgId(void)
{ {
_snMsgId++; _snMsgId++;
if (_snMsgId == 0) if (_snMsgId == 0)
{ {
_snMsgId++; _snMsgId++;
} }
return _snMsgId; return _snMsgId;
} }
Topics* Client::getTopics(void) Topics* Client::getTopics(void)
{ {
return _topics; return _topics;
} }
Network* Client::getNetwork(void) Network* Client::getNetwork(void)
{ {
return _network; return _network;
} }
void Client::setClientAddress(SensorNetAddress* sensorNetAddr) void Client::setClientAddress(SensorNetAddress* sensorNetAddr)
{ {
_sensorNetAddr = *sensorNetAddr; _sensorNetAddr = *sensorNetAddr;
} }
SensorNetAddress* Client::getSensorNetAddress(void) SensorNetAddress* Client::getSensorNetAddress(void)
{ {
return &_sensorNetAddr; return &_sensorNetAddr;
} }
void Client::setSensorNetType(bool stable) void Client::setSensorNetType(bool stable)
{ {
_sensorNetype = stable; _sensorNetype = stable;
} }
void Client::setTopics(Topics* topics) void Client::setTopics(Topics* topics)
{ {
_topics = topics; _topics = topics;
} }
ClientStatus Client::getClientStatus(void) ClientStatus Client::getClientStatus(void)
@@ -386,32 +391,32 @@ ClientStatus Client::getClientStatus(void)
void Client::setWaitWillMsgFlg(bool flg) void Client::setWaitWillMsgFlg(bool flg)
{ {
_waitWillMsgFlg = flg; _waitWillMsgFlg = flg;
} }
bool Client::isWaitWillMsg(void) bool Client::isWaitWillMsg(void)
{ {
return _waitWillMsgFlg; return _waitWillMsgFlg;
} }
bool Client::isDisconnect(void) bool Client::isDisconnect(void)
{ {
return (_status == Cstat_Disconnected); return (_status == Cstat_Disconnected);
} }
bool Client::isActive(void) bool Client::isActive(void)
{ {
return (_status == Cstat_Active); return (_status == Cstat_Active);
} }
bool Client::isSleep(void) bool Client::isSleep(void)
{ {
return (_status == Cstat_Asleep); return (_status == Cstat_Asleep);
} }
bool Client::isAwake(void) bool Client::isAwake(void)
{ {
return (_status == Cstat_Awake); return (_status == Cstat_Awake);
} }
bool Client::isConnecting(void) bool Client::isConnecting(void)
@@ -421,94 +426,94 @@ bool Client::isConnecting(void)
bool Client::isSecureNetwork(void) bool Client::isSecureNetwork(void)
{ {
return _secureNetwork; return _secureNetwork;
} }
bool Client::isSensorNetStable(void) bool Client::isSensorNetStable(void)
{ {
return _sensorNetype; return _sensorNetype;
} }
WaitREGACKPacketList* Client::getWaitREGACKPacketList() WaitREGACKPacketList* Client::getWaitREGACKPacketList()
{ {
return &_waitREGACKList; return &_waitREGACKList;
} }
Client* Client::getNextClient(void) Client* Client::getNextClient(void)
{ {
return _nextClient; return _nextClient;
} }
void Client::setClientId(MQTTSNString id) void Client::setClientId(MQTTSNString id)
{ {
if ( _clientId ) if (_clientId)
{ {
free(_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)); memcpy(_clientId, id.cstring, strlen(id.cstring));
} }
else else
{ {
/* save clientId into (char*)_clientId NULL terminated */ /* save clientId into (char*)_clientId NULL terminated */
_clientId = (char*)calloc(MQTTSNstrlen(id) + 1, 1); _clientId = (char*) calloc(MQTTSNstrlen(id) + 1, 1);
unsigned char* ptr = (unsigned char*)_clientId; unsigned char* ptr = (unsigned char*) _clientId;
writeMQTTSNString((unsigned char**)&ptr, id); writeMQTTSNString((unsigned char**) &ptr, id);
} }
} }
void Client::setWillTopic(MQTTSNString willTopic) void Client::setWillTopic(MQTTSNString willTopic)
{ {
if ( _willTopic ) if (_willTopic)
{ {
free(_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 */ /* save willTopic into (char*)_willTopic with NULL termination */
unsigned char* ptr = (unsigned char*)_willTopic; unsigned char* ptr = (unsigned char*) _willTopic;
writeMQTTSNString((unsigned char**)&ptr, willTopic); writeMQTTSNString((unsigned char**) &ptr, willTopic);
} }
void Client::setWillMsg(MQTTSNString willMsg) void Client::setWillMsg(MQTTSNString willMsg)
{ {
if ( _willMsg) if (_willMsg)
{ {
free(_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 */ /* save willMsg into (char*)_willMsg with NULL termination */
unsigned char* ptr = (unsigned char*)_willMsg; unsigned char* ptr = (unsigned char*) _willMsg;
writeMQTTSNString((unsigned char**)&ptr, willMsg); writeMQTTSNString((unsigned char**) &ptr, willMsg);
} }
char* Client::getClientId(void) char* Client::getClientId(void)
{ {
return _clientId; return _clientId;
} }
char* Client::getWillTopic(void) char* Client::getWillTopic(void)
{ {
return _willTopic; return _willTopic;
} }
char* Client::getWillMsg(void) char* Client::getWillMsg(void)
{ {
return _willMsg; return _willMsg;
} }
const char* Client::getStatus(void) const char* Client::getStatus(void)
{ {
return theClientStatus[_status]; return theClientStatus[_status];
} }
bool Client::isQoSm1Proxy(void) bool Client::isQoSm1Proxy(void)
{ {
return _clientType == Ctype_Proxy; return _clientType == Ctype_Proxy;
} }
bool Client::isForwarded(void) bool Client::isForwarded(void)
@@ -528,23 +533,23 @@ bool Client::isAggregater(void)
void Client::setAdapterType(AdapterType type) void Client::setAdapterType(AdapterType type)
{ {
switch ( type ) switch (type)
{ {
case Atype_QoSm1Proxy: case Atype_QoSm1Proxy:
_clientType = Ctype_Proxy; _clientType = Ctype_Proxy;
break; break;
case Atype_Aggregater: case Atype_Aggregater:
_clientType = Ctype_Aggregater; _clientType = Ctype_Aggregater;
break; break;
default: default:
throw Exception("Client::setAdapterType(): Invalid Type."); throw EXCEPTION("Client::setAdapterType(): Invalid Type.", 0);
break; break;
} }
} }
bool Client::isAdapter(void) bool Client::isAdapter(void)
{ {
return _clientType == Ctype_Proxy || _clientType == Ctype_Aggregater; return _clientType == Ctype_Proxy || _clientType == Ctype_Aggregater;
} }
bool Client::isQoSm1(void) bool Client::isQoSm1(void)
@@ -554,12 +559,12 @@ bool Client::isQoSm1(void)
void Client::setQoSm1(void) void Client::setQoSm1(void)
{ {
_clientType = Ctype_QoS_1; _clientType = Ctype_QoS_1;
} }
void Client::setAggregated(void) void Client::setAggregated(void)
{ {
_clientType = Ctype_Aggregated; _clientType = Ctype_Aggregated;
} }
void Client::holdPingRequest(void) void Client::holdPingRequest(void)
@@ -577,22 +582,20 @@ bool Client::isHoldPingReqest(void)
return _holdPingRequest; return _holdPingRequest;
} }
/*===================================== /*=====================================
Class WaitREGACKPacket Class WaitREGACKPacket
=====================================*/ =====================================*/
waitREGACKPacket::waitREGACKPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId) waitREGACKPacket::waitREGACKPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId)
{ {
_packet = packet; _packet = packet;
_msgId = REGACKMsgId; _msgId = REGACKMsgId;
_next = nullptr; _next = nullptr;
_prev = nullptr; _prev = nullptr;
} }
waitREGACKPacket::~waitREGACKPacket() waitREGACKPacket::~waitREGACKPacket()
{ {
delete _packet; delete _packet;
} }
/*===================================== /*=====================================
@@ -601,89 +604,89 @@ waitREGACKPacket::~waitREGACKPacket()
WaitREGACKPacketList::WaitREGACKPacketList() WaitREGACKPacketList::WaitREGACKPacketList()
{ {
_first = nullptr; _first = nullptr;
_end = nullptr; _end = nullptr;
_cnt = 0; _cnt = 0;
} }
WaitREGACKPacketList::~WaitREGACKPacketList() WaitREGACKPacketList::~WaitREGACKPacketList()
{ {
waitREGACKPacket* p = _first; waitREGACKPacket* p = _first;
while (p) while (p)
{ {
waitREGACKPacket* q = p->_next; waitREGACKPacket* q = p->_next;
delete p; delete p;
p = q; p = q;
} }
} }
int WaitREGACKPacketList::setPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId) int WaitREGACKPacketList::setPacket(MQTTSNPacket* packet, uint16_t REGACKMsgId)
{ {
waitREGACKPacket* elm = new waitREGACKPacket(packet, REGACKMsgId); waitREGACKPacket* elm = new waitREGACKPacket(packet, REGACKMsgId);
if (elm == nullptr) if (elm == nullptr)
{ {
return 0; return 0;
} }
if (_first == nullptr) if (_first == nullptr)
{ {
_first = elm; _first = elm;
_end = elm; _end = elm;
} }
else else
{ {
_end->_next = elm; _end->_next = elm;
elm->_prev = _end; elm->_prev = _end;
_end = elm; _end = elm;
} }
_cnt++; _cnt++;
return 1; return 1;
} }
MQTTSNPacket* WaitREGACKPacketList::getPacket(uint16_t REGACKMsgId) MQTTSNPacket* WaitREGACKPacketList::getPacket(uint16_t REGACKMsgId)
{ {
waitREGACKPacket* p = _first; waitREGACKPacket* p = _first;
while (p) while (p)
{ {
if (p->_msgId == REGACKMsgId) if (p->_msgId == REGACKMsgId)
{ {
return p->_packet; return p->_packet;
} }
p = p->_next; p = p->_next;
} }
return nullptr; return nullptr;
} }
void WaitREGACKPacketList::erase(uint16_t REGACKMsgId) void WaitREGACKPacketList::erase(uint16_t REGACKMsgId)
{ {
waitREGACKPacket* p = _first; waitREGACKPacket* p = _first;
while (p) while (p)
{ {
if (p->_msgId == REGACKMsgId) if (p->_msgId == REGACKMsgId)
{ {
if (p->_prev == nullptr) if (p->_prev == nullptr)
{ {
_first = p->_next; _first = p->_next;
} }
else else
{ {
p->_prev->_next = p->_next; p->_prev->_next = p->_next;
} }
if (p->_next == nullptr) if (p->_next == nullptr)
{ {
_end = p->_prev; _end = p->_prev;
} }
else else
{ {
p->_next->_prev = p->_prev; p->_next->_prev = p->_prev;
} }
_cnt--; _cnt--;
break; break;
// Do not delete element. Element is deleted after sending to Client. // Do not delete element. Element is deleted after sending to Client.
} }
p = p->_next; p = p->_next;
} }
} }
uint8_t WaitREGACKPacketList::getCount(void) uint8_t WaitREGACKPacketList::getCount(void)
@@ -691,4 +694,3 @@ uint8_t WaitREGACKPacketList::getCount(void)
return _cnt; return _cnt;
} }

View File

@@ -49,7 +49,6 @@ public:
_que = new Que<T>; _que = new Que<T>;
} }
~PacketQue() ~PacketQue()
{ {
clear(); clear();
@@ -72,8 +71,7 @@ public:
} }
} }
int int post(T* packet)
post(T* packet)
{ {
int rc; int rc;
_mutex.lock(); _mutex.lock();
@@ -113,8 +111,6 @@ private:
Mutex _mutex; Mutex _mutex;
}; };
/*===================================== /*=====================================
Class WaitREGACKPacket Class WaitREGACKPacket
=====================================*/ =====================================*/
@@ -151,26 +147,37 @@ private:
waitREGACKPacket* _end; waitREGACKPacket* _end;
}; };
/*===================================== /*=====================================
Class Client Class Client
=====================================*/ =====================================*/
typedef enum 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; } ClientStatus;
typedef enum typedef enum
{ {
Ctype_Regular = 0, Ctype_Forwarded, Ctype_QoS_1, Ctype_Aggregated, Ctype_Proxy, Ctype_Aggregater Ctype_Normal = 0,
}ClientType; Ctype_Forwarded,
Ctype_QoS_1,
Ctype_Aggregated,
Ctype_Proxy,
Ctype_Aggregater
} ClientType;
class Forwarder; class Forwarder;
class Client class Client
{ {
friend class ClientList; friend class ClientList;
friend class ClientsPool;
public: public:
Client(bool secure = false); Client(bool secure = false);
Client(uint8_t maxInflightMessages, bool secure); Client(uint8_t maxInflightMessages, bool secure);
@@ -191,10 +198,10 @@ public:
void clearWaitedPubTopicId(void); void clearWaitedPubTopicId(void);
void clearWaitedSubTopicId(void); void clearWaitedSubTopicId(void);
int setClientSleepPacket(MQTTGWPacket*); int setClientSleepPacket(MQTTGWPacket*);
int setProxyPacket(MQTTSNPacket* packet); int setProxyPacket(MQTTSNPacket* packet);
void setWaitedPubTopicId(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_topicTypes type); void setWaitedSubTopicId(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
bool checkTimeover(void); bool checkTimeover(void);
void updateStatus(MQTTSNPacket*); void updateStatus(MQTTSNPacket*);
@@ -249,6 +256,7 @@ public:
bool isSecureNetwork(void); bool isSecureNetwork(void);
bool isSensorNetStable(void); bool isSensorNetStable(void);
bool isWaitWillMsg(void); bool isWaitWillMsg(void);
bool isCleanSession(void);
void holdPingRequest(void); void holdPingRequest(void);
void resetPingRequest(void); void resetPingRequest(void);
@@ -260,7 +268,7 @@ private:
PacketQue<MQTTGWPacket> _clientSleepPacketQue; PacketQue<MQTTGWPacket> _clientSleepPacketQue;
PacketQue<MQTTSNPacket> _proxyPacketQue; PacketQue<MQTTSNPacket> _proxyPacketQue;
WaitREGACKPacketList _waitREGACKList; WaitREGACKPacketList _waitREGACKList;
Topics* _topics; Topics* _topics;
TopicIdMap _waitedPubTopicIdMap; TopicIdMap _waitedPubTopicIdMap;
@@ -285,7 +293,7 @@ private:
uint8_t _snMsgId; uint8_t _snMsgId;
Network* _network; // Broker Network* _network; // Broker
bool _secureNetwork; // SSL bool _secureNetwork; // SSL
bool _sensorNetype; // false: unstable network like a G3 bool _sensorNetype; // false: unstable network like a G3
SensorNetAddress _sensorNetAddr; SensorNetAddress _sensorNetAddr;
@@ -299,7 +307,5 @@ private:
Client* _prevClient; Client* _prevClient;
}; };
} }
#endif /* MQTTSNGWCLIENT_H_ */ #endif /* MQTTSNGWCLIENT_H_ */

View File

@@ -20,18 +20,20 @@
#include <string> #include <string>
using namespace MQTTSNGW; using namespace MQTTSNGW;
extern Gateway* theGateway; char* currentDateTime(void);
/*===================================== /*=====================================
Class ClientList Class ClientList
=====================================*/ =====================================*/
const char* common_topic = "*"; const char* common_topic = "*";
ClientList::ClientList() ClientList::ClientList(Gateway* gw)
{ {
_clientCnt = 0; _clientCnt = 0;
_authorize = false; _authorize = false;
_firstClient = nullptr; _firstClient = nullptr;
_endClient = nullptr; _endClient = nullptr;
_clientsPool = new ClientsPool();
_gateway = gw;
} }
ClientList::~ClientList() ClientList::~ClientList()
@@ -46,43 +48,51 @@ ClientList::~ClientList()
delete cl; delete cl;
cl = ncl; cl = ncl;
}; };
if (_clientsPool)
{
delete _clientsPool;
}
_mutex.unlock(); _mutex.unlock();
} }
void ClientList::initialize(bool aggregate) 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; int type = TRANSPEARENT_TYPE;
if ( aggregate ) if (aggregate)
{ {
type = AGGREGATER_TYPE; type = AGGREGATER_TYPE;
} }
setClientList(type); setClientList(type);
_authorize = true; _authorize = true;
} }
if ( theGateway->getGWParams()->predefinedTopic ) if (_gateway->getGWParams()->predefinedTopic)
{ {
setPredefinedTopics(aggregate); setPredefinedTopics(aggregate);
} }
} }
void ClientList::setClientList(int type) 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) 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,17 +158,17 @@ bool ClientList::createList(const char* fileName, int type)
forwarder = (data.find("forwarder") != string::npos); forwarder = (data.find("forwarder") != string::npos);
secure = (data.find("secureConnection") != string::npos); secure = (data.find("secureConnection") != string::npos);
stable = !(data.find("unstableLine") != 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); 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); createClient(&netAddr, &clientId, stable, secure, type);
} }
} }
else else
@@ -179,7 +189,8 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
FILE* fp; FILE* fp;
char buf[MAX_CLIENTID_LENGTH + 256]; char buf[MAX_CLIENTID_LENGTH + 256];
size_t pos0, pos1; size_t pos0, pos1;
MQTTSNString clientId = MQTTSNString_initializer;; MQTTSNString clientId = MQTTSNString_initializer;
;
bool rc = false; bool rc = false;
if ((fp = fopen(fileName, "r")) != 0) if ((fp = fopen(fileName, "r")) != 0)
@@ -201,12 +212,12 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
} }
pos0 = data.find_first_of(","); pos0 = data.find_first_of(",");
pos1 = data.find(",", pos0 + 1) ; pos1 = data.find(",", pos0 + 1);
string id = data.substr(0, pos0); string id = data.substr(0, pos0);
clientId.cstring = strdup(id.c_str()); 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)); uint16_t topicID = stoul(data.substr(pos1 + 1));
createPredefinedTopic( &clientId, topicName, topicID, aggregate); createPredefinedTopic(&clientId, topicName, topicID, aggregate);
free(clientId.cstring); free(clientId.cstring);
} }
fclose(fp); fclose(fp);
@@ -222,7 +233,7 @@ bool ClientList::readPredefinedList(const char* fileName, bool aggregate)
void ClientList::erase(Client*& client) void ClientList::erase(Client*& client)
{ {
if ( !_authorize && client->erasable()) if (!_authorize && client->erasable())
{ {
_mutex.lock(); _mutex.lock();
Client* prev = client->_prevClient; Client* prev = client->_prevClient;
@@ -247,7 +258,7 @@ void ClientList::erase(Client*& client)
} }
_clientCnt--; _clientCnt--;
Forwarder* fwd = client->getForwarder(); Forwarder* fwd = client->getForwarder();
if ( fwd ) if (fwd)
{ {
fwd->eraseClient(client); fwd->eraseClient(client);
} }
@@ -259,14 +270,14 @@ void ClientList::erase(Client*& client)
Client* ClientList::getClient(SensorNetAddress* addr) Client* ClientList::getClient(SensorNetAddress* addr)
{ {
if ( addr ) if (addr)
{ {
_mutex.lock(); _mutex.lock();
Client* client = _firstClient; Client* client = _firstClient;
while (client != nullptr) while (client != nullptr)
{ {
if (client->getSensorNetAddress()->isMatch(addr) ) if (client->getSensorNetAddress()->isMatch(addr))
{ {
_mutex.unlock(); _mutex.unlock();
return client; return client;
@@ -280,38 +291,37 @@ Client* ClientList::getClient(SensorNetAddress* addr)
Client* ClientList::getClient(int index) Client* ClientList::getClient(int index)
{ {
Client* client = _firstClient; Client* client = _firstClient;
int p = 0; int p = 0;
while ( client != nullptr ) while (client != nullptr)
{ {
if ( p == index ) if (p == index)
{ {
return client; return client;
} }
else else
{ {
client = client->_nextClient; client = client->_nextClient;
p++; p++;
} }
} }
return nullptr; return nullptr;
} }
Client* ClientList::getClient(MQTTSNString* clientId) Client* ClientList::getClient(MQTTSNString* clientId)
{ {
_mutex.lock(); _mutex.lock();
Client* client = _firstClient; Client* client = _firstClient;
const char* clID =clientId->cstring; const char* clID = clientId->cstring;
if (clID == nullptr ) if (clID == nullptr)
{ {
clID = clientId->lenstring.data; clID = clientId->lenstring.data;
} }
while (client != nullptr) 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(); _mutex.unlock();
return client; return client;
@@ -324,57 +334,59 @@ Client* ClientList::getClient(MQTTSNString* clientId)
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, int type) Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, int type)
{ {
return createClient(addr, clientId, false, false, type); return createClient(addr, clientId, false, false, type);
} }
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type) Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type)
{ {
Client* client = nullptr; Client* client = getClient(addr);
if (client)
/* anonimous clients */
if ( _clientCnt > MAX_CLIENTS )
{
return 0; // full of clients
}
client = getClient(addr);
if ( client )
{ {
return client; return client;
} }
/* creat a new client */ /* acquire a free client */
client = new Client(secure); client = _clientsPool->getClient();
if ( addr )
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->setClientAddress(addr);
} }
client->setSensorNetType(unstableLine); client->setSensorNetType(unstableLine);
if ( MQTTSNstrlen(*clientId) ) if (MQTTSNstrlen(*clientId))
{ {
client->setClientId(*clientId); client->setClientId(*clientId);
} }
else else
{ {
MQTTSNString dummyId MQTTSNString_initializer; MQTTSNString dummyId MQTTSNString_initializer;
dummyId.cstring = strdup(""); dummyId.cstring = strdup("");
client->setClientId(dummyId); client->setClientId(dummyId);
free(dummyId.cstring); free(dummyId.cstring);
} }
if ( type == AGGREGATER_TYPE ) if (type == AGGREGATER_TYPE)
{ {
client->setAggregated(); client->setAggregated();
} }
else if ( type == QOSM1PROXY_TYPE ) else if (type == QOSM1PROXY_TYPE)
{ {
client->setQoSm1(); client->setQoSm1();
} }
client->getNetwork()->setSecure(secure);
_mutex.lock(); _mutex.lock();
/* add the list */ /* add the list */
if ( _firstClient == nullptr ) if (_firstClient == nullptr)
{ {
_firstClient = client; _firstClient = client;
_endClient = client; _endClient = client;
@@ -390,66 +402,40 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
return client; 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()); WRITELOG("Invalid TopicId. Predefined Topic %s, TopicId is 0. \n", topicName.c_str());
return nullptr; 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; return nullptr;
} }
else else
{ {
Client* client = getClient(clientId); Client *client = getClient(clientId);
if ( _authorize && client == nullptr ) if (_authorize && client == nullptr)
{ {
return nullptr; return nullptr;
} }
/* anonimous clients */ client = createClient(NULL, clientId, aggregate);
if ( _clientCnt > MAX_CLIENTS )
{
return nullptr; // full of clients
}
if ( client == nullptr ) if (client == nullptr)
{ {
/* creat a new client */ return nullptr;
client = new Client(); }
client->setClientId(*clientId);
if ( aggregate )
{
client->setAggregated();
}
_mutex.lock();
/* add the list */ // create Topic & Add it
if ( _firstClient == nullptr ) client->getTopics()->add((const char*) topicName.c_str(), topicId);
{ client->_hasPredefTopic = true;
_firstClient = client; return client;
_endClient = client; }
}
else
{
_endClient->_nextClient = client;
client->_prevClient = _endClient;
_endClient = client;
}
_clientCnt++;
_mutex.unlock();
}
// create Topic & Add it
client->getTopics()->add((const char*)topicName.c_str(), topicId);
client->_hasPredefTopic = true;
return client;
}
} }
uint16_t ClientList::getClientCount() uint16_t ClientList::getClientCount()
@@ -462,4 +448,70 @@ bool ClientList::isAuthorized()
return _authorize; 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++;
}
}

View File

@@ -30,21 +30,41 @@ namespace MQTTSNGW
class Client; 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
=====================================*/ =====================================*/
class ClientList class ClientList
{ {
public: public:
ClientList(); ClientList(Gateway* gw);
~ClientList(); ~ClientList();
void initialize(bool aggregate); void initialize(bool aggregate);
void setClientList(int type); void setClientList(int type);
void setPredefinedTopics(bool aggregate); void setPredefinedTopics(bool aggregate);
void erase(Client*&); void erase(Client*&);
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,int type); Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId, bool unstableLine, bool secure, int type); int type);
Client* createClient(SensorNetAddress* addr, MQTTSNString* clientId,
bool unstableLine, bool secure, int type);
bool createList(const char* fileName, int type); bool createList(const char* fileName, int type);
Client* getClient(SensorNetAddress* addr); Client* getClient(SensorNetAddress* addr);
Client* getClient(MQTTSNString* clientId); Client* getClient(MQTTSNString* clientId);
@@ -55,18 +75,18 @@ public:
private: private:
bool readPredefinedList(const char* fileName, bool _aggregate); bool readPredefinedList(const char* fileName, bool _aggregate);
Gateway* _gateway {nullptr}; ClientsPool* _clientsPool;
Client* createPredefinedTopic( MQTTSNString* clientId, string topicName, uint16_t toipcId, bool _aggregate); Gateway* _gateway;
Client* createPredefinedTopic(MQTTSNString* clientId, string topicName,
uint16_t toipcId, bool _aggregate);
Client* _firstClient; Client* _firstClient;
Client* _endClient; Client* _endClient;
Mutex _mutex; Mutex _mutex;
uint16_t _clientCnt; uint16_t _clientCnt;
bool _authorize {false}; uint16_t _maxClients;
bool _authorize { false };
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */

View File

@@ -20,8 +20,6 @@
#include "MQTTSNGWEncapsulatedPacket.h" #include "MQTTSNGWEncapsulatedPacket.h"
#include <cstring> #include <cstring>
//#include "MQTTSNGWForwarder.h"
using namespace MQTTSNGW; using namespace MQTTSNGW;
char* currentDateTime(void); char* currentDateTime(void);
/*===================================== /*=====================================
@@ -29,242 +27,262 @@ char* currentDateTime(void);
=====================================*/ =====================================*/
ClientRecvTask::ClientRecvTask(Gateway* gateway) ClientRecvTask::ClientRecvTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*)this); _gateway->attach((Thread*) this);
_sensorNetwork = _gateway->getSensorNetwork(); _sensorNetwork = _gateway->getSensorNetwork();
setTaskName("ClientRecvTask");
} }
ClientRecvTask::~ClientRecvTask() ClientRecvTask::~ClientRecvTask()
{ {
} }
/**
* Initialize SensorNetwork
*/
void ClientRecvTask::initialize(int argc, char** argv) 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 * 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. * of MQTTSNPacketHandlingTask.
*/ */
void ClientRecvTask::run() void ClientRecvTask::run()
{ {
Event* ev = nullptr; Event* ev = nullptr;
AdapterManager* adpMgr = _gateway->getAdapterManager(); AdapterManager* adpMgr = _gateway->getAdapterManager();
QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy(); QoSm1Proxy* qosm1Proxy = adpMgr->getQoSm1Proxy();
int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE; int clientType = adpMgr->isAggregaterActive() ? AGGREGATER_TYPE : TRANSPEARENT_TYPE;
ClientList* clientList = _gateway->getClientList(); ClientList* clientList = _gateway->getClientList();
EventQue* packetEventQue = _gateway->getPacketEventQue(); EventQue* packetEventQue = _gateway->getPacketEventQue();
EventQue* clientsendQue = _gateway->getClientSendQue();
char buf[128]; char buf[128];
while (true) while (true)
{ {
Client* client = nullptr; Client* client = nullptr;
Forwarder* fwd = nullptr; Forwarder* fwd = nullptr;
WirelessNodeId nodeId; WirelessNodeId nodeId;
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
int packetLen = packet->recv(_sensorNetwork); int packetLen = packet->recv(_sensorNetwork);
if (CHK_SIGINT) if (CHK_SIGINT)
{ {
WRITELOG("\n%s ClientRecvTask stopped.", currentDateTime()); WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
delete packet; delete packet;
return; return;
} }
if (packetLen < 2 ) if (packetLen < 2)
{ {
delete packet; delete packet;
continue; continue;
} }
if ( packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO ) if (packet->getType() <= MQTTSN_ADVERTISE || packet->getType() == MQTTSN_GWINFO)
{ {
delete packet; delete packet;
continue; continue;
} }
if ( packet->getType() == MQTTSN_SEARCHGW ) if (packet->getType() == MQTTSN_SEARCHGW)
{ {
/* write log and post Event */ /* write log and post Event */
log(0, packet, 0); log(0, packet, 0);
ev = new Event(); ev = new Event();
ev->setBrodcastEvent(packet); ev->setBrodcastEvent(packet);
packetEventQue->post(ev); packetEventQue->post(ev);
continue; continue;
} }
SensorNetAddress senderAddr = *_gateway->getSensorNetwork()->getSenderAddress();
SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress(); if (packet->getType() == MQTTSN_ENCAPSULATED)
{
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(&senderAddr);
if ( packet->getType() == MQTTSN_ENCAPSULATED ) if (fwd != nullptr)
{ {
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr); MQTTSNString fwdName = MQTTSNString_initializer;
fwdName.cstring = const_cast<char *>(fwd->getName());
log(0, packet, &fwdName);
if ( fwd != nullptr ) /* get the packet from the encapsulation message */
{ MQTTSNGWEncapsulatedPacket encap;
MQTTSNString fwdName = MQTTSNString_initializer; encap.desirialize(packet->getPacketData(), packet->getPacketLength());
fwdName.cstring = const_cast<char *>( fwd->getName() ); nodeId.setId(encap.getWirelessNodeId());
log(0, packet, &fwdName); client = fwd->getClient(&nodeId);
packet = encap.getMQTTSNPacket();
}
}
else
{
/* Check the client belonging to QoS-1Proxy ? */
/* get the packet from the encapsulation message */ if (qosm1Proxy->isActive())
MQTTSNGWEncapsulatedPacket encap; {
encap.desirialize(packet->getPacketData(), packet->getPacketLength()); const char *clientName = qosm1Proxy->getClientId(&senderAddr);
nodeId.setId( encap.getWirelessNodeId() );
client = fwd->getClient(&nodeId);
packet = encap.getMQTTSNPacket();
}
}
else
{
/* Check the client belonging to QoS-1Proxy ? */
if ( qosm1Proxy->isActive() ) if (clientName != nullptr)
{ {
const char* clientName = qosm1Proxy->getClientId(senderAddr); client = qosm1Proxy->getClient();
if ( clientName != nullptr ) if (!packet->isQoSMinusPUBLISH())
{ {
client = qosm1Proxy->getClient(); log(clientName, packet);
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 ( !packet->isQoSMinusPUBLISH() ) if (client == nullptr)
{ {
log(clientName, packet); client = _gateway->getClientList()->getClient(&senderAddr);
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); log(client, packet, 0);
}
}
if ( client != nullptr ) if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
{ {
/* write log and post Event */ WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
log(client, packet, 0); ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
ev = new Event();
ev->setClientRecvEvent(client,packet);
packetEventQue->post(ev);
}
else
{
/* new client */
if (packet->getType() == MQTTSN_CONNECT)
{
MQTTSNPacket_connectData data;
memset(&data, 0, sizeof(MQTTSNPacket_connectData));
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);
delete packet;
continue;
}
client = clientList->getClient(&data.clientID); /* send DISCONNECT to the client, if it is not connected */
MQTTSNPacket* snPacket = new MQTTSNPacket();
snPacket->setDISCONNECT(0);
ev = new Event();
ev->setClientSendEvent(client, snPacket);
clientsendQue->post(ev);
delete packet;
continue;
}
else
{
ev = new Event();
ev->setClientRecvEvent(client, packet);
packetEventQue->post(ev);
}
}
else
{
/* new client */
if (packet->getType() == MQTTSN_CONNECT)
{
MQTTSNPacket_connectData data;
memset(&data, 0, sizeof(MQTTSNPacket_connectData));
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);
delete packet;
continue;
}
if ( fwd != nullptr ) client = clientList->getClient(&data.clientID);
{
if ( client == nullptr ) if (fwd != nullptr)
{ {
/* create a new client */ if (client == nullptr)
client = clientList->createClient(0, &data.clientID, clientType); {
} /* create a new client */
/* Add to a forwarded client list of forwarder. */ client = clientList->createClient(0, &data.clientID, clientType);
}
/* Add to a forwarded client list of forwarder. */
fwd->addClient(client, &nodeId); fwd->addClient(client, &nodeId);
} }
else else
{ {
if ( client ) if (client)
{ {
/* Authentication is not required */ /* Authentication is not required */
if ( _gateway->getGWParams()->clientAuthentication == false) if (_gateway->getGWParams()->clientAuthentication == false)
{ {
client->setClientAddress(senderAddr); client->setClientAddress(&senderAddr);
} }
} }
else else
{ {
/* create a new client */ /* create a new client */
client = clientList->createClient(senderAddr, &data.clientID, clientType); client = clientList->createClient(&senderAddr, &data.clientID, clientType);
} }
} }
log(client, packet, &data.clientID); 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",
delete packet; ERRMSG_HEADER, senderAddr.sprint(buf),
continue; ERRMSG_FOOTER);
} delete packet;
continue;
}
/* post Client RecvEvent */ /* post Client RecvEvent */
ev = new Event(); ev = new Event();
ev->setClientRecvEvent(client, packet); ev->setClientRecvEvent(client, packet);
packetEventQue->post(ev); packetEventQue->post(ev);
} }
else else
{ {
log(client, packet, 0); 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",
else ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->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); }
} else
delete packet; {
} WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
} ERRMSG_HEADER, senderAddr.sprint(buf),
} ERRMSG_FOOTER);
}
delete packet;
}
}
}
} }
void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id) void ClientRecvTask::log(Client* client, MQTTSNPacket* packet, MQTTSNString* id)
{ {
const char* clientId; const char* clientId;
char cstr[MAX_CLIENTID_LENGTH + 1]; 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 );
clientId = cstr; clientId = cstr;
} }
} else
else if ( client ) {
{ memset((void*) cstr, 0, id->lenstring.len + 1);
clientId = client->getClientId(); strncpy(cstr, id->lenstring.data, id->lenstring.len);
} clientId = cstr;
else }
{ }
clientId = UNKNOWNCL; else if (client)
} {
clientId = client->getClientId();
}
else
{
clientId = UNKNOWNCL;
}
log(clientId, packet); log(clientId, packet);
} }
void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet) void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
@@ -275,11 +293,13 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_SEARCHGW: 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; break;
case MQTTSN_CONNECT: case MQTTSN_CONNECT:
case MQTTSN_PINGREQ: 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; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
case MQTTSN_WILLTOPICUPD: case MQTTSN_WILLTOPICUPD:
@@ -292,18 +312,20 @@ void ClientRecvTask::log(const char* clientId, MQTTSNPacket* packet)
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: 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; break;
case MQTTSN_REGACK: case MQTTSN_REGACK:
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
case MQTTSN_PUBCOMP: 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; break;
case MQTTSN_ENCAPSULATED: case MQTTSN_ENCAPSULATED:
WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf)); WRITELOG(FORMAT_Y_G_G, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
break; break;
default: default:
WRITELOG(FORMAT_W_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf)); WRITELOG(FORMAT_W_NL, currentDateTime(), packet->getName(), LEFTARROW, clientId, packet->print(pbuf));
break; break;

View File

@@ -24,24 +24,24 @@ namespace MQTTSNGW
class AdapterManager; class AdapterManager;
/*===================================== /*=====================================
Class ClientRecvTask Class ClientRecvTask
=====================================*/ =====================================*/
class ClientRecvTask:public Thread class ClientRecvTask: public Thread
{ {
MAGIC_WORD_FOR_THREAD; MAGIC_WORD_FOR_THREAD;
friend AdapterManager; friend AdapterManager;
public: public:
ClientRecvTask(Gateway*); ClientRecvTask(Gateway*);
~ClientRecvTask(void); ~ClientRecvTask(void);
virtual void initialize(int argc, char** argv); virtual void initialize(int argc, char** argv);
void run(void); void run(void);
private: private:
void log(Client*, MQTTSNPacket*, MQTTSNString* id); void log(Client*, MQTTSNPacket*, MQTTSNString* id);
void log(const char* clientId, MQTTSNPacket* packet); void log(const char* clientId, MQTTSNPacket* packet);
Gateway* _gateway; Gateway* _gateway;
SensorNetwork* _sensorNetwork; SensorNetwork* _sensorNetwork;
}; };
} }

View File

@@ -28,106 +28,110 @@ char* currentDateTime(void);
=====================================*/ =====================================*/
ClientSendTask::ClientSendTask(Gateway* gateway) ClientSendTask::ClientSendTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*)this); _gateway->attach((Thread*) this);
_sensorNetwork = _gateway->getSensorNetwork(); _sensorNetwork = _gateway->getSensorNetwork();
setTaskName("ClientSendTask");
} }
ClientSendTask::~ClientSendTask() ClientSendTask::~ClientSendTask()
{ {
// WRITELOG("ClientSendTask is deleted normally.\r\n");
} }
void ClientSendTask::run() void ClientSendTask::run()
{ {
Client* client = nullptr; Client* client = nullptr;
MQTTSNPacket* packet = nullptr; MQTTSNPacket* packet = nullptr;
AdapterManager* adpMgr = _gateway->getAdapterManager(); AdapterManager* adpMgr = _gateway->getAdapterManager();
int rc = 0; int rc = 0;
while (true) while (true)
{ {
Event* ev = _gateway->getClientSendQue()->wait(); 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; delete ev;
break; break;
} }
if (ev->getEventType() == EtBroadcast) if (ev->getEventType() == EtBroadcast)
{ {
packet = ev->getMQTTSNPacket(); packet = ev->getMQTTSNPacket();
log(client, packet); 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", WRITELOG("%s ClientSendTask can't multicast a packet Error=%d%s\n",
ERRMSG_HEADER, errno, ERRMSG_FOOTER); ERRMSG_HEADER, errno, ERRMSG_FOOTER);
} }
} }
else else
{ {
if (ev->getEventType() == EtClientSend) if (ev->getEventType() == EtClientSend)
{ {
client = ev->getClient(); client = ev->getClient();
packet = ev->getMQTTSNPacket(); packet = ev->getMQTTSNPacket();
rc = adpMgr->unicastToClient(client, packet, this); rc = adpMgr->unicastToClient(client, packet, this);
} }
else if (ev->getEventType() == EtSensornetSend) else if (ev->getEventType() == EtSensornetSend)
{ {
packet = ev->getMQTTSNPacket(); packet = ev->getMQTTSNPacket();
log(client, packet); log(client, packet);
rc = packet->unicast(_sensorNetwork, ev->getSensorNetAddress()); 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", 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; }
} delete ev;
}
} }
void ClientSendTask::log(Client* client, MQTTSNPacket* packet) void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
{ {
char pbuf[SIZE_OF_LOG_PACKET * 3 + 1]; char pbuf[SIZE_OF_LOG_PACKET * 3 + 1];
char msgId[6]; char msgId[6];
const char* clientId = client ? (const char*)client->getClientId() : UNKNOWNCL ; const char* clientId = client ? (const char*) client->getClientId() : UNKNOWNCL;
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_ADVERTISE: case MQTTSN_ADVERTISE:
case MQTTSN_GWINFO: 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,
break; CLIENTS, packet->print(pbuf));
case MQTTSN_CONNACK: break;
case MQTTSN_DISCONNECT: case MQTTSN_CONNACK:
case MQTTSN_WILLTOPICREQ: case MQTTSN_DISCONNECT:
case MQTTSN_WILLMSGREQ: case MQTTSN_WILLTOPICREQ:
case MQTTSN_WILLTOPICRESP: case MQTTSN_WILLMSGREQ:
case MQTTSN_WILLMSGRESP: case MQTTSN_WILLTOPICRESP:
case MQTTSN_PINGRESP: case MQTTSN_WILLMSGRESP:
WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, clientId, packet->print(pbuf)); case MQTTSN_PINGRESP:
break; WRITELOG(FORMAT_Y_W_G, currentDateTime(), packet->getName(), RIGHTARROW, clientId, packet->print(pbuf));
case MQTTSN_REGISTER: break;
case MQTTSN_PUBLISH: case MQTTSN_REGISTER:
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf)); case MQTTSN_PUBLISH:
break; WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
case MQTTSN_REGACK: packet->print(pbuf));
case MQTTSN_PUBACK: break;
case MQTTSN_PUBREC: case MQTTSN_REGACK:
case MQTTSN_PUBREL: case MQTTSN_PUBACK:
case MQTTSN_PUBCOMP: case MQTTSN_PUBREC:
case MQTTSN_SUBACK: case MQTTSN_PUBREL:
case MQTTSN_UNSUBACK: case MQTTSN_PUBCOMP:
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf)); case MQTTSN_SUBACK:
break; case MQTTSN_UNSUBACK:
default: WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
break; packet->print(pbuf));
} break;
default:
break;
}
} }

View File

@@ -28,18 +28,18 @@ class AdapterManager;
=====================================*/ =====================================*/
class ClientSendTask: public Thread class ClientSendTask: public Thread
{ {
MAGIC_WORD_FOR_THREAD; MAGIC_WORD_FOR_THREAD;
friend AdapterManager; friend AdapterManager;
public: public:
ClientSendTask(Gateway* gateway); ClientSendTask(Gateway* gateway);
~ClientSendTask(void); ~ClientSendTask(void);
void run(void); void run(void);
private: private:
void log(Client* client, MQTTSNPacket* packet); void log(Client* client, MQTTSNPacket* packet);
Gateway* _gateway; Gateway* _gateway;
SensorNetwork* _sensorNetwork; SensorNetwork* _sensorNetwork;
}; };
} }

View File

@@ -28,7 +28,7 @@ using namespace MQTTSNGW;
=====================================*/ =====================================*/
MQTTSNConnectionHandler::MQTTSNConnectionHandler(Gateway* gateway) MQTTSNConnectionHandler::MQTTSNConnectionHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTSNConnectionHandler::~MQTTSNConnectionHandler() MQTTSNConnectionHandler::~MQTTSNConnectionHandler()
@@ -41,11 +41,11 @@ MQTTSNConnectionHandler::~MQTTSNConnectionHandler()
*/ */
void MQTTSNConnectionHandler::sendADVERTISE() void MQTTSNConnectionHandler::sendADVERTISE()
{ {
MQTTSNPacket* adv = new MQTTSNPacket(); MQTTSNPacket* adv = new MQTTSNPacket();
adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive); adv->setADVERTISE(_gateway->getGWParams()->gatewayId, _gateway->getGWParams()->keepAlive);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrodcastEvent(adv); //broadcast ev1->setBrodcastEvent(adv); //broadcast
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
/* /*
@@ -53,14 +53,14 @@ void MQTTSNConnectionHandler::sendADVERTISE()
*/ */
void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
{ {
if (packet->getType() == MQTTSN_SEARCHGW) if (packet->getType() == MQTTSN_SEARCHGW)
{ {
MQTTSNPacket* gwinfo = new MQTTSNPacket(); MQTTSNPacket* gwinfo = new MQTTSNPacket();
gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId); gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId);
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrodcastEvent(gwinfo); ev1->setBrodcastEvent(gwinfo);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
} }
} }
/* /*
@@ -68,89 +68,91 @@ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
*/ */
void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet)
{ {
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
if ( packet->getCONNECT(&data) == 0 ) if (packet->getCONNECT(&data) == 0)
{ {
return; return;
} }
/* return CONNACK when the client is sleeping */ /* return CONNACK when the client is sleeping */
if ( client->isSleep() || client->isAwake() ) if (client->isSleep() || client->isAwake())
{ {
MQTTSNPacket* packet = new MQTTSNPacket(); MQTTSNPacket* packet = new MQTTSNPacket();
packet->setCONNACK(MQTTSN_RC_ACCEPTED); packet->setCONNACK(MQTTSN_RC_ACCEPTED);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, packet); ev->setClientSendEvent(client, packet);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
sendStoredPublish(client); sendStoredPublish(client);
return; return;
} }
//* clear ConnectData of Client */ //* clear ConnectData of Client */
Connect* connectData = client->getConnectData(); Connect* connectData = client->getConnectData();
memset(connectData, 0, sizeof(Connect)); memset(connectData, 0, sizeof(Connect));
if ( !client->isAdapter() ) if (!client->isAdapter())
{ {
client->disconnected(); client->disconnected();
} }
Topics* topics = client->getTopics(); Topics* topics = client->getTopics();
/* CONNECT was not sent yet. prepare Connect data */ /* CONNECT was not sent yet. prepare Connect data */
connectData->header.bits.type = CONNECT; connectData->header.bits.type = CONNECT;
connectData->clientID = client->getClientId(); connectData->clientID = client->getClientId();
connectData->version = _gateway->getGWParams()->mqttVersion; connectData->version = _gateway->getGWParams()->mqttVersion;
connectData->keepAliveTimer = data.duration; connectData->keepAliveTimer = data.duration;
connectData->flags.bits.will = data.willFlag; connectData->flags.bits.will = data.willFlag;
if ((const char*) _gateway->getGWParams()->loginId != nullptr) if ((const char*) _gateway->getGWParams()->loginId != nullptr)
{ {
connectData->flags.bits.username = 1; connectData->flags.bits.username = 1;
} }
if ((const char*) _gateway->getGWParams()->password != 0) if ((const char*) _gateway->getGWParams()->password != 0)
{ {
connectData->flags.bits.password = 1; connectData->flags.bits.password = 1;
} }
client->setSessionStatus(false); client->setSessionStatus(false);
if (data.cleansession) if (data.cleansession)
{ {
connectData->flags.bits.cleanstart = 1; connectData->flags.bits.cleanstart = 1;
/* reset the table of msgNo and TopicId pare */ /* reset the table of msgNo and TopicId pare */
client->clearWaitedPubTopicId(); client->clearWaitedPubTopicId();
client->clearWaitedSubTopicId(); client->clearWaitedSubTopicId();
/* renew the TopicList */ /* renew the TopicList */
if (topics) if (topics)
{ {
topics->eraseNormal();; topics->eraseNormal();
} ;
client->setSessionStatus(true); }
} client->setSessionStatus(true);
}
if (data.willFlag) if (data.willFlag)
{ {
/* create & send WILLTOPICREQ message to the client */ /* create & send WILLTOPICREQ message to the client */
MQTTSNPacket* reqTopic = new MQTTSNPacket(); MQTTSNPacket* reqTopic = new MQTTSNPacket();
reqTopic->setWILLTOPICREQ(); reqTopic->setWILLTOPICREQ();
Event* evwr = new Event(); Event* evwr = new Event();
evwr->setClientSendEvent(client, reqTopic); evwr->setClientSendEvent(client, reqTopic);
/* Send WILLTOPICREQ to the client */ /* Send WILLTOPICREQ to the client */
_gateway->getClientSendQue()->post(evwr); _gateway->getClientSendQue()->post(evwr);
} }
else else
{ {
/* CONNECT message was not qued in. /* CONNECT message was not qued in.
* create CONNECT message & send it to the broker */ * create CONNECT message & send it to the broker */
MQTTGWPacket* mqMsg = new MQTTGWPacket(); 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,
Event* ev1 = new Event(); (unsigned char*) _gateway->getGWParams()->password);
ev1->setBrokerSendEvent(client, mqMsg); Event* ev1 = new Event();
_gateway->getBrokerSendQue()->post(ev1); ev1->setBrokerSendEvent(client, mqMsg);
} _gateway->getBrokerSendQue()->post(ev1);
}
} }
/* /*
@@ -158,29 +160,29 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
*/ */
void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* packet)
{ {
int willQos; int willQos;
uint8_t willRetain; uint8_t willRetain;
MQTTSNString willTopic = MQTTSNString_initializer; MQTTSNString willTopic = MQTTSNString_initializer;
if ( packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0 ) if (packet->getWILLTOPIC(&willQos, &willRetain, &willTopic) == 0)
{ {
return; return;
} }
client->setWillTopic(willTopic); client->setWillTopic(willTopic);
Connect* connectData = client->getConnectData(); Connect* connectData = client->getConnectData();
/* add the connectData for MQTT CONNECT message */ /* add the connectData for MQTT CONNECT message */
connectData->willTopic = client->getWillTopic(); connectData->willTopic = client->getWillTopic();
connectData->flags.bits.willQoS = willQos; connectData->flags.bits.willQoS = willQos;
connectData->flags.bits.willRetain = willRetain; connectData->flags.bits.willRetain = willRetain;
/* Send WILLMSGREQ to the client */ /* Send WILLMSGREQ to the client */
client->setWaitWillMsgFlg(true); client->setWaitWillMsgFlg(true);
MQTTSNPacket* reqMsg = new MQTTSNPacket(); MQTTSNPacket* reqMsg = new MQTTSNPacket();
reqMsg->setWILLMSGREQ(); reqMsg->setWILLMSGREQ();
Event* evt = new Event(); Event* evt = new Event();
evt->setClientSendEvent(client, reqMsg); evt->setClientSendEvent(client, reqMsg);
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
} }
/* /*
@@ -188,35 +190,36 @@ void MQTTSNConnectionHandler::handleWilltopic(Client* client, MQTTSNPacket* pack
*/ */
void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet)
{ {
if ( !client->isWaitWillMsg() ) if (!client->isWaitWillMsg())
{ {
DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n"); DEBUGLOG(" MQTTSNConnectionHandler::handleWillmsg WaitWillMsgFlg is off.\n");
return; return;
} }
MQTTSNString willmsg = MQTTSNString_initializer; MQTTSNString willmsg = MQTTSNString_initializer;
Connect* connectData = client->getConnectData(); Connect* connectData = client->getConnectData();
if( client->isConnectSendable() ) if (client->isConnectSendable())
{ {
/* save WillMsg in the client */ /* save WillMsg in the client */
if ( packet->getWILLMSG(&willmsg) == 0 ) if (packet->getWILLMSG(&willmsg) == 0)
{ {
return; return;
} }
client->setWillMsg(willmsg); client->setWillMsg(willmsg);
/* create CONNECT message */ /* create CONNECT message */
MQTTGWPacket* mqttPacket = new MQTTGWPacket(); MQTTGWPacket* mqttPacket = new MQTTGWPacket();
connectData->willMsg = client->getWillMsg(); 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 */ /* Send CONNECT to the broker */
Event* evt = new Event(); Event* evt = new Event();
evt->setBrokerSendEvent(client, mqttPacket); evt->setBrokerSendEvent(client, mqttPacket);
client->setWaitWillMsgFlg(false); client->setWaitWillMsgFlg(false);
_gateway->getBrokerSendQue()->post(evt); _gateway->getBrokerSendQue()->post(evt);
} }
} }
/* /*
@@ -226,9 +229,9 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* pac
{ {
uint16_t duration = 0; uint16_t duration = 0;
if ( packet->getDISCONNECT(&duration) != 0 ) if (packet->getDISCONNECT(&duration) != 0)
{ {
if ( duration == 0 ) if (duration == 0)
{ {
MQTTGWPacket* mqMsg = new MQTTGWPacket(); MQTTGWPacket* mqMsg = new MQTTGWPacket();
mqMsg->setHeader(DISCONNECT); mqMsg->setHeader(DISCONNECT);
@@ -250,12 +253,12 @@ void MQTTSNConnectionHandler::handleDisconnect(Client* client, MQTTSNPacket* pac
*/ */
void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* packet)
{ {
/* send NOT_SUPPORTED responce to the client */ /* send NOT_SUPPORTED responce to the client */
MQTTSNPacket* respMsg = new MQTTSNPacket(); MQTTSNPacket* respMsg = new MQTTSNPacket();
respMsg->setWILLTOPICRESP(MQTTSN_RC_NOT_SUPPORTED); respMsg->setWILLTOPICRESP(MQTTSN_RC_NOT_SUPPORTED);
Event* evt = new Event(); Event* evt = new Event();
evt->setClientSendEvent(client, respMsg); evt->setClientSendEvent(client, respMsg);
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
} }
/* /*
@@ -263,12 +266,12 @@ void MQTTSNConnectionHandler::handleWilltopicupd(Client* client, MQTTSNPacket* p
*/ */
void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* packet)
{ {
/* send NOT_SUPPORTED responce to the client */ /* send NOT_SUPPORTED responce to the client */
MQTTSNPacket* respMsg = new MQTTSNPacket(); MQTTSNPacket* respMsg = new MQTTSNPacket();
respMsg->setWILLMSGRESP(MQTTSN_RC_NOT_SUPPORTED); respMsg->setWILLMSGRESP(MQTTSN_RC_NOT_SUPPORTED);
Event* evt = new Event(); Event* evt = new Event();
evt->setClientSendEvent(client, respMsg); evt->setClientSendEvent(client, respMsg);
_gateway->getClientSendQue()->post(evt); _gateway->getClientSendQue()->post(evt);
} }
/* /*
@@ -276,31 +279,31 @@ void MQTTSNConnectionHandler::handleWillmsgupd(Client* client, MQTTSNPacket* pac
*/ */
void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet) void MQTTSNConnectionHandler::handlePingreq(Client* client, MQTTSNPacket* packet)
{ {
if ( ( client->isSleep() || client->isAwake() ) && client->getClientSleepPacket() ) if ((client->isSleep() || client->isAwake()) && client->getClientSleepPacket())
{ {
sendStoredPublish(client); sendStoredPublish(client);
client->holdPingRequest(); client->holdPingRequest();
} }
else else
{ {
/* send PINGREQ to the broker */ /* send PINGREQ to the broker */
client->resetPingRequest(); client->resetPingRequest();
MQTTGWPacket* pingreq = new MQTTGWPacket(); MQTTGWPacket* pingreq = new MQTTGWPacket();
pingreq->setHeader(PINGREQ); pingreq->setHeader(PINGREQ);
Event* evt = new Event(); Event* evt = new Event();
evt->setBrokerSendEvent(client, pingreq); evt->setBrokerSendEvent(client, pingreq);
_gateway->getBrokerSendQue()->post(evt); _gateway->getBrokerSendQue()->post(evt);
} }
} }
void MQTTSNConnectionHandler::sendStoredPublish(Client* client) void MQTTSNConnectionHandler::sendStoredPublish(Client* client)
{ {
MQTTGWPacket* msg = nullptr; 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. // ToDo: This version can't re-send PUBLISH when PUBACK is not returned.
client->deleteFirstClientSleepPacket(); // pop the que to delete element. client->deleteFirstClientSleepPacket(); // pop the que to delete element.
Event* ev = new Event(); Event* ev = new Event();
ev->setBrokerRecvEvent(client, msg); ev->setBrokerRecvEvent(client, msg);

View File

@@ -25,21 +25,21 @@ namespace MQTTSNGW
class MQTTSNConnectionHandler class MQTTSNConnectionHandler
{ {
public: public:
MQTTSNConnectionHandler(Gateway* gateway); MQTTSNConnectionHandler(Gateway* gateway);
~MQTTSNConnectionHandler(); ~MQTTSNConnectionHandler();
void sendADVERTISE(void); void sendADVERTISE(void);
void handleSearchgw(MQTTSNPacket* packet); void handleSearchgw(MQTTSNPacket* packet);
void handleConnect(Client* client, MQTTSNPacket* packet); void handleConnect(Client* client, MQTTSNPacket* packet);
void handleWilltopic(Client* client, MQTTSNPacket* packet); void handleWilltopic(Client* client, MQTTSNPacket* packet);
void handleWillmsg(Client* client, MQTTSNPacket* packet); void handleWillmsg(Client* client, MQTTSNPacket* packet);
void handleDisconnect(Client* client, MQTTSNPacket* packet); void handleDisconnect(Client* client, MQTTSNPacket* packet);
void handleWilltopicupd(Client* client, MQTTSNPacket* packet); void handleWilltopicupd(Client* client, MQTTSNPacket* packet);
void handleWillmsgupd(Client* client, MQTTSNPacket* packet); void handleWillmsgupd(Client* client, MQTTSNPacket* packet);
void handlePingreq(Client* client, MQTTSNPacket* packet); void handlePingreq(Client* client, MQTTSNPacket* packet);
private: private:
void sendStoredPublish(Client* client); void sendStoredPublish(Client* client);
Gateway* _gateway; Gateway* _gateway;
}; };
} }

View File

@@ -37,7 +37,7 @@ namespace MQTTSNGW
/*================================= /*=================================
* MQTT-SN Parametrs * 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_CLIENTID_LENGTH (64) // Max length of clientID
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages #define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
#define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size #define MAX_MESSAGEID_TABLE_SIZE (500) // Number of MessageIdTable size
@@ -53,21 +53,26 @@ namespace MQTTSNGW
/*================================= /*=================================
* Data Type * Data Type
==================================*/ ==================================*/
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef unsigned short uint16_t; typedef unsigned short uint16_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
/*================================= /*=================================
* Log controls * Log controls
==================================*/ ==================================*/
//#define DEBUG // print out log for debug //#define DEBUG_MQTTSN // print out log for debug
//#define DEBUG_NWSTACK // print out SensorNetwork log //#define DEBUG_NW // print out SensorNetwork log
#ifdef DEBUG_MQTTSN
#ifdef DEBUG
#define DEBUGLOG(...) printf(__VA_ARGS__) #define DEBUGLOG(...) printf(__VA_ARGS__)
#else #else
#define DEBUGLOG(...) #define DEBUGLOG(...)
#endif #endif
#ifdef DEBUG_NW
#define D_NWSTACK(...) printf(__VA_ARGS__)
#else
#define D_NWSTACK(...)
#endif
} }
#endif /* MQTTSNGWDEFINES_H_ */ #endif /* MQTTSNGWDEFINES_H_ */

View File

@@ -21,17 +21,15 @@
using namespace MQTTSNGW; using namespace MQTTSNGW;
using namespace std; using namespace std;
WirelessNodeId::WirelessNodeId() WirelessNodeId::WirelessNodeId() :
: _len { 0 }, _nodeId { 0 }
_len{0},
_nodeId{0}
{ {
} }
WirelessNodeId::~WirelessNodeId() WirelessNodeId::~WirelessNodeId()
{ {
if ( _nodeId ) if (_nodeId)
{ {
free(_nodeId); free(_nodeId);
} }
@@ -39,12 +37,12 @@ WirelessNodeId::~WirelessNodeId()
void WirelessNodeId::setId(uint8_t* id, uint8_t len) void WirelessNodeId::setId(uint8_t* id, uint8_t len)
{ {
if ( _nodeId ) if (_nodeId)
{ {
free(_nodeId); free(_nodeId);
} }
uint8_t* buf = (uint8_t*)malloc(len); uint8_t* buf = (uint8_t*) malloc(len);
if ( buf ) if (buf)
{ {
memcpy(buf, id, len); memcpy(buf, id, len);
_len = len; _len = len;
@@ -64,7 +62,7 @@ void WirelessNodeId::setId(WirelessNodeId* id)
bool WirelessNodeId::operator ==(WirelessNodeId& id) bool WirelessNodeId::operator ==(WirelessNodeId& id)
{ {
if ( _len == id._len ) if (_len == id._len)
{ {
return memcmp(_nodeId, id._nodeId, _len) == 0; return memcmp(_nodeId, id._nodeId, _len) == 0;
} }
@@ -77,16 +75,14 @@ bool WirelessNodeId::operator ==(WirelessNodeId& id)
/* /*
* Class MQTTSNGWEncapsulatedPacket * Class MQTTSNGWEncapsulatedPacket
*/ */
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket() :
: _mqttsn{0}, _mqttsn { 0 }, _ctrl { 0 }
_ctrl{0}
{ {
} }
MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) MQTTSNGWEncapsulatedPacket::MQTTSNGWEncapsulatedPacket(MQTTSNPacket* packet) :
: _mqttsn{packet}, _mqttsn { packet }, _ctrl { 0 }
_ctrl{0}
{ {
} }
@@ -109,18 +105,18 @@ int MQTTSNGWEncapsulatedPacket::serialize(uint8_t* buf)
buf[0] = _id._len + 3; buf[0] = _id._len + 3;
buf[1] = MQTTSN_ENCAPSULATED; buf[1] = MQTTSN_ENCAPSULATED;
buf[2] = _ctrl; buf[2] = _ctrl;
memcpy( buf + 3, _id._nodeId, _id._len); memcpy(buf + 3, _id._nodeId, _id._len);
if ( _mqttsn ) if (_mqttsn)
{ {
len = _mqttsn->getPacketLength(); len = _mqttsn->getPacketLength();
memcpy(buf + buf[0], _mqttsn->getPacketData(), len); memcpy(buf + buf[0], _mqttsn->getPacketData(), len);
} }
return buf[0] + len; return buf[0] + len;
} }
int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, unsigned short len) int MQTTSNGWEncapsulatedPacket::desirialize(unsigned char* buf, unsigned short len)
{ {
if ( _mqttsn ) if (_mqttsn)
{ {
delete _mqttsn; delete _mqttsn;
_mqttsn = nullptr; _mqttsn = nullptr;

View File

@@ -60,6 +60,4 @@ private:
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */

View File

@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
using namespace std; using namespace std;
/*===================================== /*=====================================
Class ForwarderList Class ForwarderList
=====================================*/ =====================================*/
ForwarderList::ForwarderList() ForwarderList::ForwarderList()
@@ -32,10 +32,10 @@ ForwarderList::ForwarderList()
ForwarderList::~ForwarderList() ForwarderList::~ForwarderList()
{ {
if ( _head ) if (_head)
{ {
Forwarder* p = _head; Forwarder* p = _head;
while ( p ) while (p)
{ {
Forwarder* next = p->_next; Forwarder* next = p->_next;
delete p; delete p;
@@ -44,20 +44,18 @@ ForwarderList::~ForwarderList()
} }
} }
void ForwarderList::initialize(Gateway* gw) void ForwarderList::initialize(Gateway* gw)
{ {
/* Create Fowarders from clients.conf */ /* Create Fowarders from clients.conf */
gw->getClientList()->setClientList(FORWARDER_TYPE); gw->getClientList()->setClientList(FORWARDER_TYPE);
} }
Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr) Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
{ {
Forwarder* p = _head; Forwarder* p = _head;
while ( p ) while (p)
{ {
if ( p->_sensorNetAddr.isMatch(addr) ) if (p->_sensorNetAddr.isMatch(addr))
{ {
break; break;
} }
@@ -66,19 +64,19 @@ Forwarder* ForwarderList::getForwarder(SensorNetAddress* addr)
return p; return p;
} }
Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId) Forwarder* ForwarderList::addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
{ {
Forwarder* fdr = new Forwarder(addr, forwarderId); Forwarder* fdr = new Forwarder(addr, forwarderId);
if ( _head == nullptr ) if (_head == nullptr)
{ {
_head = fdr; _head = fdr;
} }
else else
{ {
Forwarder* p = _head; Forwarder* p = _head;
while ( p ) while (p)
{ {
if ( p->_next == nullptr ) if (p->_next == nullptr)
{ {
p->_next = fdr; p->_next = fdr;
break; break;
@@ -99,10 +97,10 @@ Forwarder::Forwarder()
} }
/*===================================== /*=====================================
Class ForwarderList Class ForwarderList
=====================================*/ =====================================*/
Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId) Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
{ {
_forwarderName = string(forwarderId->cstring); _forwarderName = string(forwarderId->cstring);
_sensorNetAddr = *addr; _sensorNetAddr = *addr;
@@ -112,10 +110,10 @@ Forwarder::Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId)
Forwarder::~Forwarder(void) Forwarder::~Forwarder(void)
{ {
if ( _headClient ) if (_headClient)
{ {
ForwarderElement* p = _headClient; ForwarderElement* p = _headClient;
while ( p ) while (p)
{ {
ForwarderElement* next = p->_next; ForwarderElement* next = p->_next;
delete p; delete p;
@@ -136,11 +134,11 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
client->setForwarder(this); client->setForwarder(this);
if ( p != nullptr ) if (p != nullptr)
{ {
while ( p ) while (p)
{ {
if ( p->_client == client ) if (p->_client == client)
{ {
client->setForwarder(this); client->setForwarder(this);
p->setWirelessNodeId(id); p->setWirelessNodeId(id);
@@ -156,7 +154,7 @@ void Forwarder::addClient(Client* client, WirelessNodeId* id)
fclient->setClient(client); fclient->setClient(client);
fclient->setWirelessNodeId(id); fclient->setWirelessNodeId(id);
if ( prev ) if (prev)
{ {
prev->_next = fclient; prev->_next = fclient;
} }
@@ -171,9 +169,9 @@ Client* Forwarder::getClient(WirelessNodeId* id)
Client* cl = nullptr; Client* cl = nullptr;
_mutex.lock(); _mutex.lock();
ForwarderElement* p = _headClient; ForwarderElement* p = _headClient;
while ( p ) while (p)
{ {
if ( *(p->_wirelessNodeId) == *id ) if (*(p->_wirelessNodeId) == *id)
{ {
cl = p->_client; cl = p->_client;
break; break;
@@ -197,9 +195,9 @@ WirelessNodeId* Forwarder::getWirelessNodeId(Client* client)
WirelessNodeId* nodeId = nullptr; WirelessNodeId* nodeId = nullptr;
_mutex.lock(); _mutex.lock();
ForwarderElement* p = _headClient; ForwarderElement* p = _headClient;
while ( p ) while (p)
{ {
if ( p->_client == client ) if (p->_client == client)
{ {
nodeId = p->_wirelessNodeId; nodeId = p->_wirelessNodeId;
break; break;
@@ -219,11 +217,11 @@ void Forwarder::eraseClient(Client* client)
_mutex.lock(); _mutex.lock();
ForwarderElement* p = _headClient; ForwarderElement* p = _headClient;
while ( p ) while (p)
{ {
if ( p->_client == client ) if (p->_client == client)
{ {
if ( prev ) if (prev)
{ {
prev->_next = p->_next; prev->_next = p->_next;
} }
@@ -251,10 +249,8 @@ SensorNetAddress* Forwarder::getSensorNetAddr(void)
* Class ForwardedClient * Class ForwardedClient
*/ */
ForwarderElement::ForwarderElement() ForwarderElement::ForwarderElement() :
: _client{0} _client { 0 }, _wirelessNodeId { 0 }, _next { 0 }
, _wirelessNodeId{0}
, _next{0}
{ {
} }
@@ -273,7 +269,7 @@ void ForwarderElement::setClient(Client* client)
void ForwarderElement::setWirelessNodeId(WirelessNodeId* id) void ForwarderElement::setWirelessNodeId(WirelessNodeId* id)
{ {
if ( _wirelessNodeId == nullptr ) if (_wirelessNodeId == nullptr)
{ {
_wirelessNodeId = new WirelessNodeId(); _wirelessNodeId = new WirelessNodeId();
} }

View File

@@ -22,7 +22,6 @@
#include "MQTTSNGWEncapsulatedPacket.h" #include "MQTTSNGWEncapsulatedPacket.h"
#include "SensorNetwork.h" #include "SensorNetwork.h"
namespace MQTTSNGW namespace MQTTSNGW
{ {
class Gateway; class Gateway;
@@ -30,7 +29,7 @@ class Client;
class WirelessNodeId; class WirelessNodeId;
/*===================================== /*=====================================
Class ForwarderElement Class ForwarderElement
=====================================*/ =====================================*/
class ForwarderElement class ForwarderElement
{ {
@@ -48,14 +47,14 @@ private:
}; };
/*===================================== /*=====================================
Class Forwarder Class Forwarder
=====================================*/ =====================================*/
class Forwarder class Forwarder
{ {
friend class ForwarderList; friend class ForwarderList;
public: public:
Forwarder(void); Forwarder(void);
Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId); Forwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
~Forwarder(); ~Forwarder();
void initialize(void); void initialize(void);
@@ -70,13 +69,13 @@ public:
private: private:
string _forwarderName; string _forwarderName;
SensorNetAddress _sensorNetAddr; SensorNetAddress _sensorNetAddr;
ForwarderElement* _headClient{nullptr}; ForwarderElement* _headClient { nullptr };
Forwarder* _next {nullptr}; Forwarder* _next { nullptr };
Mutex _mutex; Mutex _mutex;
}; };
/*===================================== /*=====================================
Class ForwarderList Class ForwarderList
=====================================*/ =====================================*/
class ForwarderList class ForwarderList
{ {
@@ -86,7 +85,7 @@ public:
void initialize(Gateway* gw); void initialize(Gateway* gw);
Forwarder* getForwarder(SensorNetAddress* addr); Forwarder* getForwarder(SensorNetAddress* addr);
Forwarder* addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId); Forwarder* addForwarder(SensorNetAddress* addr, MQTTSNString* forwarderId);
private: private:
Forwarder* _head; Forwarder* _head;
@@ -94,6 +93,4 @@ private:
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */

View File

@@ -22,7 +22,7 @@ using namespace MQTTSNGW;
Logmonitor::Logmonitor() Logmonitor::Logmonitor()
{ {
theProcess = this; theProcess = this;
} }
Logmonitor::~Logmonitor() Logmonitor::~Logmonitor()
@@ -32,17 +32,17 @@ Logmonitor::~Logmonitor()
void Logmonitor::run() void Logmonitor::run()
{ {
while (true) while (true)
{ {
const char* data = getLog(); const char* data = getLog();
if ( *data == 0 ) if (*data == 0)
{ {
break; break;
} }
else else
{ {
printf("%s", data); printf("%s", data);
} }
} }
} }

View File

@@ -23,9 +23,9 @@ namespace MQTTSNGW
class Logmonitor: public Process class Logmonitor: public Process
{ {
public: public:
Logmonitor(); Logmonitor();
~Logmonitor(); ~Logmonitor();
void run(); void run();
}; };
} }

View File

@@ -29,187 +29,181 @@ MessageIdTable::MessageIdTable()
MessageIdTable::~MessageIdTable() MessageIdTable::~MessageIdTable()
{ {
_mutex.lock(); _mutex.lock();
if ( _head != nullptr ) if (_head != nullptr)
{ {
MessageIdElement* p = _tail; MessageIdElement* p = _tail;
while ( p ) while (p)
{ {
MessageIdElement* pPrev = p; MessageIdElement* pPrev = p;
delete p; delete p;
_cnt--; _cnt--;
p = pPrev->_prev; p = pPrev->_prev;
} }
_head = _tail = nullptr; _head = _tail = nullptr;
} }
_mutex.unlock(); _mutex.unlock();
} }
MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId) MessageIdElement* MessageIdTable::add(Aggregater* aggregater, Client* client, uint16_t clientMsgId)
{ {
if ( _cnt > _maxSize ) if (_cnt > _maxSize)
{ {
return nullptr; return nullptr;
} }
MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId); MessageIdElement* elm = new MessageIdElement(0, client, clientMsgId);
if ( elm == nullptr ) if (elm == nullptr)
{ {
return nullptr; return nullptr;
} }
_mutex.lock(); _mutex.lock();
if ( _head == nullptr ) if (_head == nullptr)
{ {
elm->_msgId = aggregater->msgId(); elm->_msgId = aggregater->msgId();
_head = elm; _head = elm;
_tail = elm; _tail = elm;
_cnt++; _cnt++;
} }
else else
{ {
MessageIdElement* p = find(client, clientMsgId); MessageIdElement* p = find(client, clientMsgId);
if ( p == nullptr ) if (p == nullptr)
{ {
elm->_msgId = aggregater->msgId(); elm->_msgId = aggregater->msgId();
p = _tail; p = _tail;
_tail = elm; _tail = elm;
elm->_prev = p; elm->_prev = p;
p->_next = elm; p->_next = elm;
_cnt++; _cnt++;
} }
else else
{ {
delete elm; delete elm;
elm = nullptr; elm = nullptr;
} }
} }
_mutex.unlock(); _mutex.unlock();
return elm; return elm;
} }
MessageIdElement* MessageIdTable::find(uint16_t msgId) MessageIdElement* MessageIdTable::find(uint16_t msgId)
{ {
MessageIdElement* p = _head; MessageIdElement* p = _head;
while ( p ) while (p)
{ {
if ( p->_msgId == msgId) if (p->_msgId == msgId)
{ {
break; break;
} }
p = p->_next; p = p->_next;
} }
return p; return p;
} }
MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId) MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
{ {
MessageIdElement* p = _head; MessageIdElement* p = _head;
while ( p ) while (p)
{ {
if ( p->_clientMsgId == clientMsgId && p->_client == client) if (p->_clientMsgId == clientMsgId && p->_client == client)
{ {
break; break;
} }
p = p->_next; p = p->_next;
} }
return p; return p;
} }
Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId) Client* MessageIdTable::getClientMsgId(uint16_t msgId, uint16_t* clientMsgId)
{ {
Client* clt = nullptr; Client* clt = nullptr;
*clientMsgId = 0; *clientMsgId = 0;
_mutex.lock(); _mutex.lock();
MessageIdElement* p = find(msgId); MessageIdElement* p = find(msgId);
if ( p != nullptr ) if (p != nullptr)
{ {
clt = p->_client; clt = p->_client;
*clientMsgId = p->_clientMsgId; *clientMsgId = p->_clientMsgId;
clear(p); clear(p);
} }
_mutex.unlock(); _mutex.unlock();
return clt; return clt;
} }
void MessageIdTable::erase(uint16_t msgId) void MessageIdTable::erase(uint16_t msgId)
{ {
_mutex.lock(); _mutex.lock();
MessageIdElement* p = find(msgId); MessageIdElement* p = find(msgId);
clear(p); clear(p);
_mutex.unlock(); _mutex.unlock();
} }
void MessageIdTable::clear(MessageIdElement* elm) void MessageIdTable::clear(MessageIdElement* elm)
{ {
if ( elm == nullptr ) if (elm == nullptr)
{ {
return; return;
} }
if ( elm->_prev == nullptr ) if (elm->_prev == nullptr)
{ {
_head = elm->_next; _head = elm->_next;
if ( _head == nullptr) if (_head == nullptr)
{ {
_tail = nullptr; _tail = nullptr;
} }
else else
{ {
_head->_prev = nullptr; _head->_prev = nullptr;
} }
delete elm; delete elm;
_cnt--; _cnt--;
return; return;
} }
else else
{ {
elm->_prev->_next = elm->_next; elm->_prev->_next = elm->_next;
if ( elm->_next == nullptr ) if (elm->_next == nullptr)
{ {
_tail = elm->_prev; _tail = elm->_prev;
} }
else else
{ {
elm->_next->_prev = elm->_prev; elm->_next->_prev = elm->_prev;
} }
delete elm; delete elm;
_cnt--; _cnt--;
return; return;
} }
} }
uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId) uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
{ {
uint16_t msgId = 0; uint16_t msgId = 0;
MessageIdElement* p = find(client, clientMsgId); MessageIdElement* p = find(client, clientMsgId);
if ( p != nullptr ) if (p != nullptr)
{ {
msgId = p->_msgId; msgId = p->_msgId;
} }
return msgId; return msgId;
} }
/*=============================== /*===============================
* Class MessageIdElement * Class MessageIdElement
===============================*/ ===============================*/
MessageIdElement::MessageIdElement(void) MessageIdElement::MessageIdElement(void) :
: _msgId{0} _msgId { 0 }, _clientMsgId { 0 }, _client { nullptr }, _next { nullptr }, _prev { nullptr }
, _clientMsgId {0}
, _client {nullptr}
, _next {nullptr}
, _prev {nullptr}
{ {
} }
MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) MessageIdElement::MessageIdElement(uint16_t msgId, Client* client, uint16_t clientMsgId) :
: MessageIdElement() MessageIdElement()
{ {
_msgId = msgId; _msgId = msgId;
_client = client; _client = client;
_clientMsgId = clientMsgId; _clientMsgId = clientMsgId;
} }
MessageIdElement::~MessageIdElement(void) MessageIdElement::~MessageIdElement(void)

View File

@@ -34,22 +34,23 @@ class Aggregater;
class MessageIdTable class MessageIdTable
{ {
public: public:
MessageIdTable(); MessageIdTable();
~MessageIdTable(); ~MessageIdTable();
MessageIdElement* add(Aggregater* aggregater, Client* client, uint16_t clientMsgId); MessageIdElement* add(Aggregater* aggregater, Client* client,
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId); uint16_t clientMsgId);
uint16_t getMsgId(Client* client, uint16_t clientMsgId); Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
void erase(uint16_t msgId); uint16_t getMsgId(Client* client, uint16_t clientMsgId);
void clear(MessageIdElement* elm); void erase(uint16_t msgId);
void clear(MessageIdElement* elm);
private: private:
MessageIdElement* find(uint16_t msgId); MessageIdElement* find(uint16_t msgId);
MessageIdElement* find(Client* client, uint16_t clientMsgId); MessageIdElement* find(Client* client, uint16_t clientMsgId);
MessageIdElement* _head {nullptr}; MessageIdElement* _head { nullptr };
MessageIdElement* _tail {nullptr}; MessageIdElement* _tail{ nullptr };
int _cnt {0}; int _cnt { 0 };
int _maxSize {MAX_MESSAGEID_TABLE_SIZE}; int _maxSize { MAX_MESSAGEID_TABLE_SIZE };
Mutex _mutex; Mutex _mutex;
}; };
/*===================================== /*=====================================
@@ -67,12 +68,11 @@ public:
private: private:
uint16_t _msgId; uint16_t _msgId;
uint16_t _clientMsgId; uint16_t _clientMsgId;
Client* _client; Client* _client;
MessageIdElement* _next; MessageIdElement* _next;
MessageIdElement* _prev; MessageIdElement* _prev;
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */

View File

@@ -29,286 +29,278 @@ void writeInt(unsigned char** pptr, int msgId);
MQTTSNPacket::MQTTSNPacket(void) MQTTSNPacket::MQTTSNPacket(void)
{ {
_buf = nullptr; _buf = nullptr;
_bufLen = 0; _bufLen = 0;
} }
MQTTSNPacket::MQTTSNPacket(MQTTSNPacket& packet) MQTTSNPacket::MQTTSNPacket(MQTTSNPacket& packet)
{ {
_buf = (unsigned char*)malloc(packet._bufLen); _buf = (unsigned char*) malloc(packet._bufLen);
if (_buf) if (_buf)
{ {
_bufLen = packet._bufLen; _bufLen = packet._bufLen;
memcpy(_buf, packet._buf, _bufLen); memcpy(_buf, packet._buf, _bufLen);
} }
else else
{ {
_buf = nullptr; _buf = nullptr;
_bufLen = 0; _bufLen = 0;
} }
} }
MQTTSNPacket::~MQTTSNPacket() MQTTSNPacket::~MQTTSNPacket()
{ {
if (_buf) if (_buf)
{ {
free(_buf); free(_buf);
} }
} }
int MQTTSNPacket::unicast(SensorNetwork* network, SensorNetAddress* sendTo) int MQTTSNPacket::unicast(SensorNetwork* network, SensorNetAddress* sendTo)
{ {
return network->unicast(_buf, _bufLen, sendTo); return network->unicast(_buf, _bufLen, sendTo);
} }
int MQTTSNPacket::broadcast(SensorNetwork* network) int MQTTSNPacket::broadcast(SensorNetwork* network)
{ {
return network->broadcast(_buf, _bufLen); return network->broadcast(_buf, _bufLen);
} }
int MQTTSNPacket::serialize(uint8_t* buf) int MQTTSNPacket::serialize(uint8_t* buf)
{ {
buf = _buf; buf = _buf;
return _bufLen; return _bufLen;
} }
int MQTTSNPacket::desirialize(unsigned char* buf, unsigned short len) int MQTTSNPacket::desirialize(unsigned char* buf, unsigned short len)
{ {
if ( _buf ) if (_buf)
{ {
free(_buf); free(_buf);
} }
_buf = (unsigned char*)calloc(len, sizeof(unsigned char)); _buf = (unsigned char*) calloc(len, sizeof(unsigned char));
if ( _buf ) if (_buf)
{ {
memcpy(_buf, buf, len); memcpy(_buf, buf, len);
_bufLen = len; _bufLen = len;
} }
else else
{ {
_bufLen = 0; _bufLen = 0;
} }
return _bufLen; return _bufLen;
} }
int MQTTSNPacket::recv(SensorNetwork* network) int MQTTSNPacket::recv(SensorNetwork* network)
{ {
uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE]; uint8_t buf[MQTTSNGW_MAX_PACKET_SIZE];
int len = network->read((uint8_t*) buf, MQTTSNGW_MAX_PACKET_SIZE); int len = network->read((uint8_t*) buf, MQTTSNGW_MAX_PACKET_SIZE);
if (len > 1) if (len > 1)
{ {
len = desirialize(buf, len); len = desirialize(buf, len);
} }
else return len;
{
len = 0;
}
return len;
} }
int MQTTSNPacket::getType(void) int MQTTSNPacket::getType(void)
{ {
if ( _bufLen == 0 ) if (_bufLen == 0)
{ {
return 0; return 0;
} }
int value = 0; int value = 0;
int p = MQTTSNPacket_decode(_buf, _bufLen, &value); int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
return _buf[p]; return _buf[p];
} }
bool MQTTSNPacket::isQoSMinusPUBLISH(void) bool MQTTSNPacket::isQoSMinusPUBLISH(void)
{ {
if ( _bufLen == 0 ) if (_bufLen == 0)
{ {
return false;; return false;;
} }
int value = 0; int value = 0;
int p = MQTTSNPacket_decode(_buf, _bufLen, &value); 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) unsigned char* MQTTSNPacket::getPacketData(void)
{ {
return _buf; return _buf;
} }
int MQTTSNPacket::getPacketLength(void) int MQTTSNPacket::getPacketLength(void)
{ {
return _bufLen; return _bufLen;
} }
const char* MQTTSNPacket::getName() const char* MQTTSNPacket::getName()
{ {
return MQTTSNPacket_name(getType()); return MQTTSNPacket_name(getType());
} }
int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration) int MQTTSNPacket::setADVERTISE(uint8_t gatewayid, uint16_t duration)
{ {
unsigned char buf[5]; unsigned char buf[5];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, int len = MQTTSNSerialize_advertise(buf, buflen, (unsigned char) gatewayid, (unsigned short) duration);
(unsigned short) duration); return desirialize(buf, len);
return desirialize(buf, len);
} }
int MQTTSNPacket::setGWINFO(uint8_t gatewayId) int MQTTSNPacket::setGWINFO(uint8_t gatewayId)
{ {
unsigned char buf[3]; unsigned char buf[3];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, 0); int len = MQTTSNSerialize_gwinfo(buf, buflen, (unsigned char) gatewayId, 0, 0);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setConnect(void) int MQTTSNPacket::setConnect(void)
{ {
unsigned char buf[40]; unsigned char buf[40];
int buflen = sizeof(buf); int buflen = sizeof(buf);
MQTTSNPacket_connectData data; MQTTSNPacket_connectData data;
data.clientID.cstring = (char*)"client01"; data.clientID.cstring = (char*) "client01";
int len = MQTTSNSerialize_connect(buf, buflen, &data); int len = MQTTSNSerialize_connect(buf, buflen, &data);
return desirialize(buf, len); return desirialize(buf, len);
} }
bool MQTTSNPacket::isAccepted(void) 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) int MQTTSNPacket::setCONNACK(uint8_t returnCode)
{ {
unsigned char buf[3]; unsigned char buf[3];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_connack(buf, buflen, (int) returnCode); int len = MQTTSNSerialize_connack(buf, buflen, (int) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setWILLTOPICREQ(void) int MQTTSNPacket::setWILLTOPICREQ(void)
{ {
unsigned char buf[2]; unsigned char buf[2];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_willtopicreq(buf, buflen); int len = MQTTSNSerialize_willtopicreq(buf, buflen);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setWILLMSGREQ(void) int MQTTSNPacket::setWILLMSGREQ(void)
{ {
unsigned char buf[2]; unsigned char buf[2];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_willmsgreq(buf, buflen); int len = MQTTSNSerialize_willmsgreq(buf, buflen);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* topicName) int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* topicName)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, int len = MQTTSNSerialize_register(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, topicName);
topicName); return desirialize(buf, len);
return desirialize(buf, len);
} }
int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode) int MQTTSNPacket::setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
{ {
unsigned char buf[7]; unsigned char buf[7];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, int len = MQTTSNSerialize_regack(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
(unsigned char) returnCode); return desirialize(buf, len);
return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, int MQTTSNPacket::setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, MQTTSN_topicid topic, uint8_t* payload,
uint8_t* payload, uint16_t payloadlen) uint16_t payloadlen)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, int len = MQTTSNSerialize_publish(buf, buflen, (unsigned char) dup, qos, (unsigned char) retained, (unsigned short) msgId,
(unsigned short) msgId, topic, (unsigned char*) payload, (int) payloadlen); topic, (unsigned char*) payload, (int) payloadlen);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode) int MQTTSNPacket::setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode)
{ {
unsigned char buf[7]; unsigned char buf[7];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, int len = MQTTSNSerialize_puback(buf, buflen, (unsigned short) topicId, (unsigned short) msgId, (unsigned char) returnCode);
(unsigned char) returnCode); return desirialize(buf, len);
return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBREC(uint16_t msgId) int MQTTSNPacket::setPUBREC(uint16_t msgId)
{ {
unsigned char buf[4]; unsigned char buf[4];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_pubrec(buf, buflen, (unsigned short) msgId); int len = MQTTSNSerialize_pubrec(buf, buflen, (unsigned short) msgId);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBREL(uint16_t msgId) int MQTTSNPacket::setPUBREL(uint16_t msgId)
{ {
unsigned char buf[4]; unsigned char buf[4];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_pubrel(buf, buflen, (unsigned short) msgId); int len = MQTTSNSerialize_pubrel(buf, buflen, (unsigned short) msgId);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPUBCOMP(uint16_t msgId) int MQTTSNPacket::setPUBCOMP(uint16_t msgId)
{ {
unsigned char buf[4]; unsigned char buf[4];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_pubcomp(buf, buflen, (unsigned short) msgId); int len = MQTTSNSerialize_pubcomp(buf, buflen, (unsigned short) msgId);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode) int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t returnCode)
{ {
unsigned char buf[8]; unsigned char buf[8];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, int len = MQTTSNSerialize_suback(buf, buflen, qos, (unsigned short) topicId, (unsigned short) msgId,
(unsigned short) msgId, (unsigned char) returnCode); (unsigned char) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setUNSUBACK(uint16_t msgId) int MQTTSNPacket::setUNSUBACK(uint16_t msgId)
{ {
unsigned char buf[4]; unsigned char buf[4];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_unsuback(buf, buflen, (unsigned short) msgId); int len = MQTTSNSerialize_unsuback(buf, buflen, (unsigned short) msgId);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setPINGRESP(void) int MQTTSNPacket::setPINGRESP(void)
{ {
unsigned char buf[32]; unsigned char buf[32];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_pingresp(buf, buflen); int len = MQTTSNSerialize_pingresp(buf, buflen);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setDISCONNECT(uint16_t duration) int MQTTSNPacket::setDISCONNECT(uint16_t duration)
{ {
unsigned char buf[4]; unsigned char buf[4];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_disconnect(buf, buflen, (int) duration); int len = MQTTSNSerialize_disconnect(buf, buflen, (int) duration);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setWILLTOPICRESP(uint8_t returnCode) int MQTTSNPacket::setWILLTOPICRESP(uint8_t returnCode)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_willtopicresp(buf, buflen, (int) returnCode); int len = MQTTSNSerialize_willtopicresp(buf, buflen, (int) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setWILLMSGRESP(uint8_t returnCode) int MQTTSNPacket::setWILLMSGRESP(uint8_t returnCode)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_willmsgresp(buf, buflen, (int) returnCode); int len = MQTTSNSerialize_willmsgresp(buf, buflen, (int) returnCode);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::setCONNECT(MQTTSNPacket_connectData* options) int MQTTSNPacket::setCONNECT(MQTTSNPacket_connectData* options)
@@ -323,262 +315,262 @@ int MQTTSNPacket::setPINGREQ(MQTTSNString* clientId)
{ {
unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE]; unsigned char buf[MQTTSNGW_MAX_PACKET_SIZE];
int buflen = sizeof(buf); int buflen = sizeof(buf);
int len = MQTTSNSerialize_pingreq( buf, buflen, *clientId); int len = MQTTSNSerialize_pingreq(buf, buflen, *clientId);
return desirialize(buf, len); return desirialize(buf, len);
} }
int MQTTSNPacket::getSERCHGW(uint8_t* radius) int MQTTSNPacket::getSERCHGW(uint8_t* radius)
{ {
return MQTTSNDeserialize_searchgw((unsigned char*) radius, (unsigned char*) _buf, _bufLen); return MQTTSNDeserialize_searchgw((unsigned char*) radius, (unsigned char*) _buf, _bufLen);
} }
int MQTTSNPacket::getCONNECT(MQTTSNPacket_connectData* data) int MQTTSNPacket::getCONNECT(MQTTSNPacket_connectData* data)
{ {
return MQTTSNDeserialize_connect(data, _buf, _bufLen); return MQTTSNDeserialize_connect(data, _buf, _bufLen);
} }
int MQTTSNPacket::getCONNACK(uint8_t* returnCode) int MQTTSNPacket::getCONNACK(uint8_t* returnCode)
{ {
return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode); return MQTTSNSerialize_connack(_buf, _bufLen, (int) *returnCode);
} }
int MQTTSNPacket::getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic) int MQTTSNPacket::getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
{ {
return MQTTSNDeserialize_willtopic((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen); return MQTTSNDeserialize_willtopic((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
} }
int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg) int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
{ {
return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen); return MQTTSNDeserialize_willmsg(willmsg, _buf, _bufLen);
} }
int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName) int MQTTSNPacket::getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName)
{ {
return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, return MQTTSNDeserialize_register((unsigned short*) topicId, (unsigned short*) msgId, topicName, _buf, _bufLen);
_buf, _bufLen);
} }
int MQTTSNPacket::getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode) 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, int MQTTSNPacket::getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSN_topicid* topic,
uint8_t** payload, int* payloadlen) uint8_t** payload, int* payloadlen)
{ {
return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, return MQTTSNDeserialize_publish((unsigned char*) dup, qos, (unsigned char*) retained, (unsigned short*) msgId, topic,
topic, (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen); (unsigned char**) payload, (int*) payloadlen, _buf, _bufLen);
} }
int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode) int MQTTSNPacket::getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode)
{ {
return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, return MQTTSNDeserialize_puback((unsigned short*) topicId, (unsigned short*) msgId, (unsigned char*) returnCode, _buf,
_buf, _bufLen); _bufLen);
} }
int MQTTSNPacket::getACK(uint16_t* msgId) int MQTTSNPacket::getACK(uint16_t* msgId)
{ {
unsigned char type; unsigned char type;
return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen); return MQTTSNDeserialize_ack(&type, (unsigned short*) msgId, _buf, _bufLen);
} }
int MQTTSNPacket::getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter) int MQTTSNPacket::getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter)
{ {
return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, (unsigned short*) msgId, topicFilter, _buf, _bufLen); return MQTTSNDeserialize_subscribe((unsigned char*) dup, qos, (unsigned short*) msgId, topicFilter, _buf, _bufLen);
} }
int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter) int MQTTSNPacket::getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter)
{ {
return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, _buf, _bufLen); return MQTTSNDeserialize_unsubscribe((unsigned short*) msgId, topicFilter, _buf, _bufLen);
} }
int MQTTSNPacket::getPINGREQ(void) int MQTTSNPacket::getPINGREQ(void)
{ {
if (getType() == MQTTSN_PINGRESP && _bufLen > 2 ) if (getType() == MQTTSN_PINGRESP && _bufLen > 2)
{ {
return _bufLen - 2; return _bufLen - 2;
} }
return 0; return 0;
} }
int MQTTSNPacket::getDISCONNECT(uint16_t* duration) int MQTTSNPacket::getDISCONNECT(uint16_t* duration)
{ {
int dur = 0; int dur = 0;
int rc = MQTTSNDeserialize_disconnect(&dur, _buf, _bufLen); int rc = MQTTSNDeserialize_disconnect(&dur, _buf, _bufLen);
*duration = (uint16_t)dur; *duration = (uint16_t) dur;
return rc; return rc;
} }
int MQTTSNPacket::getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic) int MQTTSNPacket::getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic)
{ {
return MQTTSNDeserialize_willtopicupd((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen); return MQTTSNDeserialize_willtopicupd((int*) willQoS, (unsigned char*) willRetain, willTopic, _buf, _bufLen);
} }
int MQTTSNPacket::getWILLMSGUPD(MQTTSNString* willMsg) int MQTTSNPacket::getWILLMSGUPD(MQTTSNString* willMsg)
{ {
return MQTTSNDeserialize_willmsgupd(willMsg, _buf, _bufLen); return MQTTSNDeserialize_willmsgupd(willMsg, _buf, _bufLen);
} }
char* MQTTSNPacket::print(char* pbuf) char* MQTTSNPacket::print(char* pbuf)
{ {
char* ptr = pbuf; char* ptr = pbuf;
char** pptr = &pbuf; char** pptr = &pbuf;
int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen; int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
sprintf(*pptr, " %02X", *(_buf + i)); sprintf(*pptr, " %02X", *(_buf + i));
*pptr += 3; *pptr += 3;
} }
**pptr = 0; **pptr = 0;
return ptr; return ptr;
} }
char* MQTTSNPacket::getMsgId(char* pbuf) char* MQTTSNPacket::getMsgId(char* pbuf)
{ {
int value = 0; int value = 0;
int p = 0; int p = 0;
switch ( getType() ) switch (getType())
{ {
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); 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]); sprintf(pbuf, "+%02X%02X", _buf[p + 4], _buf[p + 5]);
} }
else else
{ {
sprintf(pbuf, " %02X%02X", _buf[p + 4], _buf[p + 5]); sprintf(pbuf, " %02X%02X", _buf[p + 4], _buf[p + 5]);
} }
break; break;
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
case MQTTSN_REGACK: case MQTTSN_REGACK:
sprintf(pbuf, " %02X%02X", _buf[4], _buf[5]); sprintf(pbuf, " %02X%02X", _buf[4], _buf[5]);
break; break;
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
case MQTTSN_UNSUBACK: case MQTTSN_UNSUBACK:
sprintf(pbuf, " %02X%02X", _buf[2], _buf[3]); sprintf(pbuf, " %02X%02X", _buf[2], _buf[3]);
break; break;
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); p = MQTTSNPacket_decode(_buf, _bufLen, &value);
sprintf(pbuf, " %02X%02X", _buf[p + 2], _buf[p + 3]); sprintf(pbuf, " %02X%02X", _buf[p + 2], _buf[p + 3]);
break; break;
case MQTTSN_SUBACK: case MQTTSN_SUBACK:
sprintf(pbuf, " %02X%02X", _buf[5], _buf[6]); sprintf(pbuf, " %02X%02X", _buf[5], _buf[6]);
break; break;
default: default:
sprintf(pbuf, " "); sprintf(pbuf, " ");
break; break;
} }
if ( strcmp(pbuf, " 0000") == 0 ) if (strcmp(pbuf, " 0000") == 0)
{ {
sprintf(pbuf, " "); sprintf(pbuf, " ");
} }
return pbuf; return pbuf;
} }
int MQTTSNPacket::getMsgId(void) int MQTTSNPacket::getMsgId(void)
{ {
int value = 0; int value = 0;
int p = 0; int p = 0;
int msgId = 0; int msgId = 0;
char* ptr = 0; char* ptr = 0;
switch ( getType() ) switch (getType())
{ {
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); p = MQTTSNPacket_decode(_buf, _bufLen, &value);
ptr = (char*)_buf + p + 4; ptr = (char*) _buf + p + 4;
msgId = readInt((char**)&ptr); msgId = readInt((char**) &ptr);
break; break;
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
case MQTTSN_REGACK: case MQTTSN_REGACK:
ptr = (char*)_buf + 4; ptr = (char*) _buf + 4;
msgId = readInt((char**)&ptr); msgId = readInt((char**) &ptr);
break; break;
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
case MQTTSN_UNSUBACK: case MQTTSN_UNSUBACK:
ptr = (char*)_buf + 2; ptr = (char*) _buf + 2;
msgId = readInt((char**)&ptr); msgId = readInt((char**) &ptr);
break; break;
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); p = MQTTSNPacket_decode(_buf, _bufLen, &value);
ptr = (char*)_buf + p + 2; ptr = (char*) _buf + p + 2;
msgId = readInt((char**)&ptr); msgId = readInt((char**) &ptr);
break; break;
case MQTTSN_SUBACK: case MQTTSN_SUBACK:
ptr = (char*)_buf + 5; ptr = (char*) _buf + 5;
msgId = readInt((char**)&ptr); msgId = readInt((char**) &ptr);
break; break;
default: default:
break; break;
} }
return msgId; return msgId;
} }
void MQTTSNPacket::setMsgId(uint16_t msgId) void MQTTSNPacket::setMsgId(uint16_t msgId)
{ {
int value = 0; int value = 0;
int p = 0; int p = 0;
//unsigned char* ptr = 0; //unsigned char* ptr = 0;
switch ( getType() ) switch (getType())
{ {
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); p = MQTTSNPacket_decode(_buf, _bufLen, &value);
_buf[p + 4] = (unsigned char)(msgId / 256); _buf[p + 4] = (unsigned char) (msgId / 256);
_buf[p + 5] = (unsigned char)(msgId % 256); _buf[p + 5] = (unsigned char) (msgId % 256);
//ptr = _buf + p + 4; //ptr = _buf + p + 4;
//writeInt(&ptr, msgId); //writeInt(&ptr, msgId);
break; break;
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
case MQTTSN_REGACK: case MQTTSN_REGACK:
_buf[4] = (unsigned char)(msgId / 256); _buf[4] = (unsigned char) (msgId / 256);
_buf[5] = (unsigned char)(msgId % 256); _buf[5] = (unsigned char) (msgId % 256);
//ptr = _buf + 4; //ptr = _buf + 4;
//writeInt(&ptr, msgId); //writeInt(&ptr, msgId);
break; break;
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
case MQTTSN_UNSUBACK: case MQTTSN_UNSUBACK:
_buf[2] = (unsigned char)(msgId / 256); _buf[2] = (unsigned char) (msgId / 256);
_buf[3] = (unsigned char)(msgId % 256); _buf[3] = (unsigned char) (msgId % 256);
//ptr = _buf + 2; //ptr = _buf + 2;
//writeInt(&ptr, msgId); //writeInt(&ptr, msgId);
break; break;
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
p = MQTTSNPacket_decode(_buf, _bufLen, &value); p = MQTTSNPacket_decode(_buf, _bufLen, &value);
_buf[p + 2] = (unsigned char)(msgId / 256); _buf[p + 2] = (unsigned char) (msgId / 256);
_buf[p + 3] = (unsigned char)(msgId % 256); _buf[p + 3] = (unsigned char) (msgId % 256);
//ptr = _buf + p + 2; //ptr = _buf + p + 2;
//writeInt(&ptr, msgId); //writeInt(&ptr, msgId);
break; break;
case MQTTSN_SUBACK: case MQTTSN_SUBACK:
_buf[5] = (unsigned char)(msgId / 256); _buf[5] = (unsigned char) (msgId / 256);
_buf[6] = (unsigned char)(msgId % 256); _buf[6] = (unsigned char) (msgId % 256);
//ptr = _buf + 5; //ptr = _buf + 5;
//writeInt(&ptr, msgId); //writeInt(&ptr, msgId);
break; break;
default: default:
break; break;
} }
} }
bool MQTTSNPacket::isDuplicate(void) bool MQTTSNPacket::isDuplicate(void)
{ {
int value = 0; int value = 0;
int p = MQTTSNPacket_decode(_buf, _bufLen, &value); int p = MQTTSNPacket_decode(_buf, _bufLen, &value);
return ( _buf[p + 1] & 0x80 ); return (_buf[p + 1] & 0x80);
} }

View File

@@ -22,76 +22,82 @@
namespace MQTTSNGW namespace MQTTSNGW
{ {
class SensorNetwork;
class MQTTSNPacket class MQTTSNPacket
{ {
public: public:
MQTTSNPacket(void); MQTTSNPacket(void);
MQTTSNPacket(MQTTSNPacket &packet); MQTTSNPacket(MQTTSNPacket &packet);
~MQTTSNPacket(void); ~MQTTSNPacket(void);
int unicast(SensorNetwork* network, SensorNetAddress* sendTo); int unicast(SensorNetwork* network, SensorNetAddress* sendTo);
int broadcast(SensorNetwork* network); int broadcast(SensorNetwork* network);
int recv(SensorNetwork* network); int recv(SensorNetwork* network);
int serialize(uint8_t* buf); int serialize(uint8_t* buf);
int desirialize(unsigned char* buf, unsigned short len); int desirialize(unsigned char* buf, unsigned short len);
int getType(void); int getType(void);
unsigned char* getPacketData(void); unsigned char* getPacketData(void);
int getPacketLength(void); int getPacketLength(void);
const char* getName(); const char* getName();
int setConnect(void); // Debug int setConnect(void); // Debug
int setADVERTISE(uint8_t gatewayid, uint16_t duration); int setADVERTISE(uint8_t gatewayid, uint16_t duration);
int setGWINFO(uint8_t gatewayId); int setGWINFO(uint8_t gatewayId);
int setCONNACK(uint8_t returnCode); int setCONNACK(uint8_t returnCode);
int setWILLTOPICREQ(void); int setWILLTOPICREQ(void);
int setWILLMSGREQ(void); int setWILLMSGREQ(void);
int setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* TopicName); int setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* TopicName);
int setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode); int setREGACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
int setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId, int setPUBLISH(uint8_t dup, int qos, uint8_t retained, uint16_t msgId,
MQTTSN_topicid topic, uint8_t* payload, uint16_t payloadlen); MQTTSN_topicid topic, uint8_t* payload, uint16_t payloadlen);
int setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode); int setPUBACK(uint16_t topicId, uint16_t msgId, uint8_t returnCode);
int setPUBREC(uint16_t msgId); int setPUBREC(uint16_t msgId);
int setPUBREL(uint16_t msgId); int setPUBREL(uint16_t msgId);
int setPUBCOMP(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,
int setUNSUBACK(uint16_t msgId); uint8_t returnCode);
int setPINGRESP(void); int setUNSUBACK(uint16_t msgId);
int setDISCONNECT(uint16_t duration); int setPINGRESP(void);
int setWILLTOPICRESP(uint8_t returnCode); int setDISCONNECT(uint16_t duration);
int setWILLMSGRESP(uint8_t returnCode); int setWILLTOPICRESP(uint8_t returnCode);
int setWILLMSGRESP(uint8_t returnCode);
int setCONNECT(MQTTSNPacket_connectData* options); int setCONNECT(MQTTSNPacket_connectData* options);
int setPINGREQ(MQTTSNString* clientId); int setPINGREQ(MQTTSNString* clientId);
int getSERCHGW(uint8_t* radius); int getSERCHGW(uint8_t* radius);
int getCONNECT(MQTTSNPacket_connectData* option); int getCONNECT(MQTTSNPacket_connectData* option);
int getCONNACK(uint8_t* returnCode); int getCONNACK(uint8_t* returnCode);
int getWILLTOPIC(int* willQoS, uint8_t* willRetain, MQTTSNString* willTopic); int getWILLTOPIC(int* willQoS, uint8_t* willRetain,
int getWILLMSG(MQTTSNString* willmsg); MQTTSNString* willTopic);
int getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName); int getWILLMSG(MQTTSNString* willmsg);
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode); int getREGISTER(uint16_t* topicId, uint16_t* msgId,
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId, MQTTSNString* topicName);
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen); int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode); int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
int getACK(uint16_t* msgId); MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter); int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter); int getACK(uint16_t* msgId);
int getPINGREQ(void); int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId,
int getDISCONNECT(uint16_t* duration); MQTTSN_topicid* topicFilter);
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic); int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
int getWILLMSGUPD(MQTTSNString* willMsg); int getPINGREQ(void);
int getDISCONNECT(uint16_t* duration);
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain,
MQTTSNString* willTopic);
int getWILLMSGUPD(MQTTSNString* willMsg);
bool isAccepted(void); bool isAccepted(void);
bool isDuplicate(void); bool isDuplicate(void);
bool isQoSMinusPUBLISH(void); bool isQoSMinusPUBLISH(void);
char* getMsgId(char* buf); char* getMsgId(char* buf);
int getMsgId(void); int getMsgId(void);
void setMsgId(uint16_t msgId); void setMsgId(uint16_t msgId);
char* print(char* buf); char* print(char* buf);
private: private:
unsigned char* _buf; // Ptr to a packet data unsigned char* _buf; // Ptr to a packet data
int _bufLen; // length of the packet data int _bufLen; // length of the packet data
}; };
} }

View File

@@ -38,22 +38,24 @@ using namespace MQTTSNGW;
#define EVENT_QUE_TIME_OUT 2000 // 2000 msecs #define EVENT_QUE_TIME_OUT 2000 // 2000 msecs
char* currentDateTime(void); char* currentDateTime(void);
/*===================================== /*=====================================
Class PacketHandleTask Class PacketHandleTask
=====================================*/ =====================================*/
PacketHandleTask::PacketHandleTask(Gateway* gateway) PacketHandleTask::PacketHandleTask(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
_gateway->attach((Thread*)this); _gateway->attach((Thread*) this);
_mqttConnection = new MQTTGWConnectionHandler(_gateway); _mqttConnection = new MQTTGWConnectionHandler(_gateway);
_mqttPublish = new MQTTGWPublishHandler(_gateway); _mqttPublish = new MQTTGWPublishHandler(_gateway);
_mqttSubscribe = new MQTTGWSubscribeHandler(_gateway); _mqttSubscribe = new MQTTGWSubscribeHandler(_gateway);
_mqttsnConnection = new MQTTSNConnectionHandler(_gateway); _mqttsnConnection = new MQTTSNConnectionHandler(_gateway);
_mqttsnPublish = new MQTTSNPublishHandler(_gateway); _mqttsnPublish = new MQTTSNPublishHandler(_gateway);
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway); _mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway); _mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
setTaskName("PacketHandleTask");
} }
/** /**
@@ -61,315 +63,309 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
*/ */
PacketHandleTask::~PacketHandleTask() PacketHandleTask::~PacketHandleTask()
{ {
if ( _mqttConnection ) if (_mqttConnection)
{ {
delete _mqttConnection; delete _mqttConnection;
} }
if ( _mqttPublish ) if (_mqttPublish)
{ {
delete _mqttPublish; delete _mqttPublish;
} }
if ( _mqttSubscribe ) if (_mqttSubscribe)
{ {
delete _mqttSubscribe; delete _mqttSubscribe;
} }
if ( _mqttsnConnection ) if (_mqttsnConnection)
{ {
delete _mqttsnConnection; delete _mqttsnConnection;
} }
if ( _mqttsnPublish ) if (_mqttsnPublish)
{ {
delete _mqttsnPublish; delete _mqttsnPublish;
} }
if ( _mqttsnSubscribe ) if (_mqttsnSubscribe)
{ {
delete _mqttsnSubscribe; delete _mqttsnSubscribe;
} }
if ( _mqttsnAggrConnection ) if (_mqttsnAggrConnection)
{ {
delete _mqttsnAggrConnection; delete _mqttsnAggrConnection;
} }
} }
void PacketHandleTask::run() void PacketHandleTask::run()
{ {
Event* ev = nullptr; Event* ev = nullptr;
EventQue* eventQue = _gateway->getPacketEventQue(); EventQue* eventQue = _gateway->getPacketEventQue();
AdapterManager* adpMgr = _gateway->getAdapterManager(); AdapterManager* adpMgr = _gateway->getAdapterManager();
Client* client = nullptr; Client* client = nullptr;
MQTTSNPacket* snPacket = nullptr; MQTTSNPacket* snPacket = nullptr;
MQTTGWPacket* brPacket = nullptr; MQTTGWPacket* brPacket = nullptr;
char msgId[6]; char msgId[6];
memset(msgId, 0, 6); memset(msgId, 0, 6);
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL); _advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
while (true) while (true)
{ {
/* wait Event */ /* wait Event */
ev = eventQue->timedwait(EVENT_QUE_TIME_OUT); ev = eventQue->timedwait(EVENT_QUE_TIME_OUT);
if (ev->getEventType() == EtStop) if (ev->getEventType() == EtStop)
{ {
WRITELOG("\n%s PacketHandleTask stopped.", currentDateTime()); WRITELOG("%s %s stopped.\n", currentDateTime(), getTaskName());
delete ev; delete ev;
return; return;
} }
if (ev->getEventType() == EtTimeout) if (ev->getEventType() == EtTimeout)
{ {
/*------ Check Keep Alive Timer & send Advertise ------*/ /*------ Check Keep Alive Timer & send Advertise ------*/
if (_advertiseTimer.isTimeup()) if (_advertiseTimer.isTimeup())
{ {
_mqttsnConnection->sendADVERTISE(); _mqttsnConnection->sendADVERTISE();
_advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL); _advertiseTimer.start(_gateway->getGWParams()->keepAlive * 1000UL);
} }
/*------ Check Adapters Connect or PINGREQ ------*/ /*------ Check Adapters Connect or PINGREQ ------*/
adpMgr->checkConnection(); adpMgr->checkConnection();
} }
/*------ Handle SEARCHGW Message ---------*/ /*------ Handle SEARCHGW Message ---------*/
else if (ev->getEventType() == EtBroadcast) else if (ev->getEventType() == EtBroadcast)
{ {
snPacket = ev->getMQTTSNPacket(); snPacket = ev->getMQTTSNPacket();
_mqttsnConnection->handleSearchgw(snPacket); _mqttsnConnection->handleSearchgw(snPacket);
} }
/*------ Handle Messages form Clients ---------*/ /*------ Handle Messages form Clients ---------*/
else if (ev->getEventType() == EtClientRecv) else if (ev->getEventType() == EtClientRecv)
{ {
client = ev->getClient(); client = ev->getClient();
snPacket = ev->getMQTTSNPacket(); snPacket = ev->getMQTTSNPacket();
DEBUGLOG(" PacketHandleTask gets %s %s from the client.\n", snPacket->getName(), snPacket->getMsgId(msgId)); 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 aggregatePacketHandler(client, snPacket); // client is converted to Aggregater by BrokerSendTask
} }
else else
{ {
transparentPacketHandler(client, snPacket); transparentPacketHandler(client, snPacket);
} }
/* Reset the Timer for PINGREQ. */
client->updateStatus(snPacket);
}
/*------ Handle Messages form Broker ---------*/
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));
/* Reset the Timer for PINGREQ. */ if (client->isAggregater())
client->updateStatus(snPacket); {
} aggregatePacketHandler(client, brPacket);
/*------ Handle Messages form Broker ---------*/ }
else if ( ev->getEventType() == EtBrokerRecv ) else
{ {
client = ev->getClient(); transparentPacketHandler(client, brPacket);
brPacket = ev->getMQTTGWPacket(); }
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId)); }
delete ev;
}
if ( client->isAggregater() )
{
aggregatePacketHandler(client, brPacket);
}
else
{
transparentPacketHandler(client, brPacket);
}
}
delete ev;
}
} }
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet) void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_CONNECT: case MQTTSN_CONNECT:
_mqttsnAggrConnection->handleConnect(client, packet); _mqttsnAggrConnection->handleConnect(client, packet);
break; break;
case MQTTSN_WILLTOPIC: case MQTTSN_WILLTOPIC:
_mqttsnConnection->handleWilltopic(client, packet); _mqttsnConnection->handleWilltopic(client, packet);
break; break;
case MQTTSN_WILLMSG: case MQTTSN_WILLMSG:
_mqttsnAggrConnection->handleWillmsg(client, packet); _mqttsnAggrConnection->handleWillmsg(client, packet);
break; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
_mqttsnAggrConnection->handleDisconnect(client, packet); _mqttsnAggrConnection->handleDisconnect(client, packet);
break; break;
case MQTTSN_WILLTOPICUPD: case MQTTSN_WILLTOPICUPD:
_mqttsnConnection->handleWilltopicupd(client, packet); _mqttsnConnection->handleWilltopicupd(client, packet);
break; break;
case MQTTSN_WILLMSGUPD: case MQTTSN_WILLMSGUPD:
_mqttsnConnection->handleWillmsgupd(client, packet); _mqttsnConnection->handleWillmsgupd(client, packet);
break; break;
case MQTTSN_PINGREQ: case MQTTSN_PINGREQ:
_mqttsnAggrConnection->handlePingreq(client, packet); _mqttsnAggrConnection->handlePingreq(client, packet);
break; break;
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
_mqttsnPublish->handleAggregatePublish(client, packet); _mqttsnPublish->handleAggregatePublish(client, packet);
break; break;
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBACK); _mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBACK);
break; break;
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREC); _mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREC);
break; break;
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREL); _mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBREL);
break; break;
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
_mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBCOMP); _mqttsnPublish->handleAggregateAck(client, packet, MQTTSN_PUBCOMP);
break; break;
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
_mqttsnPublish->handleRegister(client, packet); _mqttsnPublish->handleRegister(client, packet);
break; break;
case MQTTSN_REGACK: case MQTTSN_REGACK:
_mqttsnPublish->handleRegAck(client, packet); _mqttsnPublish->handleRegAck(client, packet);
break; break;
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
_mqttsnSubscribe->handleAggregateSubscribe(client, packet); _mqttsnSubscribe->handleAggregateSubscribe(client, packet);
break; break;
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
_mqttsnSubscribe->handleAggregateUnsubscribe(client, packet); _mqttsnSubscribe->handleAggregateUnsubscribe(client, packet);
break; break;
default: default:
break; break;
} }
} }
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet) void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case CONNACK: case CONNACK:
_mqttConnection->handleConnack(client, packet); _mqttConnection->handleConnack(client, packet);
break; break;
case PINGRESP: case PINGRESP:
_mqttConnection->handlePingresp(client, packet); _mqttConnection->handlePingresp(client, packet);
break; break;
case PUBLISH: case PUBLISH:
_mqttPublish->handleAggregatePublish(client, packet); _mqttPublish->handleAggregatePublish(client, packet);
break; break;
case PUBACK: case PUBACK:
_mqttPublish->handleAggregatePuback(client, packet); _mqttPublish->handleAggregatePuback(client, packet);
break; break;
case PUBREC: case PUBREC:
_mqttPublish->handleAggregateAck(client, packet, PUBREC); _mqttPublish->handleAggregateAck(client, packet, PUBREC);
break; break;
case PUBREL: case PUBREL:
_mqttPublish->handleAggregatePubrel(client, packet); _mqttPublish->handleAggregatePubrel(client, packet);
break; break;
case PUBCOMP: case PUBCOMP:
_mqttPublish->handleAggregateAck(client, packet, PUBCOMP); _mqttPublish->handleAggregateAck(client, packet, PUBCOMP);
break; break;
case SUBACK: case SUBACK:
_mqttSubscribe->handleAggregateSuback(client, packet); _mqttSubscribe->handleAggregateSuback(client, packet);
break; break;
case UNSUBACK: case UNSUBACK:
_mqttSubscribe->handleAggregateUnsuback(client, packet); _mqttSubscribe->handleAggregateUnsuback(client, packet);
break; break;
default: default:
break; break;
} }
} }
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* packet) void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case MQTTSN_CONNECT: case MQTTSN_CONNECT:
_mqttsnConnection->handleConnect(client, packet); _mqttsnConnection->handleConnect(client, packet);
break; break;
case MQTTSN_WILLTOPIC: case MQTTSN_WILLTOPIC:
_mqttsnConnection->handleWilltopic(client, packet); _mqttsnConnection->handleWilltopic(client, packet);
break; break;
case MQTTSN_WILLMSG: case MQTTSN_WILLMSG:
_mqttsnConnection->handleWillmsg(client, packet); _mqttsnConnection->handleWillmsg(client, packet);
break; break;
case MQTTSN_DISCONNECT: case MQTTSN_DISCONNECT:
_mqttsnConnection->handleDisconnect(client, packet); _mqttsnConnection->handleDisconnect(client, packet);
break; break;
case MQTTSN_WILLTOPICUPD: case MQTTSN_WILLTOPICUPD:
_mqttsnConnection->handleWilltopicupd(client, packet); _mqttsnConnection->handleWilltopicupd(client, packet);
break; break;
case MQTTSN_WILLMSGUPD: case MQTTSN_WILLMSGUPD:
_mqttsnConnection->handleWillmsgupd(client, packet); _mqttsnConnection->handleWillmsgupd(client, packet);
break; break;
case MQTTSN_PINGREQ: case MQTTSN_PINGREQ:
_mqttsnConnection->handlePingreq(client, packet); _mqttsnConnection->handlePingreq(client, packet);
break; break;
case MQTTSN_PUBLISH: case MQTTSN_PUBLISH:
_mqttsnPublish->handlePublish(client, packet); _mqttsnPublish->handlePublish(client, packet);
break; break;
case MQTTSN_PUBACK: case MQTTSN_PUBACK:
_mqttsnPublish->handlePuback(client, packet); _mqttsnPublish->handlePuback(client, packet);
break; break;
case MQTTSN_PUBREC: case MQTTSN_PUBREC:
_mqttsnPublish->handleAck(client, packet, PUBREC); _mqttsnPublish->handleAck(client, packet, PUBREC);
break; break;
case MQTTSN_PUBREL: case MQTTSN_PUBREL:
_mqttsnPublish->handleAck(client, packet, PUBREL); _mqttsnPublish->handleAck(client, packet, PUBREL);
break; break;
case MQTTSN_PUBCOMP: case MQTTSN_PUBCOMP:
_mqttsnPublish->handleAck(client, packet, PUBCOMP); _mqttsnPublish->handleAck(client, packet, PUBCOMP);
break; break;
case MQTTSN_REGISTER: case MQTTSN_REGISTER:
_mqttsnPublish->handleRegister(client, packet); _mqttsnPublish->handleRegister(client, packet);
break; break;
case MQTTSN_REGACK: case MQTTSN_REGACK:
_mqttsnPublish->handleRegAck(client, packet); _mqttsnPublish->handleRegAck(client, packet);
break; break;
case MQTTSN_SUBSCRIBE: case MQTTSN_SUBSCRIBE:
_mqttsnSubscribe->handleSubscribe(client, packet); _mqttsnSubscribe->handleSubscribe(client, packet);
break; break;
case MQTTSN_UNSUBSCRIBE: case MQTTSN_UNSUBSCRIBE:
_mqttsnSubscribe->handleUnsubscribe(client, packet); _mqttsnSubscribe->handleUnsubscribe(client, packet);
break; break;
default: default:
break; break;
} }
} }
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet) void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
{ {
switch (packet->getType()) switch (packet->getType())
{ {
case CONNACK: case CONNACK:
_mqttConnection->handleConnack(client, packet); _mqttConnection->handleConnack(client, packet);
break; break;
case PINGRESP: case PINGRESP:
_mqttConnection->handlePingresp(client, packet); _mqttConnection->handlePingresp(client, packet);
break; break;
case PUBLISH: case PUBLISH:
_mqttPublish->handlePublish(client, packet); _mqttPublish->handlePublish(client, packet);
break; break;
case PUBACK: case PUBACK:
_mqttPublish->handlePuback(client, packet); _mqttPublish->handlePuback(client, packet);
break; break;
case PUBREC: case PUBREC:
_mqttPublish->handleAck(client, packet, PUBREC); _mqttPublish->handleAck(client, packet, PUBREC);
break; break;
case PUBREL: case PUBREL:
_mqttPublish->handleAck(client, packet, PUBREL); _mqttPublish->handleAck(client, packet, PUBREL);
break; break;
case PUBCOMP: case PUBCOMP:
_mqttPublish->handleAck(client, packet, PUBCOMP); _mqttPublish->handleAck(client, packet, PUBCOMP);
break; break;
case SUBACK: case SUBACK:
_mqttSubscribe->handleSuback(client, packet); _mqttSubscribe->handleSuback(client, packet);
break; break;
case UNSUBACK: case UNSUBACK:
_mqttSubscribe->handleUnsuback(client, packet); _mqttSubscribe->handleUnsuback(client, packet);
break; break;
case DISCONNECT: case DISCONNECT:
client->disconnected(); // Just change Client's status to "Disconnected" client->disconnected(); // Just change Client's status to "Disconnected"
break; break;
default: default:
break; break;
} }
} }

View File

@@ -40,40 +40,39 @@ class MQTTSNAggregateConnectionHandler;
class Thread; class Thread;
class Timer; class Timer;
/*===================================== /*=====================================
Class PacketHandleTask Class PacketHandleTask
=====================================*/ =====================================*/
class PacketHandleTask : public Thread class PacketHandleTask: public Thread
{ {
MAGIC_WORD_FOR_THREAD; MAGIC_WORD_FOR_THREAD;
friend class MQTTGWAggregatePublishHandler; friend class MQTTGWAggregatePublishHandler;
friend class MQTTGWAggregateSubscribeHandler; friend class MQTTGWAggregateSubscribeHandler;
friend class MQTTSNAggregateConnectionHandler; friend class MQTTSNAggregateConnectionHandler;
friend class MQTTSNAggregatePublishHandler; friend class MQTTSNAggregatePublishHandler;
friend class MQTTSNAggregateSubscribeHandler; friend class MQTTSNAggregateSubscribeHandler;
public: public:
PacketHandleTask(Gateway* gateway); PacketHandleTask(Gateway* gateway);
~PacketHandleTask(); ~PacketHandleTask();
void run(); void run();
private: private:
void aggregatePacketHandler(Client*client, MQTTSNPacket* packet); void aggregatePacketHandler(Client*client, MQTTSNPacket* packet);
void aggregatePacketHandler(Client*client, MQTTGWPacket* packet); void aggregatePacketHandler(Client*client, MQTTGWPacket* packet);
void transparentPacketHandler(Client*client, MQTTSNPacket* packet); void transparentPacketHandler(Client*client, MQTTSNPacket* packet);
void transparentPacketHandler(Client*client, MQTTGWPacket* packet); void transparentPacketHandler(Client*client, MQTTGWPacket* packet);
Gateway* _gateway {nullptr}; Gateway* _gateway
Timer _advertiseTimer; { nullptr };
Timer _sendUnixTimer; Timer _advertiseTimer;
MQTTGWConnectionHandler* _mqttConnection {nullptr}; Timer _sendUnixTimer;
MQTTGWPublishHandler* _mqttPublish {nullptr}; MQTTGWConnectionHandler* _mqttConnection { nullptr };
MQTTGWSubscribeHandler* _mqttSubscribe {nullptr}; MQTTGWPublishHandler* _mqttPublish { nullptr };
MQTTSNConnectionHandler* _mqttsnConnection {nullptr}; MQTTGWSubscribeHandler* _mqttSubscribe { nullptr };
MQTTSNPublishHandler* _mqttsnPublish {nullptr}; MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
MQTTSNSubscribeHandler* _mqttsnSubscribe {nullptr}; MQTTSNPublishHandler* _mqttsnPublish { nullptr };
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection {nullptr}; MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
}; };
} }
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */ #endif /* MQTTSNGWPACKETHANDLETASK_H_ */

View File

@@ -13,10 +13,10 @@
* Contributors: * Contributors:
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation * Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
**************************************************************************************/ **************************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
#include <stdarg.h> #include <stdarg.h>
#include <signal.h> #include <signal.h>
#include <Timer.h> #include <Timer.h>
@@ -44,7 +44,7 @@ volatile int theSignaled = 0;
static void signalHandler(int sig) static void signalHandler(int sig)
{ {
theSignaled = sig; theSignaled = sig;
} }
/*===================================== /*=====================================
@@ -52,23 +52,25 @@ static void signalHandler(int sig)
====================================*/ ====================================*/
Process::Process() Process::Process()
{ {
_argc = 0; _argc = 0;
_argv = 0; _argv = 0;
_configDir = CONFIG_DIRECTORY; _configDir = CONFIG_DIRECTORY;
_configFile = CONFIG_FILE; _configFile = CONFIG_FILE;
_log = 0; _log = 0;
_rbsem = NULL;
_rb = NULL;
} }
Process::~Process() Process::~Process()
{ {
if (_rb ) if (_rb)
{ {
delete _rb; delete _rb;
} }
if ( _rbsem ) if (_rbsem)
{ {
delete _rbsem; delete _rbsem;
} }
} }
void Process::run() void Process::run()
@@ -78,168 +80,185 @@ void Process::run()
void Process::initialize(int argc, char** argv) void Process::initialize(int argc, char** argv)
{ {
char param[MQTTSNGW_PARAM_MAX]; char param[MQTTSNGW_PARAM_MAX];
_argc = argc; _argc = argc;
_argv = argv; _argv = argv;
signal(SIGINT, signalHandler); signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler); signal(SIGTERM, signalHandler);
signal(SIGHUP, signalHandler); signal(SIGHUP, signalHandler);
int opt; int opt;
while ((opt = getopt(_argc, _argv, "f:")) != -1) while ((opt = getopt(_argc, _argv, "f:")) != -1)
{ {
if ( opt == 'f' ) if (opt == 'f')
{ {
string config = string(optarg); string config = string(optarg);
size_t pos = 0; size_t pos = 0;
if ( (pos = config.find_last_of("/")) == string::npos ) if ((pos = config.find_last_of("/")) == string::npos)
{ {
_configFile = optarg; _configFile = optarg;
} }
else 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); _configDir = config.substr(0, pos + 1);
} }
} }
} }
_rbsem = new NamedSemaphore(MQTTSNGW_RB_SEMAPHOR_NAME, 0); _rbsem = new NamedSemaphore(MQTTSNGW_RB_SEMAPHOR_NAME, 0);
_rb = new RingBuffer(_configDir.c_str()); _rb = new RingBuffer(_configDir.c_str());
if (getParam("ShearedMemory", param) == 0) if (getParam("ShearedMemory", param) == 0)
{ {
if (!strcasecmp(param, "YES")) if (!strcasecmp(param, "YES"))
{ {
_log = 1; _log = 1;
} }
else else
{ {
_log = 0; _log = 0;
} }
} }
} }
void Process::putLog(const char* format, ...) void Process::putLog(const char* format, ...)
{ {
_mt.lock(); _mt.lock();
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
vsprintf(_rbdata, format, arg); vsprintf(_rbdata, format, arg);
va_end(arg); va_end(arg);
if (strlen(_rbdata)) if (strlen(_rbdata))
{ {
if ( _log > 0 ) if (_log > 0)
{ {
_rb->put(_rbdata); _rb->put(_rbdata);
_rbsem->post(); _rbsem->post();
} }
else else
{ {
printf("%s", _rbdata); printf("%s", _rbdata);
} }
} }
_mt.unlock(); _mt.unlock();
} }
int Process::getArgc() int Process::getArgc()
{ {
return _argc; return _argc;
} }
char** Process::getArgv() char** Process::getArgv()
{ {
return _argv; return _argv;
} }
int Process::getParam(const char* parameter, char* value) int Process::getParam(const char* parameter, char* value)
{ {
char str[MQTTSNGW_PARAM_MAX]; char str[MQTTSNGW_PARAM_MAX];
char param[MQTTSNGW_PARAM_MAX]; char param[MQTTSNGW_PARAM_MAX];
FILE *fp; memset(str, 0, sizeof(str));
memset(param, 0, sizeof(param));
FILE *fp;
int i = 0, j = 0; int i = 0, j = 0;
string configPath = _configDir + _configFile; string configPath = _configDir + _configFile;
if ((fp = fopen(configPath.c_str(), "r")) == NULL) 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);
} }
while (true) int paramlen = strlen(parameter);
{
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
{
fclose(fp);
return -3;
}
if (!strncmp(str, parameter, strlen(parameter)))
{
while (str[i++] != '=')
{
;
}
while (str[i] != '\n')
{
param[j++] = str[i++];
}
param[j] = '\0';
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--) while (true)
; {
param[i + 1] = '\0'; int pos = 0;
for (i = 0; isspace(param[i]); i++) int len = 0;
; if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
if (i > 0) {
{ fclose(fp);
j = 0; return -3;
while (param[i]) }
param[j++] = param[i++]; if (str[0] == '#' || str[0] == '\n')
param[j] = '\0'; {
} continue;
strcpy(value, param); }
fclose(fp);
return 0; len = strlen(str);
} for (pos = 0; i < len; pos++)
} {
fclose(fp); if (str[pos] == '=')
return -2; {
break;
}
}
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--)
;
param[i + 1] = '\0';
for (i = 0; isspace(param[i]); i++)
;
if (i > 0)
{
j = 0;
while (param[i])
param[j++] = param[i++];
param[j] = '\0';
}
strcpy(value, param);
fclose(fp);
return 0;
}
}
}
fclose(fp);
return -2;
} }
const char* Process::getLog() const char* Process::getLog()
{ {
int len = 0; int len = 0;
_mt.lock(); _mt.lock();
while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0) while ((len = _rb->get(_rbdata, PROCESS_LOG_BUFFER_SIZE)) == 0)
{ {
_rbsem->timedwait(1000); _rbsem->timedwait(1000);
if ( checkSignal() == SIGINT) if (checkSignal() == SIGINT)
{ {
break; break;
} }
} }
*(_rbdata + len) = 0; *(_rbdata + len) = 0;
_mt.unlock(); _mt.unlock();
return _rbdata; return _rbdata;
} }
void Process::resetRingBuffer() void Process::resetRingBuffer()
{ {
_rb->reset(); _rb->reset();
} }
int Process::checkSignal(void) int Process::checkSignal(void)
{ {
return theSignaled; return theSignaled;
} }
const string* Process::getConfigDirName(void) const string* Process::getConfigDirName(void)
{ {
return &_configDir; return &_configDir;
} }
const string* Process::getConfigFileName(void) const string* Process::getConfigFileName(void)
{ {
return &_configFile; return &_configFile;
} }
/*===================================== /*=====================================
@@ -247,130 +266,110 @@ const string* Process::getConfigFileName(void)
====================================*/ ====================================*/
MultiTaskProcess::MultiTaskProcess() MultiTaskProcess::MultiTaskProcess()
{ {
theMultiTaskProcess = this; theMultiTaskProcess = this;
_threadCount = 0; _threadCount = 0;
_stopCount = 0; _stopCount = 0;
} }
MultiTaskProcess::~MultiTaskProcess() MultiTaskProcess::~MultiTaskProcess()
{ {
for (int i = 0; i < _threadCount; i++) for (int i = 0; i < _threadCount; i++)
{ {
_threadList[i]->stop(); _threadList[i]->stop();
} }
} }
void MultiTaskProcess::initialize(int argc, char** argv) void MultiTaskProcess::initialize(int argc, char** argv)
{ {
Process::initialize(argc, argv); Process::initialize(argc, argv);
for (int i = 0; i < _threadCount; i++) for (int i = 0; i < _threadCount; i++)
{ {
_threadList[i]->initialize(argc, argv); _threadList[i]->initialize(argc, argv);
} }
} }
void MultiTaskProcess::run(void) void MultiTaskProcess::run(void)
{ {
for (int i = 0; i < _threadCount; i++) for (int i = 0; i < _threadCount; i++)
{ {
_threadList[i]->start(); _threadList[i]->start();
} }
try while (true)
{ {
while(true) if (theProcess->checkSignal() == SIGINT)
{ {
if (theProcess->checkSignal() == SIGINT) return;
{ }
return; sleep(1);
} }
sleep(1);
}
}
catch(Exception* ex)
{
ex->writeMessage();
}
catch(...)
{
throw;
}
} }
void MultiTaskProcess::waitStop(void) void MultiTaskProcess::waitStop(void)
{ {
while (_stopCount < _threadCount) while (_stopCount < _threadCount)
{ {
sleep(1); sleep(1);
} }
} }
void MultiTaskProcess::threadStopped(void) void MultiTaskProcess::threadStopped(void)
{ {
_mutex.lock(); _mutex.lock();
_stopCount++; _stopCount++;
_mutex.unlock(); _mutex.unlock();
} }
void MultiTaskProcess::abort(void)
{
signalHandler(SIGINT);
}
void MultiTaskProcess::attach(Thread* thread) void MultiTaskProcess::attach(Thread* thread)
{ {
_mutex.lock(); _mutex.lock();
if (_threadCount < MQTTSNGW_MAX_TASK) if (_threadCount < MQTTSNGW_MAX_TASK)
{ {
_threadList[_threadCount] = thread; _threadList[_threadCount] = thread;
_threadCount++; _threadCount++;
} }
else else
{ {
_mutex.unlock(); _mutex.unlock();
throw Exception("Full of Threads"); throw Exception("The maximum number of threads has been exceeded.", -1);
} }
_mutex.unlock(); _mutex.unlock();
} }
int MultiTaskProcess::getParam(const char* parameter, char* value) int MultiTaskProcess::getParam(const char* parameter, char* value)
{ {
_mutex.lock(); _mutex.lock();
int rc = Process::getParam(parameter, value); int rc = Process::getParam(parameter, value);
_mutex.unlock(); _mutex.unlock();
if (rc == -1) return rc;
{
throw Exception("No config file.");
}
return rc;
} }
/*===================================== /*=====================================
Class Exception Class Exception
======================================*/ ======================================*/
Exception::Exception(const string& message) Exception::Exception(const char* message, const int errNo)
{ {
_message = message; _message = message;
_exNo = 0; _errNo = errNo;
_fileName = 0; _fileName = nullptr;
_functionName = 0; _functionName = nullptr;
_line = 0; _line = 0;
} }
Exception::Exception(const char* message, const int errNo, const char* file, const char* function, const int line)
Exception::Exception(const int exNo, const string& message)
{ {
_message = message; _message = message;
_exNo = exNo; _errNo = errNo;
_fileName = nullptr; _fileName = getFileName(file);
_functionName = nullptr; ;
_line = 0; _functionName = function;
} _line = line;
Exception::Exception(const int exNo, const string& message, const char* file,
const char* function, const int line)
{
_message = message;
_exNo = exNo;
_fileName = file;
_functionName = function;
_line = line;
} }
Exception::~Exception() throw () Exception::~Exception() throw ()
@@ -380,38 +379,67 @@ Exception::~Exception() throw ()
const char* Exception::what() const throw () const char* Exception::what() const throw ()
{ {
return _message.c_str(); return _message;
} }
const char* Exception::getFileName() const char* Exception::getFileName()
{ {
return _fileName; return _fileName;
} }
const char* Exception::getFunctionName() const char* Exception::getFunctionName()
{ {
return _functionName; return _functionName;
} }
const int Exception::getLineNo() const int Exception::getLineNo()
{ {
return _line; return _line;
} }
const int Exception::getExceptionNo() const int Exception::getErrNo()
{ {
return _exNo; return _errNo;
} }
void Exception::writeMessage() void Exception::writeMessage()
{ {
if (getExceptionNo() == 0 ) if (_fileName == nullptr)
{ {
WRITELOG("%s %s\n", currentDateTime(), what()); if (_errNo == 0)
} {
else WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
{ }
WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(), else
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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@ using namespace MQTTSNGW;
MQTTSNPublishHandler::MQTTSNPublishHandler(Gateway* gateway) MQTTSNPublishHandler::MQTTSNPublishHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTSNPublishHandler::~MQTTSNPublishHandler() MQTTSNPublishHandler::~MQTTSNPublishHandler()
@@ -37,263 +37,267 @@ MQTTSNPublishHandler::~MQTTSNPublishHandler()
MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket* packet) MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket* packet)
{ {
uint8_t dup; uint8_t dup;
int qos; int qos;
uint8_t retained; uint8_t retained;
uint16_t msgId; uint16_t msgId;
uint8_t* payload; uint16_t tid;
uint8_t* payload;
MQTTSN_topicid topicid; MQTTSN_topicid topicid;
int payloadlen; int payloadlen;
Publish pub = MQTTPacket_Publish_Initializer; Publish pub = MQTTPacket_Publish_Initializer;
char shortTopic[2]; 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); _gateway->getAdapterManager()->getQoSm1Proxy()->savePacket(client, packet);
return nullptr; return nullptr;
} }
} }
if ( packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) ==0 ) if (packet->getPUBLISH(&dup, &qos, &retained, &msgId, &topicid, &payload, &payloadlen) == 0)
{ {
return nullptr; return nullptr;
} }
pub.msgId = msgId; pub.msgId = msgId;
pub.header.bits.dup = dup; 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; pub.header.bits.retain = retained;
tid = topicid.data.id;
Topic* topic = nullptr; 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[0] = topicid.data.short_name[0];
shortTopic[1] = topicid.data.short_name[1]; shortTopic[1] = topicid.data.short_name[1];
pub.topic = shortTopic; pub.topic = shortTopic;
pub.topiclen = 2; pub.topiclen = 2;
} }
else else
{ {
topic = client->getTopics()->getTopicById(&topicid); topic = client->getTopics()->getTopicById(&topicid);
if ( !topic ) if (!topic)
{ {
topic = _gateway->getTopics()->getTopicById(&topicid); topic = _gateway->getTopics()->getTopicById(&topicid);
if ( topic ) if (topic)
{ {
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId()); 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); WRITELOG("%s Invalid TopicId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
return nullptr; 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); WRITELOG("%s Invalid MsgId.%s %s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
return nullptr; 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 */ /* Reply PubAck with INVALID_TOPIC_ID to the client */
MQTTSNPacket* pubAck = new MQTTSNPacket(); 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(); Event* ev1 = new Event();
ev1->setClientSendEvent(client, pubAck); ev1->setClientSendEvent(client, pubAck);
_gateway->getClientSendQue()->post(ev1); _gateway->getClientSendQue()->post(ev1);
return nullptr; return nullptr;
} }
if ( topic ) if (topic)
{ {
pub.topic = (char*)topic->getTopicName()->data(); pub.topic = (char*) topic->getTopicName()->data();
pub.topiclen = topic->getTopicName()->length(); 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) }
{ /* Save a msgId & a TopicId pare for PUBACK */
client->setWaitedPubTopicId(msgId, topicid.data.id, topicid.type); if (msgId && qos > 0 && qos < 3)
} {
client->setWaitedPubTopicId(msgId, tid, &topicid);
}
pub.payload = (char*)payload; pub.payload = (char*) payload;
pub.payloadlen = payloadlen; pub.payloadlen = payloadlen;
MQTTGWPacket* publish = new MQTTGWPacket(); MQTTGWPacket* publish = new MQTTGWPacket();
publish->setPUBLISH(&pub); publish->setPUBLISH(&pub);
if ( _gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated() ) if (_gateway->getAdapterManager()->isAggregaterActive() && client->isAggregated())
{ {
return publish; return publish;
} }
else else
{ {
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, publish); ev1->setBrokerSendEvent(client, publish);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
return nullptr; return nullptr;
} }
} }
void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet) void MQTTSNPublishHandler::handlePuback(Client* client, MQTTSNPacket* packet)
{ {
uint16_t topicId; uint16_t topicId;
uint16_t msgId;
uint8_t rc;
if ( client->isActive() )
{
if ( packet->getPUBACK(&topicId, &msgId, &rc) == 0 )
{
return;
}
if ( rc == MQTTSN_RC_ACCEPTED)
{
if ( !_gateway->getAdapterManager()->getAggregater()->isActive() )
{
MQTTGWPacket* pubAck = new MQTTGWPacket();
pubAck->setAck(PUBACK, msgId);
Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, pubAck);
_gateway->getBrokerSendQue()->post(ev1);
}
}
else if ( rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
{
WRITELOG(" PUBACK %d : Invalid Topic ID\n", msgId);
}
}
}
void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType)
{
uint16_t msgId;
if ( client->isActive() )
{
if ( packet->getACK(&msgId) == 0 )
{
return;
}
MQTTGWPacket* ackPacket = new MQTTGWPacket();
ackPacket->setAck(packetType, msgId);
Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, ackPacket);
_gateway->getBrokerSendQue()->post(ev1);
}
}
void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
{
uint16_t id;
uint16_t msgId;
MQTTSNString topicName = MQTTSNString_initializer;;
MQTTSN_topicid topicid;
if ( client->isActive() || client->isAwake())
{
if ( packet->getREGISTER(&id, &msgId, &topicName) == 0 )
{
return;
}
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
topicid.data.long_.len = topicName.lenstring.len;
topicid.data.long_.name = topicName.lenstring.data;
id = client->getTopics()->add(&topicid)->getTopicId();
MQTTSNPacket* regAck = new MQTTSNPacket();
regAck->setREGACK(id, msgId, MQTTSN_RC_ACCEPTED);
Event* ev = new Event();
ev->setClientSendEvent(client, regAck);
_gateway->getClientSendQue()->post(ev);
}
}
void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
{
uint16_t id;
uint16_t msgId; uint16_t msgId;
uint8_t rc; uint8_t rc;
if ( client->isActive() || client->isAwake())
if (client->isActive())
{ {
if ( packet->getREGACK(&id, &msgId, &rc) == 0 ) if (packet->getPUBACK(&topicId, &msgId, &rc) == 0)
{ {
return; return;
} }
if (rc == MQTTSN_RC_ACCEPTED)
{
if (!_gateway->getAdapterManager()->getAggregater()->isActive())
{
MQTTGWPacket* pubAck = new MQTTGWPacket();
pubAck->setAck(PUBACK, msgId);
Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, pubAck);
_gateway->getBrokerSendQue()->post(ev1);
}
}
else if (rc == MQTTSN_RC_REJECTED_INVALID_TOPIC_ID)
{
WRITELOG(" PUBACK %d : Invalid Topic ID\n", msgId);
}
}
}
void MQTTSNPublishHandler::handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType)
{
uint16_t msgId;
if (client->isActive())
{
if (packet->getACK(&msgId) == 0)
{
return;
}
MQTTGWPacket* ackPacket = new MQTTGWPacket();
ackPacket->setAck(packetType, msgId);
Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, ackPacket);
_gateway->getBrokerSendQue()->post(ev1);
}
}
void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
{
uint16_t id;
uint16_t msgId;
MQTTSNString topicName = MQTTSNString_initializer;
;
MQTTSN_topicid topicid;
if (client->isActive() || client->isAwake())
{
if (packet->getREGISTER(&id, &msgId, &topicName) == 0)
{
return;
}
topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
topicid.data.long_.len = topicName.lenstring.len;
topicid.data.long_.name = topicName.lenstring.data;
id = client->getTopics()->add(&topicid)->getTopicId();
MQTTSNPacket* regAck = new MQTTSNPacket();
regAck->setREGACK(id, msgId, MQTTSN_RC_ACCEPTED);
Event* ev = new Event();
ev->setClientSendEvent(client, regAck);
_gateway->getClientSendQue()->post(ev);
}
}
void MQTTSNPublishHandler::handleRegAck(Client* client, MQTTSNPacket* packet)
{
uint16_t id;
uint16_t msgId;
uint8_t rc;
if (client->isActive() || client->isAwake())
{
if (packet->getREGACK(&id, &msgId, &rc) == 0)
{
return;
}
/* get PUBLISH message */
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId); MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
if ( regAck != nullptr ) if (regAck != nullptr)
{ {
client->getWaitREGACKPacketList()->erase(msgId); client->getWaitREGACKPacketList()->erase(msgId);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, regAck); ev->setClientSendEvent(client, regAck);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
} }
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0 )
if (client->isHoldPingReqest() && client->getWaitREGACKPacketList()->getCount() == 0)
{ {
/* send PINGREQ to the broker */ /* send PINGREQ to the broker */
client->resetPingRequest(); client->resetPingRequest();
MQTTGWPacket* pingreq = new MQTTGWPacket(); MQTTGWPacket* pingreq = new MQTTGWPacket();
pingreq->setHeader(PINGREQ); pingreq->setHeader(PINGREQ);
Event* evt = new Event(); Event* evt = new Event();
evt->setBrokerSendEvent(client, pingreq); evt->setBrokerSendEvent(client, pingreq);
_gateway->getBrokerSendQue()->post(evt); _gateway->getBrokerSendQue()->post(evt);
} }
} }
} }
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet) void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
{ {
int msgId = 0; int msgId = 0;
MQTTGWPacket* publish = handlePublish(client, packet); 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()); msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
} }
else else
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId()); msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId());
} }
publish->setMsgId(msgId); publish->setMsgId(msgId);
} }
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, publish); ev1->setBrokerSendEvent(client, publish);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
} }
} }
void MQTTSNPublishHandler::handleAggregateAck(Client* client, MQTTSNPacket* packet, int type) void MQTTSNPublishHandler::handleAggregateAck(Client* client, MQTTSNPacket* packet, int type)
{ {
if ( type == MQTTSN_PUBREC ) if (type == MQTTSN_PUBREC)
{ {
uint16_t msgId; uint16_t msgId;
if ( packet->getACK(&msgId) == 0 ) if (packet->getACK(&msgId) == 0)
{ {
return; return;
} }
MQTTSNPacket* ackPacket = new MQTTSNPacket(); MQTTSNPacket* ackPacket = new MQTTSNPacket();
ackPacket->setPUBREL(msgId); ackPacket->setPUBREL(msgId);
Event* ev = new Event(); Event* ev = new Event();
ev->setClientSendEvent(client, ackPacket); ev->setClientSendEvent(client, ackPacket);
_gateway->getClientSendQue()->post(ev); _gateway->getClientSendQue()->post(ev);
} }
} }

View File

@@ -25,19 +25,19 @@ namespace MQTTSNGW
class MQTTSNPublishHandler class MQTTSNPublishHandler
{ {
public: public:
MQTTSNPublishHandler(Gateway* gateway); MQTTSNPublishHandler(Gateway* gateway);
~MQTTSNPublishHandler(); ~MQTTSNPublishHandler();
MQTTGWPacket* handlePublish(Client* client, MQTTSNPacket* packet); MQTTGWPacket* handlePublish(Client* client, MQTTSNPacket* packet);
void handlePuback(Client* client, MQTTSNPacket* packet); void handlePuback(Client* client, MQTTSNPacket* packet);
void handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType); void handleAck(Client* client, MQTTSNPacket* packet, uint8_t packetType);
void handleRegister(Client* client, MQTTSNPacket* packet); 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 handleAggregatePublish(Client* client, MQTTSNPacket* packet);
void handleAggregateAck(Client* client, MQTTSNPacket* packet, int type); void handleAggregateAck(Client* client, MQTTSNPacket* packet, int type);
private: private:
Gateway* _gateway; Gateway* _gateway;
}; };
} }

View File

@@ -21,13 +21,13 @@
#include <string> #include <string>
#include <string.h> #include <string.h>
using namespace MQTTSNGW; using namespace MQTTSNGW;
/*===================================== /*=====================================
Class QoSm1Proxy Class QoSm1Proxy
=====================================*/ =====================================*/
QoSm1Proxy:: QoSm1Proxy(Gateway* gw) : Adapter(gw) QoSm1Proxy::QoSm1Proxy(Gateway* gw) :
Adapter(gw)
{ {
_gateway = gw; _gateway = gw;
} }
@@ -37,24 +37,22 @@ QoSm1Proxy::~QoSm1Proxy(void)
} }
void QoSm1Proxy::initialize(char* gwName) void QoSm1Proxy::initialize(char* gwName)
{ {
if ( _gateway->hasSecureConnection() ) if (_gateway->hasSecureConnection())
{ {
_isSecure = true; _isSecure = true;
} }
/* Create QoS-1 Clients from clients.conf */ /* Create QoS-1 Clients from clients.conf */
_gateway->getClientList()->setClientList(QOSM1PROXY_TYPE); _gateway->getClientList()->setClientList(QOSM1PROXY_TYPE);
/* Create a client for QoS-1 proxy */ /* Create a client for QoS-1 proxy */
string name = string(gwName) + string("_QoS-1"); string name = string(gwName) + string("_QoS-1");
setup(name.c_str(), Atype_QoSm1Proxy); setup(name.c_str(), Atype_QoSm1Proxy);
_isActive = true; _isActive = true;
} }
bool QoSm1Proxy::isActive(void) bool QoSm1Proxy::isActive(void)
{ {
return _isActive; return _isActive;

View File

@@ -27,12 +27,12 @@ class SensorNetAddress;
class MQTTSNPacket; class MQTTSNPacket;
/*===================================== /*=====================================
Class QoSm1Proxy Class QoSm1Proxy
=====================================*/ =====================================*/
class QoSm1Proxy : public Adapter class QoSm1Proxy: public Adapter
{ {
public: public:
QoSm1Proxy(Gateway* gw); QoSm1Proxy(Gateway* gw);
~QoSm1Proxy(void); ~QoSm1Proxy(void);
void initialize(char* GWnAME); void initialize(char* GWnAME);
@@ -41,13 +41,10 @@ public:
private: private:
Gateway* _gateway; Gateway* _gateway;
bool _isActive {false}; bool _isActive { false };
bool _isSecure {false}; bool _isSecure { false };
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */

View File

@@ -26,7 +26,7 @@ using namespace MQTTSNGW;
MQTTSNSubscribeHandler::MQTTSNSubscribeHandler(Gateway* gateway) MQTTSNSubscribeHandler::MQTTSNSubscribeHandler(Gateway* gateway)
{ {
_gateway = gateway; _gateway = gateway;
} }
MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler() MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler()
@@ -36,63 +36,71 @@ MQTTSNSubscribeHandler::~MQTTSNSubscribeHandler()
MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPacket* packet) MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPacket* packet)
{ {
uint8_t dup; uint8_t dup;
int qos; int qos;
uint16_t msgId; uint16_t msgId;
MQTTSN_topicid topicFilter; MQTTSN_topicid topicFilter;
Topic* topic = nullptr; Topic* topic = nullptr;
uint16_t topicId = 0; uint16_t topicId = 0;
MQTTGWPacket* subscribe; MQTTGWPacket* subscribe;
Event* ev1; Event* ev1;
Event* evsuback; Event* evsuback;
if ( packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0 ) if (packet->getSUBSCRIBE(&dup, &qos, &msgId, &topicFilter) == 0)
{ {
return nullptr; return nullptr;
} }
if ( msgId == 0 ) if (msgId == 0)
{ {
return nullptr; return nullptr;
} }
if ( topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED ) if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
{ {
topic = client->getTopics()->getTopicById(&topicFilter); topic = client->getTopics()->getTopicById(&topicFilter);
if ( !topic ) if (!topic)
{ {
topic = _gateway->getTopics()->getTopicById(&topicFilter); /* Search the topic in Client common topic table */
if ( topic ) topic = _gateway->getTopics()->getTopicById(&topicFilter);
{ if (topic)
topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId()); {
} topic = client->getTopics()->add(topic->getTopicName()->c_str(), topic->getTopicId());
else if (topic == nullptr)
{ {
goto RespExit; WRITELOG("%s Client(%s) can't add the Topic.%s\n",
} ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
goto RespExit;
}
}
else
{
goto RespExit;
}
} }
topicId = topic->getTopicId(); topicId = topic->getTopicId();
subscribe = new MQTTGWPacket(); 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) else if (topicFilter.type == MQTTSN_TOPIC_TYPE_NORMAL)
{ {
topic = client->getTopics()->getTopicByName(&topicFilter); topic = client->getTopics()->getTopicByName(&topicFilter);
if ( topic == nullptr ) if (topic == nullptr)
{ {
topic = client->getTopics()->add(&topicFilter); 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); WRITELOG("%s Client(%s) can't add the Topic.%s\n",
return nullptr; ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
goto RespExit;
} }
} }
topicId = topic->getTopicId(); topicId = topic->getTopicId();
subscribe = new MQTTGWPacket(); 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 else //MQTTSN_TOPIC_TYPE_SHORT
{ {
@@ -103,73 +111,70 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
topicId = topicFilter.data.short_name[0] << 8; topicId = topicFilter.data.short_name[0] << 8;
topicId |= topicFilter.data.short_name[1]; topicId |= topicFilter.data.short_name[1];
subscribe = new MQTTGWPacket(); 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 = new Event();
ev1->setBrokerSendEvent(client, subscribe); ev1->setBrokerSendEvent(client, subscribe);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
return nullptr; return nullptr;
} }
else else
{ {
return subscribe; return subscribe;
} }
RespExit: MQTTSNPacket* sSuback = new MQTTSNPacket();
RespExit: sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_REJECTED_INVALID_TOPIC_ID);
MQTTSNPacket* sSuback = new MQTTSNPacket(); evsuback = new Event();
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_NOT_SUPPORTED); evsuback->setClientSendEvent(client, sSuback);
evsuback = new Event(); _gateway->getClientSendQue()->post(evsuback);
evsuback->setClientSendEvent(client, sSuback); return nullptr;
_gateway->getClientSendQue()->post(evsuback);
return nullptr;
} }
MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPacket* packet) MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPacket* packet)
{ {
uint16_t msgId; uint16_t msgId;
MQTTSN_topicid topicFilter; MQTTSN_topicid topicFilter;
MQTTGWPacket* unsubscribe = nullptr; MQTTGWPacket* unsubscribe = nullptr;
if ( packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0 ) if (packet->getUNSUBSCRIBE(&msgId, &topicFilter) == 0)
{
return nullptr;
}
if ( msgId == 0 )
{ {
return nullptr; return nullptr;
} }
if (msgId == 0)
{
return nullptr;
}
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT) if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
{ {
char shortTopic[3]; char shortTopic[3];
shortTopic[0] = topicFilter.data.short_name[0]; shortTopic[0] = topicFilter.data.short_name[0];
shortTopic[1] = topicFilter.data.short_name[1]; shortTopic[1] = topicFilter.data.short_name[1];
shortTopic[2] = 0; shortTopic[2] = 0;
unsubscribe = new MQTTGWPacket(); unsubscribe = new MQTTGWPacket();
unsubscribe->setUNSUBSCRIBE(shortTopic, msgId); unsubscribe->setUNSUBSCRIBE(shortTopic, msgId);
} }
else else
{ {
Topic* topic = nullptr; Topic* topic = nullptr;
if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED) if (topicFilter.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
{ {
topic = client->getTopics()->getTopicById(&topicFilter); topic = client->getTopics()->getTopicById(&topicFilter);
} }
else else
{ {
topic = client->getTopics()->getTopicByName(&topicFilter); topic = client->getTopics()->getTopicByName(&topicFilter);
} }
if ( topic == nullptr ) if (topic == nullptr)
{ {
MQTTSNPacket* sUnsuback = new MQTTSNPacket(); MQTTSNPacket* sUnsuback = new MQTTSNPacket();
sUnsuback->setUNSUBACK(msgId); sUnsuback->setUNSUBACK(msgId);
@@ -183,85 +188,87 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
unsubscribe = new MQTTGWPacket(); unsubscribe = new MQTTGWPacket();
unsubscribe->setUNSUBSCRIBE(topic->getTopicName()->c_str(), msgId); unsubscribe->setUNSUBSCRIBE(topic->getTopicName()->c_str(), msgId);
} }
} }
if ( !client->isAggregated() ) if (!client->isAggregated())
{ {
Event* ev1 = new Event(); Event* ev1 = new Event();
ev1->setBrokerSendEvent(client, unsubscribe); ev1->setBrokerSendEvent(client, unsubscribe);
_gateway->getBrokerSendQue()->post(ev1); _gateway->getBrokerSendQue()->post(ev1);
return nullptr; return nullptr;
} }
else else
{ {
return unsubscribe; return unsubscribe;
} }
} }
void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPacket* packet) void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPacket* packet)
{ {
MQTTGWPacket* subscribe = handleSubscribe(client, packet); MQTTGWPacket* subscribe = handleSubscribe(client, packet);
if ( subscribe != nullptr ) if (subscribe != nullptr)
{ {
int msgId = 0; int msgId = 0;
if ( packet->isDuplicate() ) if (packet->isDuplicate())
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId()); msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
} }
else else
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId()); 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",
return; ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
} return;
}
UTF8String str = subscribe->getTopic(); UTF8String str = subscribe->getTopic();
string* topicName = new string(str.data, str.len); // topicName is delete by topic string* topicName = new string(str.data, str.len); // topicName is delete by topic
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
_gateway->getAdapterManager()->getAggregater()->addAggregateTopic(&topic, client); _gateway->getAdapterManager()->getAggregater()->addAggregateTopic(&topic, client);
subscribe->setMsgId(msgId); subscribe->setMsgId(msgId);
Event* ev = new Event(); Event* ev = new Event();
ev->setBrokerSendEvent(client, subscribe); ev->setBrokerSendEvent(client, subscribe);
_gateway->getBrokerSendQue()->post(ev); _gateway->getBrokerSendQue()->post(ev);
} }
} }
void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet) void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet)
{ {
MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet); MQTTGWPacket* unsubscribe = handleUnsubscribe(client, packet);
if ( unsubscribe != nullptr ) if (unsubscribe != nullptr)
{ {
int msgId = 0; int msgId = 0;
if ( packet->isDuplicate() ) if (packet->isDuplicate())
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId()); msgId = _gateway->getAdapterManager()->getAggregater()->getMsgId(client, packet->getMsgId());
} }
else else
{ {
msgId = _gateway->getAdapterManager()->getAggregater()->addMessageIdTable(client, packet->getMsgId()); 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",
return; ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
} return;
}
UTF8String str = unsubscribe->getTopic(); UTF8String str = unsubscribe->getTopic();
string* topicName = new string(str.data, str.len); // topicName is delete by topic string* topicName = new string(str.data, str.len); // topicName is delete by topic
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL); Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
_gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(&topic, client); _gateway->getAdapterManager()->getAggregater()->removeAggregateTopic(&topic, client);
unsubscribe->setMsgId(msgId); unsubscribe->setMsgId(msgId);
Event* ev = new Event(); Event* ev = new Event();
ev->setBrokerSendEvent(client, unsubscribe); ev->setBrokerSendEvent(client, unsubscribe);
_gateway->getBrokerSendQue()->post(ev); _gateway->getBrokerSendQue()->post(ev);
} }
} }

View File

@@ -24,23 +24,22 @@
namespace MQTTSNGW namespace MQTTSNGW
{ {
/*===================================== /*=====================================
Class MQTTSNSubscribeHandler Class MQTTSNSubscribeHandler
=====================================*/ =====================================*/
class MQTTSNSubscribeHandler class MQTTSNSubscribeHandler
{ {
public: public:
MQTTSNSubscribeHandler(Gateway* gateway); MQTTSNSubscribeHandler(Gateway* gateway);
~MQTTSNSubscribeHandler(); ~MQTTSNSubscribeHandler();
MQTTGWPacket* handleSubscribe(Client* client, MQTTSNPacket* packet); MQTTGWPacket* handleSubscribe(Client* client, MQTTSNPacket* packet);
MQTTGWPacket* handleUnsubscribe(Client* client, MQTTSNPacket* packet); MQTTGWPacket* handleUnsubscribe(Client* client, MQTTSNPacket* packet);
void handleAggregateSubscribe(Client* client, MQTTSNPacket* packet); void handleAggregateSubscribe(Client* client, MQTTSNPacket* packet);
void handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet); void handleAggregateUnsubscribe(Client* client, MQTTSNPacket* packet);
private: private:
Gateway* _gateway; Gateway* _gateway;
}; };
} }
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */ #endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */

View File

@@ -27,35 +27,35 @@ using namespace MQTTSNGW;
Topic::Topic() Topic::Topic()
{ {
_type = MQTTSN_TOPIC_TYPE_NORMAL; _type = MQTTSN_TOPIC_TYPE_NORMAL;
_topicName = nullptr; _topicName = nullptr;
_topicId = 0; _topicId = 0;
_next = nullptr; _next = nullptr;
} }
Topic::Topic(string* topic, MQTTSN_topicTypes type) Topic::Topic(string* topic, MQTTSN_topicTypes type)
{ {
_type = type; _type = type;
_topicName = topic; _topicName = topic;
_topicId = 0; _topicId = 0;
_next = nullptr; _next = nullptr;
} }
Topic::~Topic() Topic::~Topic()
{ {
if ( _topicName ) if (_topicName)
{ {
delete _topicName; delete _topicName;
} }
} }
string* Topic::getTopicName(void) string* Topic::getTopicName(void)
{ {
return _topicName; return _topicName;
} }
uint16_t Topic::getTopicId(void) uint16_t Topic::getTopicId(void)
{ {
return _topicId; return _topicId;
} }
MQTTSN_topicTypes Topic::getType(void) MQTTSN_topicTypes Topic::getType(void)
@@ -65,103 +65,103 @@ MQTTSN_topicTypes Topic::getType(void)
Topic* Topic::duplicate(void) Topic* Topic::duplicate(void)
{ {
Topic* newTopic = new Topic(); Topic* newTopic = new Topic();
newTopic->_type = _type; newTopic->_type = _type;
newTopic->_topicId = _topicId; newTopic->_topicId = _topicId;
newTopic->_topicName = new string(_topicName->c_str()); newTopic->_topicName = new string(_topicName->c_str());
return newTopic; return newTopic;
} }
bool Topic::isMatch(string* topicName) bool Topic::isMatch(string* topicName)
{ {
string::size_type tlen = _topicName->size(); string::size_type tlen = _topicName->size();
string::size_type tpos = 0; string::size_type tpos = 0;
string::size_type tloc = 0; string::size_type tloc = 0;
string::size_type pos = 0; string::size_type pos = 0;
string::size_type loc = 0; string::size_type loc = 0;
string wildcard = "#"; string wildcard = "#";
string wildcards = "+"; string wildcards = "+";
while(true) while (true)
{ {
loc = topicName->find('/', pos); loc = topicName->find('/', pos);
tloc = _topicName->find('/', tpos); 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 subtopic = topicName->substr(pos, loc - pos);
string subtopict = _topicName->substr(tpos, tloc - tpos); string subtopict = _topicName->substr(tpos, tloc - tpos);
if (subtopict == wildcard) if (subtopict == wildcard)
{ {
return true; return true;
} }
else if (subtopict == wildcards) else if (subtopict == wildcards)
{ {
if ( (tpos = tloc + 1 ) > tlen ) if ((tpos = tloc + 1) > tlen)
{ {
pos = loc + 1; pos = loc + 1;
loc = topicName->find('/', pos); loc = topicName->find('/', pos);
if ( loc == string::npos ) if (loc == string::npos)
{ {
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
pos = loc + 1; pos = loc + 1;
} }
else if ( subtopic != subtopict ) else if (subtopic != subtopict)
{ {
return false; return false;
} }
else else
{ {
if ( (tpos = tloc + 1) > tlen ) if ((tpos = tloc + 1) > tlen)
{ {
return false; return false;
} }
pos = loc + 1; 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 subtopic = topicName->substr(pos);
string subtopict = _topicName->substr(tpos); string subtopict = _topicName->substr(tpos);
if ( subtopict == wildcard || subtopict == wildcards) if (subtopict == wildcard || subtopict == wildcards)
{ {
return true; return true;
} }
else if ( subtopic == subtopict ) else if (subtopic == subtopict)
{ {
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
else if ( loc == string::npos && tloc != string::npos ) else if (loc == string::npos && tloc != string::npos)
{ {
string subtopic = topicName->substr(pos); string subtopic = topicName->substr(pos);
string subtopict = _topicName->substr(tpos, tloc - tpos); string subtopict = _topicName->substr(tpos, tloc - tpos);
if ( subtopic != subtopict) if (subtopic != subtopict)
{ {
return false; return false;
} }
tpos = tloc + 1; tpos = tloc + 1;
return _topicName->substr(tpos) == wildcard; 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; return _topicName->substr(tpos) == wildcard;
} }
} }
} }
void Topic::print(void) void Topic::print(void)
@@ -198,11 +198,11 @@ Topic* Topics::getTopicByName(const MQTTSN_topicid* topicid)
string sname = string(ch, ch + topicid->data.long_.len); string sname = string(ch, ch + topicid->data.long_.len);
while (p) while (p)
{ {
if ( p->_topicName->compare(sname) == 0 ) if (p->_topicName->compare(sname) == 0)
{ {
return p; return p;
} }
p = p->_next; p = p->_next;
} }
return 0; return 0;
} }
@@ -213,7 +213,7 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
while (p) while (p)
{ {
if ( p->_type == topicid->type && p->_topicId == topicid->data.id ) if (p->_type == topicid->type && p->_topicId == topicid->data.id)
{ {
return p; return p;
} }
@@ -225,14 +225,14 @@ Topic* Topics::getTopicById(const MQTTSN_topicid* topicid)
// For MQTTSN_TOPIC_TYPE_NORMAL */ // For MQTTSN_TOPIC_TYPE_NORMAL */
Topic* Topics::add(const MQTTSN_topicid* topicid) Topic* Topics::add(const MQTTSN_topicid* topicid)
{ {
if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL ) if (topicid->type != MQTTSN_TOPIC_TYPE_NORMAL)
{ {
return 0; return 0;
} }
Topic* topic = getTopicByName(topicid); Topic* topic = getTopicByName(topicid);
if ( topic ) if (topic)
{ {
return topic; return topic;
} }
@@ -244,18 +244,17 @@ Topic* Topics::add(const char* topicName, uint16_t id)
{ {
MQTTSN_topicid topicId; MQTTSN_topicid topicId;
if ( _cnt >= MAX_TOPIC_PAR_CLIENT ) if (_cnt >= MAX_TOPIC_PAR_CLIENT)
{ {
return 0; 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); topicId.data.long_.len = strlen(topicName);
Topic* topic = getTopicByName(&topicId); Topic* topic = getTopicByName(&topicId);
if ( topic ) if (topic)
{ {
return topic; return topic;
} }
@@ -270,7 +269,7 @@ Topic* Topics::add(const char* topicName, uint16_t id)
string* name = new string(topicName); string* name = new string(topicName);
topic->_topicName = name; topic->_topicName = name;
if ( id == 0 ) if (id == 0)
{ {
topic->_type = MQTTSN_TOPIC_TYPE_NORMAL; topic->_type = MQTTSN_TOPIC_TYPE_NORMAL;
topic->_topicId = getNextTopicId(); topic->_topicId = getNextTopicId();
@@ -278,12 +277,12 @@ Topic* Topics::add(const char* topicName, uint16_t id)
else else
{ {
topic->_type = MQTTSN_TOPIC_TYPE_PREDEFINED; topic->_type = MQTTSN_TOPIC_TYPE_PREDEFINED;
topic->_topicId = id; topic->_topicId = id;
} }
_cnt++; _cnt++;
if ( _first == nullptr) if (_first == nullptr)
{ {
_first = topic; _first = topic;
} }
@@ -331,7 +330,6 @@ Topic* Topics::match(const MQTTSN_topicid* topicid)
return 0; return 0;
} }
void Topics::eraseNormal(void) void Topics::eraseNormal(void)
{ {
Topic* topic = _first; Topic* topic = _first;
@@ -340,14 +338,14 @@ void Topics::eraseNormal(void)
while (topic) while (topic)
{ {
if ( topic->_type == MQTTSN_TOPIC_TYPE_NORMAL ) if (topic->_type == MQTTSN_TOPIC_TYPE_NORMAL)
{ {
next = topic->_next; next = topic->_next;
if ( _first == topic ) if (_first == topic)
{ {
_first = next; _first = next;
} }
if ( prev ) if (prev)
{ {
prev->_next = next; prev->_next = next;
} }
@@ -365,18 +363,18 @@ void Topics::eraseNormal(void)
Topic* Topics::getFirstTopic(void) Topic* Topics::getFirstTopic(void)
{ {
return _first; return _first;
} }
Topic* Topics::getNextTopic(Topic* topic) Topic* Topics::getNextTopic(Topic* topic)
{ {
return topic->_next; return topic->_next;
} }
void Topics::print(void) void Topics::print(void)
{ {
Topic* topic = _first; Topic* topic = _first;
if (topic == nullptr ) if (topic == nullptr)
{ {
WRITELOG("No Topic.\n"); WRITELOG("No Topic.\n");
} }
@@ -398,13 +396,22 @@ uint8_t Topics::getCount(void)
/*===================================== /*=====================================
Class TopicIdMap 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; _msgId = msgId;
_topicId = topicId; _topicId = topicId;
_type = type; _type = topic->type;
_wildcard = 0;
_next = nullptr; _next = nullptr;
_prev = 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() TopicIdMapElement::~TopicIdMapElement()
@@ -419,7 +426,14 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
uint16_t TopicIdMapElement::getTopicId(void) uint16_t TopicIdMapElement::getTopicId(void)
{ {
return _topicId; if (_wildcard > 0)
{
return 0;
}
else
{
return _topicId;
}
} }
TopicIdMap::TopicIdMap() TopicIdMap::TopicIdMap()
@@ -434,7 +448,7 @@ TopicIdMap::TopicIdMap()
TopicIdMap::~TopicIdMap() TopicIdMap::~TopicIdMap()
{ {
TopicIdMapElement* p = _first; TopicIdMapElement* p = _first;
while ( p ) while (p)
{ {
TopicIdMapElement* q = p->_next; TopicIdMapElement* q = p->_next;
delete p; delete p;
@@ -445,9 +459,9 @@ TopicIdMap::~TopicIdMap()
TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId) TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
{ {
TopicIdMapElement* p = _first; TopicIdMapElement* p = _first;
while ( p ) while (p)
{ {
if ( p->_msgId == msgId ) if (p->_msgId == msgId)
{ {
return p; return p;
} }
@@ -456,23 +470,23 @@ TopicIdMapElement* TopicIdMap::getElement(uint16_t msgId)
return 0; 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; return 0;
} }
if ( getElement(msgId) ) if (getElement(msgId))
{ {
erase(msgId); erase(msgId);
} }
TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, type); TopicIdMapElement* elm = new TopicIdMapElement(msgId, topicId, topic);
if ( elm == 0 ) if (elm == 0)
{ {
return 0; return 0;
} }
if ( _first == nullptr ) if (_first == nullptr)
{ {
_first = elm; _first = elm;
_end = elm; _end = elm;
@@ -490,11 +504,11 @@ TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topi
void TopicIdMap::erase(uint16_t msgId) void TopicIdMap::erase(uint16_t msgId)
{ {
TopicIdMapElement* p = _first; 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; _first = p->_next;
} }
@@ -503,7 +517,7 @@ void TopicIdMap::erase(uint16_t msgId)
p->_prev->_next = p->_next; p->_prev->_next = p->_next;
} }
if ( p->_next == nullptr ) if (p->_next == nullptr)
{ {
_end = p->_prev; _end = p->_prev;
} }
@@ -523,7 +537,7 @@ void TopicIdMap::erase(uint16_t msgId)
void TopicIdMap::clear(void) void TopicIdMap::clear(void)
{ {
TopicIdMapElement* p = _first; TopicIdMapElement* p = _first;
while ( p ) while (p)
{ {
TopicIdMapElement* q = p->_next; TopicIdMapElement* q = p->_next;
delete p; delete p;
@@ -534,5 +548,3 @@ void TopicIdMap::clear(void)
_cnt = 0; _cnt = 0;
} }

View File

@@ -24,7 +24,6 @@
namespace MQTTSNGW namespace MQTTSNGW
{ {
/*===================================== /*=====================================
Class Topic Class Topic
======================================*/ ======================================*/
@@ -46,7 +45,7 @@ public:
private: private:
MQTTSN_topicTypes _type; MQTTSN_topicTypes _type;
uint16_t _topicId; uint16_t _topicId;
string* _topicName; string* _topicName;
Topic* _next; Topic* _next;
}; };
@@ -72,7 +71,7 @@ public:
private: private:
uint16_t _nextTopicId; uint16_t _nextTopicId;
Topic* _first; Topic* _first;
uint8_t _cnt; uint8_t _cnt;
}; };
/*===================================== /*=====================================
@@ -82,7 +81,7 @@ class TopicIdMapElement
{ {
friend class TopicIdMap; friend class TopicIdMap;
public: public:
TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicTypes type); TopicIdMapElement(uint16_t msgId, uint16_t topicId, MQTTSN_topicid* topic);
~TopicIdMapElement(); ~TopicIdMapElement();
MQTTSN_topicTypes getTopicType(void); MQTTSN_topicTypes getTopicType(void);
uint16_t getTopicId(void); uint16_t getTopicId(void);
@@ -90,6 +89,7 @@ public:
private: private:
uint16_t _msgId; uint16_t _msgId;
uint16_t _topicId; uint16_t _topicId;
uint8_t _wildcard;
MQTTSN_topicTypes _type; MQTTSN_topicTypes _type;
TopicIdMapElement* _next; TopicIdMapElement* _next;
TopicIdMapElement* _prev; TopicIdMapElement* _prev;
@@ -101,7 +101,7 @@ public:
TopicIdMap(); TopicIdMap();
~TopicIdMap(); ~TopicIdMap();
TopicIdMapElement* getElement(uint16_t msgId); 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 erase(uint16_t msgId);
void clear(void); void clear(void);
private: private:
@@ -112,9 +112,6 @@ private:
int _maxInflight; int _maxInflight;
}; };
} }
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWTOPIC_H_ */ #endif /* MQTTSNGATEWAY_SRC_MQTTSNGWTOPIC_H_ */

View File

@@ -17,6 +17,6 @@
#ifndef MQTTSNGWVERSION_H_IN_ #ifndef MQTTSNGWVERSION_H_IN_
#define 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_ */ #endif /* MQTTSNGWVERSION_H_IN_ */

View File

@@ -17,6 +17,6 @@
#ifndef MQTTSNGWVERSION_H_IN_ #ifndef MQTTSNGWVERSION_H_IN_
#define MQTTSNGWVERSION_H_IN_ #define MQTTSNGWVERSION_H_IN_
#define PAHO_GATEWAY_VERSION "@GATEWAY_VERSION@" #define PAHO_GATEWAY_VERSION "@GATEWAY_VERSION@"
#endif /* MQTTSNGWVERSION_H_IN_ */ #endif /* MQTTSNGWVERSION_H_IN_ */

View File

@@ -32,10 +32,10 @@ MQTTSNGW::Gateway* theGateway = nullptr;
Gateway::Gateway(void) Gateway::Gateway(void)
{ {
theGateway = this;
theMultiTaskProcess = this; theMultiTaskProcess = this;
theProcess = this; theProcess = this;
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS); _clientList = new ClientList(this);
_clientList = new ClientList();
_adapterManager = new AdapterManager(this); _adapterManager = new AdapterManager(this);
_topics = new Topics(); _topics = new Topics();
_stopFlg = false; _stopFlg = false;
@@ -43,78 +43,87 @@ Gateway::Gateway(void)
Gateway::~Gateway() Gateway::~Gateway()
{ {
if ( _params.loginId ) if (_params.loginId)
{ {
free(_params.loginId); free(_params.loginId);
} }
if ( _params.password ) if (_params.password)
{ {
free(_params.password); free(_params.password);
} }
if ( _params.gatewayName ) if (_params.gatewayName)
{ {
free(_params.gatewayName); free(_params.gatewayName);
} }
if ( _params.brokerName ) if (_params.brokerName)
{ {
free(_params.brokerName); free(_params.brokerName);
} }
if ( _params.port ) if (_params.port)
{ {
free(_params.port); free(_params.port);
} }
if ( _params.portSecure ) if (_params.portSecure)
{ {
free(_params.portSecure); free(_params.portSecure);
} }
if ( _params.certKey ) if (_params.certKey)
{ {
free(_params.certKey); free(_params.certKey);
} }
if ( _params.privateKey ) if (_params.privateKey)
{ {
free(_params.privateKey); free(_params.privateKey);
} }
if ( _params.rootCApath ) if (_params.rootCApath)
{ {
free(_params.rootCApath); free(_params.rootCApath);
} }
if ( _params.rootCAfile ) if (_params.rootCAfile)
{ {
free(_params.rootCAfile); free(_params.rootCAfile);
} }
if ( _params.clientListName ) if (_params.clientListName)
{ {
free(_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); free(_params.configName);
} }
if (_params.qosMinusClientListName)
if ( _params.qosMinusClientListName )
{ {
free(_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; delete _adapterManager;
} }
if ( _clientList ) if (_clientList)
{ {
delete _clientList; delete _clientList;
} }
if (_topics)
if ( _topics ) {
{ delete _topics;
delete _topics; }
}
// WRITELOG("Gateway is deleted normally.\r\n");
} }
int Gateway::getParam(const char* parameter, char* value) int Gateway::getParam(const char* parameter, char* value)
@@ -124,256 +133,285 @@ int Gateway::getParam(const char* parameter, char* value)
char* Gateway::getClientListFileName(void) char* Gateway::getClientListFileName(void)
{ {
return _params.clientListName; return _params.clientListName;
} }
char* Gateway::getPredefinedTopicFileName(void) char* Gateway::getPredefinedTopicFileName(void)
{ {
return _params.predefinedTopicFileName; return _params.predefinedTopicFileName;
} }
void Gateway::initialize(int argc, char** argv) void Gateway::initialize(int argc, char** argv)
{ {
char param[MQTTSNGW_PARAM_MAX]; char param[MQTTSNGW_PARAM_MAX];
string fileName; string fileName;
theGateway = this; theGateway = this;
MultiTaskProcess::initialize(argc, argv); MultiTaskProcess::initialize(argc, argv);
resetRingBuffer(); resetRingBuffer();
_params.configDir = *getConfigDirName(); _params.configDir = *getConfigDirName();
fileName = _params.configDir + *getConfigFileName(); fileName = _params.configDir + *getConfigFileName();
_params.configName = strdup(fileName.c_str()); _params.configName = strdup(fileName.c_str());
if (getParam("BrokerName", param) == 0) if (getParam("BrokerName", param) == 0)
{ {
_params.brokerName = strdup(param); _params.brokerName = strdup(param);
} }
if (getParam("BrokerPortNo", param) == 0) if (getParam("BrokerPortNo", param) == 0)
{ {
_params.port = strdup(param); _params.port = strdup(param);
} }
if (getParam("BrokerSecurePortNo", param) == 0) if (getParam("BrokerSecurePortNo", param) == 0)
{ {
_params.portSecure = strdup(param); _params.portSecure = strdup(param);
} }
if (getParam("CertKey", param) == 0) if (getParam("CertKey", param) == 0)
{ {
_params.certKey = strdup(param); _params.certKey = strdup(param);
} }
if (getParam("PrivateKey", param) == 0) if (getParam("PrivateKey", param) == 0)
{ {
_params.privateKey = strdup(param); _params.privateKey = strdup(param);
} }
if (getParam("RootCApath", param) == 0) if (getParam("RootCApath", param) == 0)
{ {
_params.rootCApath = strdup(param); _params.rootCApath = strdup(param);
} }
if (getParam("RootCAfile", param) == 0) if (getParam("RootCAfile", param) == 0)
{ {
_params.rootCAfile = strdup(param); _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) if (getParam("GatewayID", param) == 0)
{ {
_params.gatewayId = atoi(param); _params.gatewayId = atoi(param);
} }
if (_params.gatewayId == 0 || _params.gatewayId > 255) 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) if (getParam("GatewayName", param) == 0)
{ {
_params.gatewayName = strdup(param); _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; _params.mqttVersion = DEFAULT_MQTT_VERSION;
if (getParam("MQTTVersion", param) == 0) if (getParam("MQTTVersion", param) == 0)
{ {
_params.mqttVersion = atoi(param); _params.mqttVersion = atoi(param);
} }
_params.maxInflightMsgs = DEFAULT_MQTT_VERSION; _params.maxInflightMsgs = MAX_INFLIGHTMESSAGES;
if (getParam("MaxInflightMsgs", param) == 0) if (getParam("MaxInflightMsgs", param) == 0)
{ {
_params.maxInflightMsgs = atoi(param); _params.maxInflightMsgs = atoi(param);
} }
_params.keepAlive = DEFAULT_KEEP_ALIVE_TIME; _params.keepAlive = DEFAULT_KEEP_ALIVE_TIME;
if (getParam("KeepAlive", param) == 0) if (getParam("KeepAlive", param) == 0)
{ {
_params.keepAlive = atoi(param); _params.keepAlive = atoi(param);
} }
if (getParam("LoginID", param) == 0) if (getParam("LoginID", param) == 0)
{ {
_params.loginId = strdup(param); _params.loginId = strdup(param);
} }
if (getParam("Password", param) == 0) if (getParam("Password", param) == 0)
{ {
_params.password = strdup(param); _params.password = strdup(param);
} }
if (getParam("ClientAuthentication", param) == 0) if (getParam("ClientAuthentication", param) == 0)
{ {
if (!strcasecmp(param, "YES")) if (!strcasecmp(param, "YES"))
{ {
_params.clientAuthentication = true; _params.clientAuthentication = true;
} }
} }
if (getParam("ClientsList", param) == 0) if (getParam("ClientsList", param) == 0)
{ {
_params.clientListName = strdup(param); _params.clientListName = strdup(param);
} }
if (getParam("PredefinedTopic", param) == 0) if (getParam("PredefinedTopic", param) == 0)
{ {
if ( !strcasecmp(param, "YES") ) if (!strcasecmp(param, "YES"))
{ {
_params.predefinedTopic = true; _params.predefinedTopic = true;
if (getParam("PredefinedTopicList", param) == 0) if (getParam("PredefinedTopicList", param) == 0)
{ {
_params.predefinedTopicFileName = strdup(param); _params.predefinedTopicFileName = strdup(param);
} }
} }
} }
if (getParam("AggregatingGateway", param) == 0) if (getParam("AggregatingGateway", param) == 0)
{ {
if ( !strcasecmp(param, "YES") ) if (!strcasecmp(param, "YES"))
{ {
_params.aggregatingGw = true; _params.aggregatingGw = true;
} }
} }
if (getParam("Forwarder", param) == 0) if (getParam("Forwarder", param) == 0)
{ {
if ( !strcasecmp(param, "YES") ) if (!strcasecmp(param, "YES"))
{ {
_params.forwarder = true; _params.forwarder = true;
} }
} }
if (getParam("QoS-1", param) == 0) if (getParam("QoS-1", param) == 0)
{ {
if ( !strcasecmp(param, "YES") ) if (!strcasecmp(param, "YES"))
{ {
_params.qosMinus1 = true; _params.qosMinus1 = true;
} }
} }
_params.maxClients = MAX_CLIENTS;
if (getParam("MaxNumberOfClients", param) == 0)
{
_params.maxClients = atoi(param);
}
/* Initialize adapters */ if (getParam("RFCOMMAddress", param) == 0)
_adapterManager->initialize( _params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1); {
_params.rfcommAddr = strdup(param);
}
/* Setup ClientList and Predefined topics */ /* Setup max PacketEventQue size */
_clientList->initialize(_params.aggregatingGw); _packetEventQue.setMaxSize(_params.maxInflightMsgs * _params.maxClients);
/* Initialize adapters */
_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) void Gateway::run(void)
{ {
/* write prompts */ /* write prompts */
_lightIndicator.redLight(true); _lightIndicator.redLight(true);
WRITELOG("\n%s", PAHO_COPYRIGHT4); WRITELOG("\n%s", PAHO_COPYRIGHT4);
WRITELOG("\n%s\n", PAHO_COPYRIGHT0); WRITELOG("\n%s\n", PAHO_COPYRIGHT0);
WRITELOG("%s\n", PAHO_COPYRIGHT1); WRITELOG("%s\n", PAHO_COPYRIGHT1);
WRITELOG("%s\n", PAHO_COPYRIGHT2); WRITELOG("%s\n", PAHO_COPYRIGHT2);
WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3); WRITELOG(" *\n%s\n", PAHO_COPYRIGHT3);
WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION); WRITELOG(" * Version: %s\n", PAHO_GATEWAY_VERSION);
WRITELOG("%s\n", PAHO_COPYRIGHT4); 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);
}
if ( _params.predefinedTopicFileName )
{ {
WRITELOG(" PreDefFile: %s\n", _params.predefinedTopicFileName); WRITELOG(" ClientList : %s\n", _params.clientListName);
} }
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription()); if (_params.predefinedTopicFileName)
WRITELOG(" Broker: %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure); {
WRITELOG(" RootCApath: %s\n", _params.rootCApath); WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
WRITELOG(" RootCAfile: %s\n", _params.rootCAfile); }
WRITELOG(" CertKey: %s\n", _params.certKey);
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
_stopFlg = false; 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);
/* Run Tasks until CTRL+C entred */ _stopFlg = false;
MultiTaskProcess::run();
_stopFlg = true; /* Run Tasks until CTRL+C entered or Exception occurred */
MultiTaskProcess::run();
WRITELOG("\n");
_stopFlg = true;
/* stop Tasks */ /* stop Tasks */
Event* ev = new Event(); Event* ev = new Event();
ev->setStop(); ev->setStop();
_packetEventQue.post(ev); _packetEventQue.post(ev);
ev = new Event(); ev = new Event();
ev->setStop(); ev->setStop();
_brokerSendQue.post(ev); _brokerSendQue.post(ev);
ev = new Event(); ev = new Event();
ev->setStop(); ev->setStop();
_clientSendQue.post(ev); _clientSendQue.post(ev);
/* wait until all Task stop */ /* wait until all Task stop */
MultiTaskProcess::waitStop(); 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(); _lightIndicator.allLightOff();
} }
bool Gateway::IsStopping(void) bool Gateway::IsStopping(void)
{ {
return _stopFlg; return _stopFlg;
} }
EventQue* Gateway::getPacketEventQue() EventQue* Gateway::getPacketEventQue()
{ {
return &_packetEventQue; return &_packetEventQue;
} }
EventQue* Gateway::getClientSendQue() EventQue* Gateway::getClientSendQue()
{ {
return &_clientSendQue; return &_clientSendQue;
} }
EventQue* Gateway::getBrokerSendQue() EventQue* Gateway::getBrokerSendQue()
{ {
return &_brokerSendQue; return &_brokerSendQue;
} }
ClientList* Gateway::getClientList() ClientList* Gateway::getClientList()
{ {
return _clientList; return _clientList;
} }
SensorNetwork* Gateway::getSensorNetwork() SensorNetwork* Gateway::getSensorNetwork()
{ {
return &_sensorNetwork; return &_sensorNetwork;
} }
LightIndicator* Gateway::getLightIndicator() LightIndicator* Gateway::getLightIndicator()
{ {
return &_lightIndicator; return &_lightIndicator;
} }
GatewayParams* Gateway::getGWParams(void) GatewayParams* Gateway::getGWParams(void)
{ {
return &_params; return &_params;
} }
AdapterManager* Gateway::getAdapterManager(void) AdapterManager* Gateway::getAdapterManager(void)
@@ -388,102 +426,98 @@ Topics* Gateway::getTopics(void)
bool Gateway::hasSecureConnection(void) bool Gateway::hasSecureConnection(void)
{ {
return ( _params.certKey return (_params.certKey && _params.privateKey && _params.rootCApath && _params.rootCAfile);
&& _params.privateKey
&& _params.rootCApath
&& _params.rootCAfile );
} }
/*===================================== /*=====================================
Class EventQue Class EventQue
=====================================*/ =====================================*/
EventQue::EventQue() EventQue::EventQue()
{ {
} }
EventQue::~EventQue() EventQue::~EventQue()
{ {
_mutex.lock(); _mutex.lock();
while (_que.size() > 0) while (_que.size() > 0)
{ {
delete _que.front(); delete _que.front();
_que.pop(); _que.pop();
} }
_mutex.unlock(); _mutex.unlock();
} }
void EventQue::setMaxSize(uint16_t maxSize) void EventQue::setMaxSize(uint16_t maxSize)
{ {
_que.setMaxSize((int)maxSize); _que.setMaxSize((int) maxSize);
} }
Event* EventQue::wait(void) Event* EventQue::wait(void)
{ {
Event* ev = nullptr; Event* ev = nullptr;
while(ev == nullptr) while (ev == nullptr)
{ {
if ( _que.size() == 0 ) if (_que.size() == 0)
{ {
_sem.wait(); _sem.wait();
} }
_mutex.lock(); _mutex.lock();
ev = _que.front(); ev = _que.front();
_que.pop(); _que.pop();
_mutex.unlock(); _mutex.unlock();
} }
return ev; return ev;
} }
Event* EventQue::timedwait(uint16_t millsec) Event* EventQue::timedwait(uint16_t millsec)
{ {
Event* ev; Event* ev;
if ( _que.size() == 0 ) if (_que.size() == 0)
{ {
_sem.timedwait(millsec); _sem.timedwait(millsec);
} }
_mutex.lock(); _mutex.lock();
if (_que.size() == 0) if (_que.size() == 0)
{ {
ev = new Event(); ev = new Event();
ev->setTimeout(); ev->setTimeout();
} }
else else
{ {
ev = _que.front(); ev = _que.front();
_que.pop(); _que.pop();
} }
_mutex.unlock(); _mutex.unlock();
return ev; return ev;
} }
void EventQue::post(Event* ev) void EventQue::post(Event* ev)
{ {
if ( ev ) if (ev)
{ {
_mutex.lock(); _mutex.lock();
if ( _que.post(ev) ) if (_que.post(ev))
{ {
_sem.post(); _sem.post();
} }
else else
{ {
delete ev; delete ev;
} }
_mutex.unlock(); _mutex.unlock();
} }
} }
int EventQue::size() int EventQue::size()
{ {
_mutex.lock(); _mutex.lock();
int sz = _que.size(); int sz = _que.size();
_mutex.unlock(); _mutex.unlock();
return sz; return sz;
} }
/*===================================== /*=====================================
Class Event Class Event
=====================================*/ =====================================*/
@@ -494,96 +528,95 @@ Event::Event()
Event::~Event() Event::~Event()
{ {
if (_sensorNetAddr) if (_sensorNetAddr)
{ {
delete _sensorNetAddr; delete _sensorNetAddr;
} }
if (_mqttSNPacket) if (_mqttSNPacket)
{ {
delete _mqttSNPacket; delete _mqttSNPacket;
} }
if (_mqttGWPacket) if (_mqttGWPacket)
{ {
delete _mqttGWPacket; delete _mqttGWPacket;
} }
} }
EventType Event::getEventType() EventType Event::getEventType()
{ {
return _eventType; return _eventType;
} }
void Event::setClientSendEvent(Client* client, MQTTSNPacket* packet) void Event::setClientSendEvent(Client* client, MQTTSNPacket* packet)
{ {
_client = client; _client = client;
_eventType = EtClientSend; _eventType = EtClientSend;
_mqttSNPacket = packet; _mqttSNPacket = packet;
} }
void Event::setBrokerSendEvent(Client* client, MQTTGWPacket* packet) void Event::setBrokerSendEvent(Client* client, MQTTGWPacket* packet)
{ {
_client = client; _client = client;
_eventType = EtBrokerSend; _eventType = EtBrokerSend;
_mqttGWPacket = packet; _mqttGWPacket = packet;
} }
void Event::setClientRecvEvent(Client* client, MQTTSNPacket* packet) void Event::setClientRecvEvent(Client* client, MQTTSNPacket* packet)
{ {
_client = client; _client = client;
_eventType = EtClientRecv; _eventType = EtClientRecv;
_mqttSNPacket = packet; _mqttSNPacket = packet;
} }
void Event::setBrokerRecvEvent(Client* client, MQTTGWPacket* packet) void Event::setBrokerRecvEvent(Client* client, MQTTGWPacket* packet)
{ {
_client = client; _client = client;
_eventType = EtBrokerRecv; _eventType = EtBrokerRecv;
_mqttGWPacket = packet; _mqttGWPacket = packet;
} }
void Event::setTimeout(void) void Event::setTimeout(void)
{ {
_eventType = EtTimeout; _eventType = EtTimeout;
} }
void Event::setStop(void) void Event::setStop(void)
{ {
_eventType = EtStop; _eventType = EtStop;
} }
void Event::setBrodcastEvent(MQTTSNPacket* msg) void Event::setBrodcastEvent(MQTTSNPacket* msg)
{ {
_mqttSNPacket = msg; _mqttSNPacket = msg;
_eventType = EtBroadcast; _eventType = EtBroadcast;
} }
void Event::setClientSendEvent(SensorNetAddress* addr, MQTTSNPacket* msg) void Event::setClientSendEvent(SensorNetAddress* addr, MQTTSNPacket* msg)
{ {
_eventType = EtSensornetSend; _eventType = EtSensornetSend;
_sensorNetAddr = addr; _sensorNetAddr = addr;
_mqttSNPacket = msg; _mqttSNPacket = msg;
} }
Client* Event::getClient(void) Client* Event::getClient(void)
{ {
return _client; return _client;
} }
SensorNetAddress* Event::getSensorNetAddress(void) SensorNetAddress* Event::getSensorNetAddress(void)
{ {
return _sensorNetAddr; return _sensorNetAddr;
} }
MQTTSNPacket* Event::getMQTTSNPacket() MQTTSNPacket* Event::getMQTTSNPacket()
{ {
return _mqttSNPacket; return _mqttSNPacket;
} }
MQTTGWPacket* Event::getMQTTGWPacket(void) MQTTGWPacket* Event::getMQTTGWPacket(void)
{ {
return _mqttGWPacket; return _mqttGWPacket;
} }

Some files were not shown because too many files have changed in this diff Show More