mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2026-02-03 12:03:44 +01:00
232
.cproject
232
.cproject
@@ -1,352 +1,192 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?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">
|
<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">
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||||
|
|
||||||
<externalSettings/>
|
<externalSettings/>
|
||||||
|
|
||||||
<extensions>
|
<extensions>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.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.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<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">
|
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1685199227" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||||
|
|
||||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1685199227." name="/" resourcePath="">
|
<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">
|
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.102264757" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||||
|
|
||||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2137160061" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
<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"/>
|
||||||
<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"/>
|
|
||||||
|
|
||||||
<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.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">
|
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.109068141" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||||
|
|
||||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1710260957" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
<option id="gnu.cpp.compiler.exe.debug.option.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"/>
|
||||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1258567310" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
|
||||||
|
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="" valueType="string"/>
|
||||||
<option id="gnu.cpp.compiler.option.dialect.std.1678347248" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
|
|
||||||
|
|
||||||
<option id="gnu.cpp.compiler.option.dialect.flags.1711182709" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
|
||||||
|
|
||||||
<option 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">
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1361987608" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNClient/src}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
|
||||||
|
|
||||||
</option>
|
</option>
|
||||||
|
<option id="gnu.cpp.compiler.option.debugging.sanitleak.778932189" name="Sanitize memory leak (-fsanitize=leak)" superClass="gnu.cpp.compiler.option.debugging.sanitleak" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||||
|
<option id="gnu.cpp.compiler.option.debugging.sanitpointers.435146187" name="Sanitize pointer operations (-fsanitize=pointer-compare -fsanitize=pointer-subtract)" superClass="gnu.cpp.compiler.option.debugging.sanitpointers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||||
|
<option id="gnu.cpp.compiler.option.debugging.sanitaddress.501742254" name="Sanitize address (-fsanitize=address)" superClass="gnu.cpp.compiler.option.debugging.sanitaddress" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.1354093543" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||||
|
<listOptionValue builtIn="false" value="DTLS"/>
|
||||||
|
</option>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1626802967" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||||
|
|
||||||
</tool>
|
</tool>
|
||||||
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
<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 defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1941536725" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||||
|
|
||||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1668726974" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.798283837" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||||
|
<listOptionValue builtIn="false" value="OPENSSL_API_COMPAT=30000"/>
|
||||||
|
</option>
|
||||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1870583388" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/dtls}""/>
|
||||||
|
</option>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.814497727" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||||
|
|
||||||
</tool>
|
</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">
|
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1881440001" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
|
||||||
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.910023243" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||||
|
|
||||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||||
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||||
|
|
||||||
</inputType>
|
</inputType>
|
||||||
|
|
||||||
</tool>
|
</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">
|
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.581660133" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||||
|
|
||||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1848275182" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
<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" srcPrefixMapping="" srcRootPath="" value="pthread"/>
|
<listOptionValue builtIn="false" value="crypto"/>
|
||||||
|
<listOptionValue builtIn="false" value="pthread"/>
|
||||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
<listOptionValue builtIn="false" value="bluetooth"/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
|
||||||
|
|
||||||
</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">
|
<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"/>
|
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||||
|
|
||||||
</option>
|
</option>
|
||||||
|
<option id="gnu.cpp.link.option.shared.1648098307" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.98211496" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||||
|
|
||||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||||
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||||
|
|
||||||
</inputType>
|
</inputType>
|
||||||
|
|
||||||
</tool>
|
</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.assembler.exe.debug.1531154076" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||||
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1193873077" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||||
|
|
||||||
</tool>
|
</tool>
|
||||||
|
|
||||||
</toolChain>
|
</toolChain>
|
||||||
|
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
|
|
||||||
<sourceEntries>
|
<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"/>
|
||||||
<entry excluding="MQTTSNGateway/src/linux/loralink|MQTTSNGateway/GatewayTester|MQTTSNGateway/GatewayTester/samples|MQTTSNGateway/src/linux/udp6|MQTTSNClient|MQTTSNGateway/src/MQTTSNGWProxy.cpp|MQTTSNPacket/test|MQTTSNPacket/samples|MQTTSNGateway/src/mainLogmonitor.cpp|MQTTSNGateway/src/linux/xbee|MQTTSNGateway/GatewayTester/samples/mainTemplate.cpp|MQTTSNGateway/src/tests|MQTTSNGateway/src/tests/mainTestProcessFramework.cpp|ClientPubQoS-1|MQTTSNGateway/GatewayTester/samples/mainOTA.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
<entry excluding="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||||
|
<entry excluding="samples|test" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
|
|
||||||
</cconfiguration>
|
</cconfiguration>
|
||||||
|
|
||||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.561557339">
|
||||||
|
|
||||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.561557339" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
<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/>
|
<externalSettings/>
|
||||||
|
|
||||||
<extensions>
|
<extensions>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.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.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" optionalBuildProperties="" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
|
||||||
|
|
||||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.561557339." name="/" resourcePath="">
|
||||||
|
|
||||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.474335535" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
<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"/>
|
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.338327831" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||||
|
|
||||||
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
<builder buildPath="${workspace_loc:/MQTTSN-embedded-C}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1268563010" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||||
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1908794347" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||||
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||||
|
|
||||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.15425920" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||||
|
|
||||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.857802503" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||||
|
|
||||||
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
<option id="gnu.cpp.compiler.option.dialect.flags.1078302249" name="Other dialect flags" superClass="gnu.cpp.compiler.option.dialect.flags" useByScannerDiscovery="true" value="-std=c++11" valueType="string"/>
|
||||||
|
|
||||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.2114194326" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux/udp}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNPacket/src}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src/linux}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/src}""/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/MQTTSNGateway/GatewayTester/src}""/>
|
||||||
|
|
||||||
</option>
|
</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"/>
|
<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"/>
|
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||||
|
|
||||||
</tool>
|
</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">
|
<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 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"/>
|
<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"/>
|
<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">
|
<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">
|
<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="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||||
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||||
|
|
||||||
</inputType>
|
</inputType>
|
||||||
|
|
||||||
</tool>
|
</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">
|
<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">
|
<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="pthread"/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="ssl"/>
|
||||||
|
|
||||||
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="crypto"/>
|
||||||
|
|
||||||
</option>
|
</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">
|
<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"/>
|
<listOptionValue builtIn="false" value="/usr/local/lib"/>
|
||||||
|
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2044523925" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
<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="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||||
|
|
||||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||||
|
|
||||||
</inputType>
|
</inputType>
|
||||||
|
|
||||||
</tool>
|
</tool>
|
||||||
|
|
||||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.67939689" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
<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"/>
|
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.651929038" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||||
|
|
||||||
</tool>
|
</tool>
|
||||||
|
|
||||||
</toolChain>
|
</toolChain>
|
||||||
|
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
|
|
||||||
<sourceEntries>
|
<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=""/>
|
||||||
<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="mainTest.cpp|ClientSub|ClientPubQoS-1|ClientPub" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/GatewayTester/samples"/>
|
||||||
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="MQTTSNGateway/src"/>
|
||||||
<entry 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"/>
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="MQTTSNPacket/src"/>
|
||||||
|
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
|
|
||||||
</cconfiguration>
|
</cconfiguration>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<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"/>
|
<project id="MQTTSN-embedded-C.cdt.managedbuild.target.gnu.exe.317758410" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||||
|
|
||||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||||
|
<configuration configurationName="Debug"/>
|
||||||
<configuration configurationName="Release">
|
<configuration configurationName="Release">
|
||||||
|
|
||||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
<configuration configurationName="Debug">
|
|
||||||
|
|
||||||
<resource resourceType="PROJECT" workspacePath="/MQTTSN-embedded-C"/>
|
|
||||||
|
|
||||||
</configuration>
|
|
||||||
|
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||||
|
|
||||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||||
|
|
||||||
<storageModule moduleId="scannerConfiguration">
|
<storageModule moduleId="scannerConfiguration">
|
||||||
|
|
||||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
<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">
|
<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=""/>
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
|
||||||
</scannerConfigBuildInfo>
|
</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">
|
<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=""/>
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
|
||||||
</scannerConfigBuildInfo>
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1685199227;cdt.managedbuild.config.gnu.exe.debug.1685199227.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2017162618;cdt.managedbuild.tool.gnu.c.compiler.input.814497727">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
|
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.561557339;cdt.managedbuild.config.gnu.exe.release.561557339.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1903732701;cdt.managedbuild.tool.gnu.cpp.compiler.input.1606625536">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||||
|
</scannerConfigBuildInfo>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
||||||
</cproject>
|
</cproject>
|
||||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -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/
|
||||||
@@ -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">
|
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||||
|
|
||||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
<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.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
|
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" 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="-176156747064280842" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
|
||||||
|
|
||||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
|
|
||||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
|
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
<configuration id="cdt.managedbuild.config.gnu.exe.release.561557339" name="Release">
|
||||||
|
|
||||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||||
|
|
||||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
<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.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
|
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" 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="-176157551606184930" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-179845344490928458" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
|
||||||
|
|
||||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
|
|
||||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
|
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
77
.settings/org.eclipse.cdt.codan.core.prefs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
fr.ac6.mcu.ide.source.checker.libnano.problem=Error
|
||||||
|
fr.ac6.mcu.ide.source.checker.libnano.problem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Float formatting support\\")"}
|
||||||
|
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||||
|
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
||||||
|
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||||
|
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
||||||
|
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||||
|
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
||||||
|
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||||
|
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
||||||
|
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||||
|
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||||
|
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
||||||
|
org.eclipse.cdt.qt.core.qtproblem=Warning
|
||||||
|
org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null}
|
||||||
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
2
.settings/org.eclipse.cdt.ui.prefs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
formatter_settings_version=1
|
||||||
12
.travis.yml
12
.travis.yml
@@ -13,20 +13,12 @@ addons:
|
|||||||
- g++-4.8
|
- 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:
|
||||||
- tomoaki@tomy-tech.com
|
- tomoaki@tomy-tech.com
|
||||||
|
|||||||
@@ -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)
|
||||||
16
MQTTSNGateway/CMakeLists.txt
Normal file
16
MQTTSNGateway/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#*******************************************************************************
|
||||||
|
# Copyright (c) 2022 a1lu
|
||||||
|
#
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
#
|
||||||
|
# The Eclipse Public License is available at
|
||||||
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
# and the Eclipse Distribution License is available at
|
||||||
|
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
#
|
||||||
|
# Contributors:
|
||||||
|
# a1lu - initial version
|
||||||
|
#*******************************************************************************/
|
||||||
|
ADD_SUBDIRECTORY(src)
|
||||||
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
BIN
MQTTSNGateway/Gateway Overview.pdf
Normal file
Binary file not shown.
@@ -20,6 +20,10 @@ CPPSRCS := \
|
|||||||
$(SUBDIR)/LGwProxy.cpp \
|
$(SUBDIR)/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)
|
||||||
|
|||||||
@@ -1,28 +1,7 @@
|
|||||||
###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];
|
||||||
@@ -36,9 +15,35 @@ 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
|
||||||
*------------------------------------------------------*/
|
*------------------------------------------------------*/
|
||||||
@@ -52,68 +57,61 @@ TEST_LIST = {// e.g. TEST( Label, Test),
|
|||||||
TEST("Disconnect", test5),
|
TEST("Disconnect", test5),
|
||||||
END_OF_TEST_LIST
|
END_OF_TEST_LIST
|
||||||
};
|
};
|
||||||
````
|
|
||||||
|
|
||||||
### **step1. Build **
|
|
||||||
````
|
|
||||||
$ git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
|
||||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
|
||||||
$ make
|
|
||||||
$ make install
|
|
||||||
$ make clean
|
|
||||||
```
|
```
|
||||||
MQTT-SNGatewayTester program is copied into ../../../ directory.
|
|
||||||
|
**UDP**, **DTLS**, **UDP6**, **DTLS6** or **Bluetooth** is available as a sensor network.
|
||||||
|
```
|
||||||
|
/*------------------------------------------------------
|
||||||
|
* UDP, DTLS Configuration (theNetcon)
|
||||||
|
*------------------------------------------------------*/
|
||||||
|
UDPCONF = { "GatewayTestClient", // ClientId
|
||||||
|
{ 225, 1, 1, 1 }, // Multicast group IP
|
||||||
|
1883, // Multicast group Port
|
||||||
|
20020, // Local PortNo
|
||||||
|
};
|
||||||
|
|
||||||
|
/*------------------------------------------------------
|
||||||
|
* UDP6, DTLS6 Configuration (theNetcon)
|
||||||
|
*------------------------------------------------------*/
|
||||||
|
UDP6CONF = { "GatewayTestClient", // ClientId
|
||||||
|
"ff12::feed:caca:dead", // Multicast group IP
|
||||||
|
"wlp4s0",
|
||||||
|
1883, // Multicast group Port
|
||||||
|
20020, // Local PortNo
|
||||||
|
};
|
||||||
|
|
||||||
|
/*------------------------------------------------------
|
||||||
|
* RFCOMM Configuration (theNetcon)
|
||||||
|
*------------------------------------------------------*/
|
||||||
|
RFCOMMCONF = { "GatewayTestClient", // ClientId
|
||||||
|
"60:57:18:06:8B:72", // GW Address
|
||||||
|
1, // Rfcomm channel
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### **step2. Execute Gateway Tester.**
|
## How to Build
|
||||||
|
```
|
||||||
|
copy codes from the github.
|
||||||
|
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway/GatewayTester
|
||||||
|
$ ./build.sh [udp | udp6 | dtls | dtls6 | rfcomm]
|
||||||
|
```
|
||||||
|
|
||||||
````
|
|
||||||
$ cd ../../..
|
## Execute Gateway Tester
|
||||||
$ ./MQTT-SNGatewayTester
|
```
|
||||||
|
$ ./Build/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 ) :
|
|
||||||
|
|
||||||
````
|
|
||||||
|
|||||||
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
23
MQTTSNGateway/GatewayTester/build.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DEF1="DEF1=${2}"
|
||||||
|
DEF2="DEF2=${3}"
|
||||||
|
|
||||||
|
if [ $1 == "udp" ] ; then
|
||||||
|
make SN=UDP $DEF1 $DEF2
|
||||||
|
elif [ $1 == "udp6" ] ; then
|
||||||
|
make SN=UDP6 $DEF1 $DEF2
|
||||||
|
elif [ $1 == "rfcomm" ] ; then
|
||||||
|
export LDADDBLT=-lbluetooth
|
||||||
|
make SN=RFCOMM $DEF1 $DEF2
|
||||||
|
elif [ $1 == "dtls" ] ; then
|
||||||
|
make SN=DTLS $DEF1 $DEF2
|
||||||
|
elif [ $1 == "dtls6" ] ; then
|
||||||
|
make SN=DTLS6 $DEF1 $DEF2
|
||||||
|
elif [ $1 == "clean" ] ; then
|
||||||
|
make clean
|
||||||
|
else
|
||||||
|
echo "Usage: build.sh [ udp | udp6 | rfcomm | dtls | dtls6 | clean]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -51,13 +51,30 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,13 +51,30 @@ 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)
|
||||||
*------------------------------------------------------*/
|
*------------------------------------------------------*/
|
||||||
|
|||||||
@@ -51,13 +51,30 @@ 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)
|
||||||
*------------------------------------------------------*/
|
*------------------------------------------------------*/
|
||||||
|
|||||||
@@ -49,20 +49,36 @@ 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
|
||||||
@@ -78,12 +94,12 @@ 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
|
||||||
*------------------------------------------------------*/
|
*------------------------------------------------------*/
|
||||||
@@ -112,37 +128,40 @@ int on_Topic03(uint8_t* pload, uint16_t ploadlen)
|
|||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------
|
/*------------------------------------------------------
|
||||||
* 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 =
|
||||||
|
{ // e.g. SUB(TopicType, topicName, TopicId, callback, QoSx),
|
||||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic1, 0, on_Topic01, QoS1),
|
||||||
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
SUB(MQTTSN_TOPIC_TYPE_NORMAL, topic2, 0, on_Topic02, QoS1),
|
||||||
END_OF_SUBSCRIBE_LIST
|
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];
|
||||||
@@ -150,6 +169,22 @@ void publishTopic2(void)
|
|||||||
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)
|
||||||
@@ -180,41 +215,70 @@ 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("Step3:Publish topic1", publishTopic1),
|
||||||
TEST("Step4:Publish topic2", publishTopic2),
|
TEST("Step4:Publish topic2", publishTopic2),
|
||||||
TEST("Step5:Unsubscribe topic2", unsubscribe),
|
TEST("Step5:Subscribe PreDefined topic10. ID is not defined.", subscribeTopic10),
|
||||||
TEST("Step6:Publish topic2", publishTopic2),
|
TEST("Step6:Publish topic2", publishTopic2),
|
||||||
TEST("Step7:subscribe again", subscribechangeCallback),
|
TEST("Step7:Unsubscribe topic2", unsubscribe),
|
||||||
TEST("Step8:Publish topic2", publishTopic2),
|
TEST("Step8:Publish topic2", publishTopic2),
|
||||||
TEST("Step9:Sleep ", asleep),
|
TEST("Step9:subscribe again", subscribechangeCallback),
|
||||||
TEST("Step10:Publish topic1", publishTopic1),
|
TEST("Step10:Publish topic2", publishTopic2),
|
||||||
TEST("Step11:Disconnect", disconnect),
|
|
||||||
|
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
|
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 =
|
||||||
|
{ // e.g. TASK( task, executing duration in second),
|
||||||
TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
|
TASK(publishTopic1, 4),// publishTopic1() is executed every 4 seconds
|
||||||
TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
|
TASK(publishTopic2, 7),// publishTopic2() is executed every 7 seconds
|
||||||
END_OF_TASK_LIST
|
END_OF_TASK_LIST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------
|
/*------------------------------------------------------
|
||||||
* Initialize function
|
* Initialize function
|
||||||
*------------------------------------------------------*/
|
*------------------------------------------------------*/
|
||||||
@@ -223,5 +287,4 @@ void setup(void)
|
|||||||
SetForwarderMode(false);
|
SetForwarderMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************** END OF PROGRAM ********************/
|
/***************** END OF PROGRAM ********************/
|
||||||
|
|||||||
@@ -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;
|
_status = GW_CONNECTING;
|
||||||
|
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection established.\033[0m\033[0;37m\n\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DISPLAY("\033[0m\033[0;32m\n\nLGwProxy::getConnectResponce DTLS connection failed.\033[0m\033[0;37m\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
_status = GW_CONNECTING;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
else if (_mqttsnMsg[0] == MQTTSN_TYPE_WILLTOPICREQ && _status == GW_WAIT_WILLTOPICREQ)
|
||||||
{
|
{
|
||||||
@@ -230,11 +259,14 @@ int LGwProxy::getConnectResponce(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LGwProxy::reconnect(void)
|
void LGwProxy::reconnect(void)
|
||||||
|
{
|
||||||
|
if (_isAutoConnectMode)
|
||||||
{
|
{
|
||||||
D_MQTTLOG("...Gateway reconnect\r\n");
|
D_MQTTLOG("...Gateway reconnect\r\n");
|
||||||
_status = GW_DISCONNECTED;
|
_status = GW_DISCONNECTED;
|
||||||
connect();
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -111,6 +120,8 @@ private:
|
|||||||
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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -204,11 +220,21 @@ void LMqttsnClient::disconnect(uint16_t sleepInSecs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LMqttsnClient::run()
|
void LMqttsnClient::run()
|
||||||
|
{
|
||||||
|
if (_isAutoConnect)
|
||||||
{
|
{
|
||||||
_gwProxy.connect();
|
_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
|
||||||
@@ -226,9 +252,12 @@ 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 " ***************************************************************************"
|
||||||
|
|
||||||
|
|||||||
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
544
MQTTSNGateway/GatewayTester/src/LNetworkDtls.cpp
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
#ifdef DTLS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include "LMqttsnClientApp.h"
|
||||||
|
#include "LNetworkDtls.h"
|
||||||
|
#include "LTimer.h"
|
||||||
|
#include "LScreen.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace linuxAsyncClient;
|
||||||
|
|
||||||
|
extern uint16_t getUint16(const uint8_t* pos);
|
||||||
|
extern uint32_t getUint32(const uint8_t* pos);
|
||||||
|
extern LScreen* theScreen;
|
||||||
|
extern bool theClientMode;
|
||||||
|
|
||||||
|
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||||
|
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class LNetwork
|
||||||
|
=========================================*/
|
||||||
|
LNetwork::LNetwork()
|
||||||
|
{
|
||||||
|
_sleepflg = false;
|
||||||
|
resetGwAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
LNetwork::~LNetwork()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LDtlsPort::multicast(xmitData, (uint32_t) dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LDtlsPort::unicast(xmitData, dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t* LNetwork::getMessage(int *len)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
uint16_t recvLen = 0;
|
||||||
|
if (checkRecvBuf())
|
||||||
|
{
|
||||||
|
recvLen = LDtlsPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||||
|
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recvLen < 0)
|
||||||
|
{
|
||||||
|
*len = recvLen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_rxDataBuf[0] == 0x01)
|
||||||
|
{
|
||||||
|
*len = getUint16(_rxDataBuf + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*len = _rxDataBuf[0];
|
||||||
|
}
|
||||||
|
return _rxDataBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setGwAddress(void)
|
||||||
|
{
|
||||||
|
_gwPortNo = _portNo;
|
||||||
|
_gwIpAddress = _ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::resetGwAddress(void)
|
||||||
|
{
|
||||||
|
_gwIpAddress = 0;
|
||||||
|
_gwPortNo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LNetwork::initialize(LUdpConfig *config)
|
||||||
|
{
|
||||||
|
return LDtlsPort::open(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setSleep()
|
||||||
|
{
|
||||||
|
_sleepflg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::isBroadcastable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::sslConnect(void)
|
||||||
|
{
|
||||||
|
return LDtlsPort::sslConnect(_gwIpAddress, _gwPortNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class DtlsPort
|
||||||
|
=========================================*/
|
||||||
|
LDtlsPort::LDtlsPort()
|
||||||
|
{
|
||||||
|
_disconReq = false;
|
||||||
|
_sockfdMcast = 0;
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
_castStat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LDtlsPort::~LDtlsPort()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LDtlsPort::close()
|
||||||
|
{
|
||||||
|
if (_sockfdMcast > 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdMcast);
|
||||||
|
_sockfdMcast = 0;
|
||||||
|
if (_sockfdSsl > 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtlsPort::open(LUdpConfig *config)
|
||||||
|
{
|
||||||
|
char errmsg[256];
|
||||||
|
int optval = 0;
|
||||||
|
|
||||||
|
uint8_t sav = config->ipAddress[3];
|
||||||
|
config->ipAddress[3] = config->ipAddress[0];
|
||||||
|
config->ipAddress[0] = sav;
|
||||||
|
sav = config->ipAddress[2];
|
||||||
|
config->ipAddress[2] = config->ipAddress[1];
|
||||||
|
config->ipAddress[1] = sav;
|
||||||
|
|
||||||
|
_gIpAddr = getUint32((const uint8_t*) config->ipAddress);
|
||||||
|
_gPortNo = htons(config->gPortNo);
|
||||||
|
_uPortNo = htons(config->uPortNo);
|
||||||
|
|
||||||
|
if (_gPortNo == 0 || _gIpAddr == 0 || _uPortNo == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||||
|
|
||||||
|
if (_ctx == 0)
|
||||||
|
{
|
||||||
|
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||||
|
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Client certification and cookie are not required */
|
||||||
|
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||||
|
|
||||||
|
/* setup Multicast socket */
|
||||||
|
_sockfdMcast = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (_sockfdMcast < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addrm;
|
||||||
|
addrm.sin_family = AF_INET;
|
||||||
|
addrm.sin_port = _gPortNo;
|
||||||
|
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
|
||||||
|
if (::bind(_sockfdMcast, (struct sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_mreq mreq;
|
||||||
|
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||||
|
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||||
|
|
||||||
|
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in LDtlsPort::open\033[0m\033[0;37m\n");
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtlsPort::isUnicast()
|
||||||
|
{
|
||||||
|
return (_castStat == STAT_UNICAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LDtlsPort::unicast(const uint8_t *buf, uint32_t length)
|
||||||
|
{
|
||||||
|
int status = SSL_write(_ssl, buf, length);
|
||||||
|
if (status <= 0)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
SSL_get_error(_ssl, rc);
|
||||||
|
DISPLAY("errno == %d in LDtlsPort::unicast\n", rc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("sendto gateway via DTLS ");
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LDtlsPort::multicast(const uint8_t *buf, uint32_t length)
|
||||||
|
{
|
||||||
|
struct sockaddr_in dest;
|
||||||
|
dest.sin_family = AF_INET;
|
||||||
|
dest.sin_port = _gPortNo;
|
||||||
|
dest.sin_addr.s_addr = _gIpAddr;
|
||||||
|
|
||||||
|
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||||
|
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::multicast\033[0m\033[0;37m\n", errno);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("sendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
DISPLAY(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtlsPort::checkRecvBuf()
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 50000; // 50 msec
|
||||||
|
|
||||||
|
uint8_t buf[2];
|
||||||
|
fd_set recvfds;
|
||||||
|
int maxSock = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&recvfds);
|
||||||
|
if (_sockfdMcast)
|
||||||
|
{
|
||||||
|
FD_SET(_sockfdMcast, &recvfds);
|
||||||
|
}
|
||||||
|
if (_sockfdSsl)
|
||||||
|
{
|
||||||
|
FD_SET(_sockfdSsl, &recvfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sockfdMcast > _sockfdSsl)
|
||||||
|
{
|
||||||
|
maxSock = _sockfdMcast;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxSock = _sockfdSsl;
|
||||||
|
}
|
||||||
|
|
||||||
|
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||||
|
|
||||||
|
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||||
|
{
|
||||||
|
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
_castStat = STAT_MULTICAST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||||
|
{
|
||||||
|
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
_castStat = STAT_SSL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_castStat = STAT_NONE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtlsPort::recv(uint8_t *buf, uint16_t len, bool flg, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||||
|
{
|
||||||
|
int flags = flg ? MSG_DONTWAIT : 0;
|
||||||
|
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtlsPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, in_port_t *portPtr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sender;
|
||||||
|
int status = 0;
|
||||||
|
socklen_t addrlen = sizeof(sender);
|
||||||
|
memset(&sender, 0, addrlen);
|
||||||
|
|
||||||
|
if (_castStat == STAT_SSL)
|
||||||
|
{
|
||||||
|
D_NWLOG("Ucast ");
|
||||||
|
if (SSL_read(_ssl, buf, length) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_castStat == STAT_MULTICAST)
|
||||||
|
{
|
||||||
|
D_NWLOG("Mcast ");
|
||||||
|
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
|
DISPLAY("\033[0m\033[0;31merrno == %d in LDtlsPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
|
}
|
||||||
|
else if (status > 0)
|
||||||
|
{
|
||||||
|
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||||
|
*portPtr = sender.sin_port;
|
||||||
|
|
||||||
|
D_NWLOG("recved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", inet_ntoa(sender.sin_addr), ntohs(*portPtr));
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtlsPort::sslConnect(uint32_t ipAddress, in_port_t portNo)
|
||||||
|
{
|
||||||
|
int reuse = 1;
|
||||||
|
if (_ssl != 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect SSL exists.\n");
|
||||||
|
SSL_shutdown(_ssl);
|
||||||
|
SSL_free(_ssl);
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
_ssl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sockfdSsl > 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect socket exists.\n");
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sockfdSsl = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (_sockfdSsl < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect Can't create a socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = _uPortNo;
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in dest;
|
||||||
|
dest.sin_family = AF_INET;
|
||||||
|
dest.sin_port = portNo;
|
||||||
|
dest.sin_addr.s_addr = ipAddress;
|
||||||
|
int rc = 0;
|
||||||
|
errno = 0;
|
||||||
|
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||||
|
connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in));
|
||||||
|
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest);
|
||||||
|
_ssl = SSL_new(_ctx);
|
||||||
|
SSL_set_bio(_ssl, cbio, cbio);
|
||||||
|
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect connect to %-15s:%-6u\n", inet_ntoa(dest.sin_addr), htons(dest.sin_port));
|
||||||
|
|
||||||
|
timeval timeout;
|
||||||
|
timeout.tv_sec = 5;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||||
|
|
||||||
|
int stat = SSL_connect(_ssl);
|
||||||
|
if (stat != 1)
|
||||||
|
{
|
||||||
|
rc = -1;
|
||||||
|
D_NWLOG("SSL fail to connect\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
D_NWLOG("SSL connected\n");
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
118
MQTTSNGateway/GatewayTester/src/LNetworkDtls.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2016, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef NETWORKDTLS_H_
|
||||||
|
#define NETWORKDTLS_H_
|
||||||
|
|
||||||
|
#ifdef DTLS
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#define SOCKET_MAXHOSTNAME 200
|
||||||
|
#define SOCKET_MAXCONNECTIONS 5
|
||||||
|
#define SOCKET_MAXRECV 500
|
||||||
|
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace linuxAsyncClient {
|
||||||
|
#define STAT_NONE 0
|
||||||
|
#define STAT_UNICAST 1
|
||||||
|
#define STAT_MULTICAST 2
|
||||||
|
#define STAT_SSL 3
|
||||||
|
/*========================================
|
||||||
|
Class LDtlsPort
|
||||||
|
=======================================*/
|
||||||
|
class LDtlsPort
|
||||||
|
{
|
||||||
|
friend class LNetwork;
|
||||||
|
public:
|
||||||
|
LDtlsPort();
|
||||||
|
virtual ~LDtlsPort();
|
||||||
|
|
||||||
|
bool open(LUdpConfig* config);
|
||||||
|
|
||||||
|
int unicast(const uint8_t *buf, uint32_t length);
|
||||||
|
int multicast( const uint8_t* buf, uint32_t length );
|
||||||
|
int recv(uint8_t* buf, uint16_t len, bool nonblock, uint32_t* ipaddress, in_port_t* port );
|
||||||
|
int recv(uint8_t* buf, int flags);
|
||||||
|
bool checkRecvBuf();
|
||||||
|
bool isUnicast();
|
||||||
|
SSL* getSSL(void);
|
||||||
|
int sslConnect(uint32_t ipAddress, in_port_t port);
|
||||||
|
private:
|
||||||
|
void close();
|
||||||
|
int recvfrom ( uint8_t* buf, uint16_t len, int flags, uint32_t* ipaddress, in_port_t* port );
|
||||||
|
|
||||||
|
int _sockfdMcast;
|
||||||
|
int _sockfdSsl;
|
||||||
|
SSL_CTX *_ctx;
|
||||||
|
SSL *_ssl;
|
||||||
|
in_port_t _gPortNo;
|
||||||
|
in_port_t _uPortNo;
|
||||||
|
uint32_t _gIpAddr;
|
||||||
|
uint8_t _castStat;
|
||||||
|
bool _disconReq;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NO_ERROR 0
|
||||||
|
#define PACKET_EXCEEDS_LENGTH 1
|
||||||
|
/*===========================================
|
||||||
|
Class Network
|
||||||
|
============================================*/
|
||||||
|
class LNetwork: public LDtlsPort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LNetwork();
|
||||||
|
~LNetwork();
|
||||||
|
|
||||||
|
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
void setGwAddress(void);
|
||||||
|
void resetGwAddress(void);
|
||||||
|
bool initialize(LUdpConfig* config);
|
||||||
|
uint8_t* getMessage(int* len);
|
||||||
|
bool isBroadcastable();
|
||||||
|
int sslConnect(void);
|
||||||
|
private:
|
||||||
|
void setSleep();
|
||||||
|
int readApiFrame(void);
|
||||||
|
|
||||||
|
uint32_t _gwIpAddress;
|
||||||
|
uint32_t _ipAddress;
|
||||||
|
in_port_t _gwPortNo;
|
||||||
|
in_port_t _portNo;
|
||||||
|
int _returnCode;
|
||||||
|
bool _sleepflg;
|
||||||
|
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* end of namespace */
|
||||||
|
#endif /* DTLS */
|
||||||
|
#endif /* NETWORKDTLS_H_ */
|
||||||
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
586
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.cpp
Normal file
@@ -0,0 +1,586 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
#ifdef DTLS6
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include "LMqttsnClientApp.h"
|
||||||
|
#include "LNetworkDtls6.h"
|
||||||
|
#include "LTimer.h"
|
||||||
|
#include "LScreen.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace linuxAsyncClient;
|
||||||
|
|
||||||
|
extern uint16_t getUint16(const uint8_t *pos);
|
||||||
|
extern uint32_t getUint32(const uint8_t *pos);
|
||||||
|
extern LScreen *theScreen;
|
||||||
|
extern bool theClientMode;
|
||||||
|
|
||||||
|
/* Certificate verification. Returns 1 if trusted, else 0 */
|
||||||
|
int verify_cert(int ok, X509_STORE_CTX *ctx);
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class LNetwork
|
||||||
|
=========================================*/
|
||||||
|
LNetwork::LNetwork()
|
||||||
|
{
|
||||||
|
_sleepflg = false;
|
||||||
|
resetGwAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
LNetwork::~LNetwork()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LDtls6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LDtls6Port::unicast(xmitData, dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* LNetwork::getMessage(int *len)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
if (checkRecvBuf())
|
||||||
|
{
|
||||||
|
uint16_t recvLen = LDtls6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||||
|
int addrFlg = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||||
|
if (isUnicast() && addrFlg && (_portNo != _gwPortNo))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recvLen < 0)
|
||||||
|
{
|
||||||
|
*len = recvLen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_rxDataBuf[0] == 0x01)
|
||||||
|
{
|
||||||
|
*len = getUint16(_rxDataBuf + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*len = _rxDataBuf[0];
|
||||||
|
}
|
||||||
|
return _rxDataBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setGwAddress(void)
|
||||||
|
{
|
||||||
|
_gwPortNo = _portNo;
|
||||||
|
memcpy(&_gwIpAddress.s6_addr, &_ipAddress.s6_addr, sizeof(_ipAddress.s6_addr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::resetGwAddress(void)
|
||||||
|
{
|
||||||
|
memset(&_gwIpAddress, 0, sizeof(_gwIpAddress));
|
||||||
|
_gwPortNo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::initialize(LUdp6Config *config)
|
||||||
|
{
|
||||||
|
return LDtls6Port::open(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setSleep()
|
||||||
|
{
|
||||||
|
_sleepflg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::isBroadcastable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::sslConnect(void)
|
||||||
|
{
|
||||||
|
return LDtls6Port::sslConnect(_gwIpAddress, _gwPortNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class Dtls6Port
|
||||||
|
=========================================*/
|
||||||
|
LDtls6Port::LDtls6Port()
|
||||||
|
{
|
||||||
|
_disconReq = false;
|
||||||
|
_castStat = STAT_NONE;
|
||||||
|
_ifIndex = 0;
|
||||||
|
_gIpAddrStr = nullptr;
|
||||||
|
_sockfdMcast = 0;
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
_ctx = nullptr;
|
||||||
|
_ssl = nullptr;
|
||||||
|
_gPortNo = _uPortNo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LDtls6Port::~LDtls6Port()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
if (_gIpAddrStr)
|
||||||
|
{
|
||||||
|
free(_gIpAddrStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LDtls6Port::close()
|
||||||
|
{
|
||||||
|
if (_sockfdMcast > 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdMcast);
|
||||||
|
_sockfdMcast = 0;
|
||||||
|
if (_sockfdSsl > 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtls6Port::open(LUdp6Config *config)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
sockaddr_in6 addr6;
|
||||||
|
char errmsg[256];
|
||||||
|
|
||||||
|
_gPortNo = htons(config->gPortNo);
|
||||||
|
_uPortNo = htons(config->uPortNo);
|
||||||
|
|
||||||
|
if (_gPortNo == 0 || _uPortNo == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
_ctx = SSL_CTX_new(DTLS_client_method());
|
||||||
|
|
||||||
|
if (_ctx == 0)
|
||||||
|
{
|
||||||
|
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||||
|
DISPLAY("SSL_CTX_new() %s\n", errmsg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Client certification and cookie are not required */
|
||||||
|
SSL_CTX_set_verify(_ctx, SSL_VERIFY_PEER, verify_cert);
|
||||||
|
|
||||||
|
if (strlen(config->interface) > 0)
|
||||||
|
{
|
||||||
|
_ifIndex = if_nametoindex(config->interface);
|
||||||
|
_interfaceName = config->interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a multicast socket */
|
||||||
|
_sockfdMcast = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if (_sockfdMcast < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(_sockfdMcast, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||||
|
|
||||||
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
|
addr6.sin6_family = AF_INET6;
|
||||||
|
addr6.sin6_port = _gPortNo;
|
||||||
|
addr6.sin6_addr = in6addr_any;
|
||||||
|
|
||||||
|
if (::bind(_sockfdMcast, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6_mreq addrm;
|
||||||
|
addrm.ipv6mr_interface = _ifIndex;
|
||||||
|
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||||
|
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
if (setsockopt(_sockfdMcast, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gIpAddr.sin6_family = AF_INET6;
|
||||||
|
_gIpAddr.sin6_port = _gPortNo;
|
||||||
|
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||||
|
_gIpAddrStr = strdup(config->ipAddress);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtls6Port::isUnicast()
|
||||||
|
{
|
||||||
|
return (_castStat == STAT_UNICAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtls6Port::unicast(const uint8_t *buf, uint32_t length)
|
||||||
|
{
|
||||||
|
int status = SSL_write(_ssl, buf, length);
|
||||||
|
if (status <= 0)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
SSL_get_error(_ssl, rc);
|
||||||
|
DISPLAY("errno == %d in LDtls6Port::unicast\n", rc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("sendto gateway via DTLS6 ");
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34msendto the gateway via SSL ");
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtls6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
char portStr[8];
|
||||||
|
sprintf(portStr, "%d", ntohs(_gIpAddr.sin6_port));
|
||||||
|
|
||||||
|
int status = ::sendto(_sockfdMcast, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::multicast\033[0m\033[0;37m\n", errno);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LDtls6Port::checkRecvBuf()
|
||||||
|
{
|
||||||
|
timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 50000; // 50 msec
|
||||||
|
|
||||||
|
uint8_t buf[2];
|
||||||
|
fd_set recvfds;
|
||||||
|
int maxSock = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&recvfds);
|
||||||
|
if (_sockfdMcast)
|
||||||
|
{
|
||||||
|
FD_SET(_sockfdMcast, &recvfds);
|
||||||
|
}
|
||||||
|
if (_sockfdSsl)
|
||||||
|
{
|
||||||
|
FD_SET(_sockfdSsl, &recvfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sockfdMcast > _sockfdSsl)
|
||||||
|
{
|
||||||
|
maxSock = _sockfdMcast;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxSock = _sockfdSsl;
|
||||||
|
}
|
||||||
|
|
||||||
|
select(maxSock + 1, &recvfds, 0, 0, &timeout);
|
||||||
|
|
||||||
|
if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||||
|
{
|
||||||
|
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
_castStat = STAT_MULTICAST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FD_ISSET(_sockfdSsl, &recvfds))
|
||||||
|
{
|
||||||
|
if (::recv(_sockfdSsl, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
_castStat = STAT_SSL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_castStat = STAT_NONE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtls6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||||
|
{
|
||||||
|
int flags = flg ? MSG_DONTWAIT : 0;
|
||||||
|
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtls6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, in_port_t *portPtr)
|
||||||
|
{
|
||||||
|
sockaddr_in6 sender;
|
||||||
|
int status = 0;
|
||||||
|
socklen_t addrlen = sizeof(sender);
|
||||||
|
memset(&sender, 0, addrlen);
|
||||||
|
char addrBuf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
if (_castStat == STAT_SSL)
|
||||||
|
{
|
||||||
|
D_NWLOG("Ucast ");
|
||||||
|
if (SSL_read(_ssl, buf, length) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_castStat == STAT_MULTICAST)
|
||||||
|
{
|
||||||
|
D_NWLOG("Mcast ");
|
||||||
|
status = ::recvfrom(_sockfdMcast, buf, length, flags, (sockaddr*) &sender, &addrlen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
|
DISPLAY("\033[0m\033[0;31merrno == %d in LDtls6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
|
}
|
||||||
|
else if (status > 0)
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||||
|
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||||
|
*portPtr = sender.sin6_port;
|
||||||
|
|
||||||
|
D_NWLOG("recved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mrecved %-15s:%-6u", addrBuf, htons(*portPtr));
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LDtls6Port::sslConnect(in6_addr ipAddress, in_port_t portNo)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
|
||||||
|
if (_ssl != 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtls6Port::sslConnect SSL exists.\n");
|
||||||
|
SSL_shutdown(_ssl);
|
||||||
|
SSL_free(_ssl);
|
||||||
|
_sockfdSsl = 0;
|
||||||
|
_ssl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sockfdSsl > 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtls6Port::sslConnect socket exists.\n");
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sockfdSsl = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if (_sockfdSsl <= 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("LDtls6Port::sslConnect Can't create a socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(_sockfdSsl, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||||
|
setsockopt(_sockfdSsl, SOL_SOCKET, SO_REUSEADDR || SO_REUSEPORT, &optval, sizeof(optval));
|
||||||
|
|
||||||
|
if (_ifIndex > 0)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
setsockopt(_sockfdSsl, IPPROTO_IP, IP_BOUND_IF, &_ifIndex, sizeof(_ifIndex));
|
||||||
|
#else
|
||||||
|
setsockopt(_sockfdSsl, SOL_SOCKET, SO_BINDTODEVICE, _interfaceName.c_str(), _interfaceName.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in6 addr;
|
||||||
|
addr.sin6_family = AF_INET6;
|
||||||
|
addr.sin6_port = _uPortNo;
|
||||||
|
addr.sin6_addr = in6addr_any;
|
||||||
|
|
||||||
|
if (::bind(_sockfdSsl, (struct sockaddr*) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
::close(_sockfdSsl);
|
||||||
|
D_NWLOG("LDtlsPort::sslConnect Can't bind a socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destination is a gateway address and portNo
|
||||||
|
int rc = 0;
|
||||||
|
sockaddr_in6 dest;
|
||||||
|
dest.sin6_family = AF_INET6;
|
||||||
|
dest.sin6_port = portNo;
|
||||||
|
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||||
|
|
||||||
|
BIO *cbio = BIO_new_dgram(_sockfdSsl, BIO_NOCLOSE);
|
||||||
|
if (connect(_sockfdSsl, (sockaddr*) &dest, sizeof(sockaddr_in6)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("socket can't connect %s\n",strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dest) <0)
|
||||||
|
{
|
||||||
|
D_NWLOG("BIO_ctrl %s\n",strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ssl = SSL_new(_ctx);
|
||||||
|
if (_ssl == nullptr)
|
||||||
|
{
|
||||||
|
D_NWLOG("SSL_new %s\n",strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SSL_set_bio(_ssl, cbio, cbio);
|
||||||
|
|
||||||
|
#ifdef DEBUG_NW
|
||||||
|
char addrBuf[INET6_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||||
|
D_NWLOG("connect to %-15s:%-6u\n", addrBuf, ntohs(dest.sin6_port));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
timeval timeout;
|
||||||
|
timeout.tv_sec = 5;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
BIO_ctrl(cbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
int stat = SSL_connect(_ssl);
|
||||||
|
if (stat != 1)
|
||||||
|
{
|
||||||
|
rc = -1;
|
||||||
|
D_NWLOG("SSL fail to connect %s\n",strerror(errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
D_NWLOG("SSL connected\n");
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int verify_cert(int ok, X509_STORE_CTX *ctx)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
122
MQTTSNGateway/GatewayTester/src/LNetworkDtls6.h
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef NETWORKDTLS6_H_
|
||||||
|
#define NETWORKDTLS6_H_
|
||||||
|
|
||||||
|
#ifdef DTLS6
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
#define SOCKET_MAXHOSTNAME 200
|
||||||
|
#define SOCKET_MAXCONNECTIONS 5
|
||||||
|
#define SOCKET_MAXRECV 500
|
||||||
|
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||||
|
|
||||||
|
#define STAT_NONE 0
|
||||||
|
#define STAT_UNICAST 1
|
||||||
|
#define STAT_MULTICAST 2
|
||||||
|
#define STAT_SSL 3
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace linuxAsyncClient {
|
||||||
|
/*========================================
|
||||||
|
Class LDtls6Port
|
||||||
|
=======================================*/
|
||||||
|
class LDtls6Port
|
||||||
|
{
|
||||||
|
friend class LNetwork;
|
||||||
|
public:
|
||||||
|
LDtls6Port();
|
||||||
|
virtual ~LDtls6Port();
|
||||||
|
|
||||||
|
bool open(LUdp6Config* config);
|
||||||
|
|
||||||
|
int unicast(const uint8_t *buf, uint32_t length);
|
||||||
|
int multicast( const uint8_t* buf, uint32_t length );
|
||||||
|
int recv(uint8_t* buf, uint16_t len, bool nonblock, in6_addr* ipaddress, in_port_t* port );
|
||||||
|
int recv(uint8_t* buf, int flags);
|
||||||
|
bool checkRecvBuf();
|
||||||
|
bool isUnicast();
|
||||||
|
SSL* getSSL(void);
|
||||||
|
int sslConnect(in6_addr ipAddress, uint16_t port);
|
||||||
|
private:
|
||||||
|
void close();
|
||||||
|
int recvfrom ( uint8_t* buf, uint16_t len, int flags, in6_addr* ipaddress, in_port_t* port );
|
||||||
|
|
||||||
|
int _sockfdMcast;
|
||||||
|
int _sockfdSsl;
|
||||||
|
SSL_CTX *_ctx;
|
||||||
|
SSL *_ssl;
|
||||||
|
in_port_t _gPortNo;
|
||||||
|
in_port_t _uPortNo;
|
||||||
|
sockaddr_in6 _gIpAddr;
|
||||||
|
char *_gIpAddrStr;
|
||||||
|
uint32_t _ifIndex;
|
||||||
|
string _interfaceName;
|
||||||
|
uint8_t _castStat;
|
||||||
|
bool _disconReq;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NO_ERROR 0
|
||||||
|
#define PACKET_EXCEEDS_LENGTH 1
|
||||||
|
/*===========================================
|
||||||
|
Class Network
|
||||||
|
============================================*/
|
||||||
|
class LNetwork: public LDtls6Port
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LNetwork();
|
||||||
|
~LNetwork();
|
||||||
|
|
||||||
|
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
void setGwAddress(void);
|
||||||
|
void resetGwAddress(void);
|
||||||
|
bool initialize(LUdp6Config* config);
|
||||||
|
uint8_t* getMessage(int* len);
|
||||||
|
bool isBroadcastable();
|
||||||
|
int sslConnect(void);
|
||||||
|
private:
|
||||||
|
void setSleep();
|
||||||
|
int readApiFrame(void);
|
||||||
|
|
||||||
|
in6_addr _gwIpAddress;
|
||||||
|
in6_addr _ipAddress;
|
||||||
|
in_port_t _gwPortNo;
|
||||||
|
in_port_t _portNo;
|
||||||
|
int _returnCode;
|
||||||
|
bool _sleepflg;
|
||||||
|
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* end of namespace */
|
||||||
|
#endif /* DTLS6 */
|
||||||
|
#endif /* NETWORKDTLS6_H_ */
|
||||||
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
286
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.cpp
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
#ifdef RFCOMM
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/rfcomm.h>
|
||||||
|
|
||||||
|
#include "LMqttsnClientApp.h"
|
||||||
|
#include "LNetworkRfcomm.h"
|
||||||
|
#include "LTimer.h"
|
||||||
|
#include "LScreen.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace linuxAsyncClient;
|
||||||
|
|
||||||
|
extern uint16_t getUint16(const uint8_t* pos);
|
||||||
|
extern uint32_t getUint32(const uint8_t* pos);
|
||||||
|
extern LScreen* theScreen;
|
||||||
|
extern bool theClientMode;
|
||||||
|
extern LRfcommConfig theNetcon;
|
||||||
|
/*=========================================
|
||||||
|
Class LNetwork
|
||||||
|
=========================================*/
|
||||||
|
LNetwork::LNetwork()
|
||||||
|
{
|
||||||
|
_sleepflg = false;
|
||||||
|
_returnCode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LNetwork::~LNetwork()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::broadcast(const uint8_t* xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LRfcommPort::unicast(xmitData, dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::unicast(const uint8_t* xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LRfcommPort::unicast(xmitData, dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* LNetwork::getMessage(int* len)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
if (checkRecvBuf())
|
||||||
|
{
|
||||||
|
uint16_t recvLen = LRfcommPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false);
|
||||||
|
|
||||||
|
if (recvLen < 0)
|
||||||
|
{
|
||||||
|
*len = recvLen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_rxDataBuf[0] == 0x01)
|
||||||
|
{
|
||||||
|
*len = getUint16(_rxDataBuf + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*len = _rxDataBuf[0];
|
||||||
|
}
|
||||||
|
return _rxDataBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setGwAddress(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setFixedGwAddress(void)
|
||||||
|
{
|
||||||
|
_channel = LRfcommPort::_channel;
|
||||||
|
str2ba( theNetcon.gwAddress, (bdaddr_t*)_gwAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::initialize(LRfcommConfig* config)
|
||||||
|
{
|
||||||
|
return LRfcommPort::open(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setSleep()
|
||||||
|
{
|
||||||
|
_sleepflg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::isBroadcastable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class RFCOMM Stack
|
||||||
|
=========================================*/
|
||||||
|
LRfcommPort::LRfcommPort()
|
||||||
|
{
|
||||||
|
_disconReq = false;
|
||||||
|
_sockRfcomm = 0;
|
||||||
|
_channel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRfcommPort::~LRfcommPort()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LRfcommPort::close()
|
||||||
|
{
|
||||||
|
if (_sockRfcomm > 0)
|
||||||
|
{
|
||||||
|
::close(_sockRfcomm);
|
||||||
|
_sockRfcomm = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LRfcommPort::open(LRfcommConfig* config)
|
||||||
|
{
|
||||||
|
const int reuse = 1;
|
||||||
|
str2ba(config->gwAddress, (bdaddr_t*)_gwAddress);
|
||||||
|
_channel = config->channel;
|
||||||
|
|
||||||
|
if (_channel == 0 || _gwAddress == 0 )
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||||
|
DISPLAY("\033[0m\033[0;31m\nerror Bluetooth Address in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sockRfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||||
|
if (_sockRfcomm < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||||
|
DISPLAY("\033[0m\033[0;31m\nerror Can't create socket in LRfcommPort::open\033[0m\033[0;37m\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setsockopt(_sockRfcomm, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||||
|
|
||||||
|
struct sockaddr_rc addru = { 0 };
|
||||||
|
addru.rc_family = AF_BLUETOOTH;
|
||||||
|
addru.rc_channel = _channel;
|
||||||
|
memcpy(&addru.rc_bdaddr, _gwAddress, 6);
|
||||||
|
|
||||||
|
char bufgw[30];
|
||||||
|
ba2str(&addru.rc_bdaddr, bufgw);
|
||||||
|
DISPLAY("GW MAC = %s RFCOMM CH = %d\n", bufgw, addru.rc_channel);
|
||||||
|
|
||||||
|
// connect to server
|
||||||
|
errno = 0;
|
||||||
|
int status = connect(_sockRfcomm, (struct sockaddr *) &addru, sizeof(addru));
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror = %d Can't connect to GW in LRfcommPort::open\033[0m\033[0;37m\n", errno);
|
||||||
|
DISPLAY("\033[0m\033[0;31merror = %d Can't connect to GW Ble socket in LRfcommPort::open\033[0m\033[0;37m\n",errno);
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LRfcommPort::unicast(const uint8_t* buf, uint32_t length)
|
||||||
|
{
|
||||||
|
int status = ::write(_sockRfcomm, buf, length);
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("errno == %d in LRfcommPort::unicast\n", errno);
|
||||||
|
DISPLAY("errno == %d in LRfcommPort::unicast\n", errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("sendto %-2d", _channel);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34msendto %-2dch", _channel);
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LRfcommPort::checkRecvBuf()
|
||||||
|
{
|
||||||
|
uint8_t buf[2];
|
||||||
|
if (::recv(_sockRfcomm, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LRfcommPort::recv(uint8_t* buf, uint16_t length, bool flg)
|
||||||
|
{
|
||||||
|
int flags = flg ? MSG_DONTWAIT : 0;
|
||||||
|
int status = ::recv(_sockRfcomm, buf, length, flags);
|
||||||
|
|
||||||
|
if (status < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||||
|
DISPLAY("\033[0m\033[0;31merrno = %d in LRfcommPort::recv \033[0m\033[0;37m\n", errno);
|
||||||
|
}
|
||||||
|
else if (status > 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\nrecved ");
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mrecved ");
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
102
MQTTSNGateway/GatewayTester/src/LNetworkRfcomm.h
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef NETWORKRFCOMM_H_
|
||||||
|
#define NETWORKRFCOMM_H_
|
||||||
|
|
||||||
|
#ifdef RFCOMM
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define SOCKET_MAXHOSTNAME 200
|
||||||
|
#define SOCKET_MAXCONNECTIONS 5
|
||||||
|
#define SOCKET_MAXRECV 500
|
||||||
|
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||||
|
|
||||||
|
#define STAT_UNICAST 1
|
||||||
|
#define STAT_MULTICAST 2
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace linuxAsyncClient
|
||||||
|
{
|
||||||
|
/*========================================
|
||||||
|
Class LRfcommPort
|
||||||
|
=======================================*/
|
||||||
|
class LRfcommPort
|
||||||
|
{
|
||||||
|
friend class LNetwork;
|
||||||
|
public:
|
||||||
|
LRfcommPort();
|
||||||
|
virtual ~LRfcommPort();
|
||||||
|
bool open(LRfcommConfig* config);
|
||||||
|
int unicast(const uint8_t* buf, uint32_t length);
|
||||||
|
int recv(uint8_t* buf, uint16_t len, bool nonblock);
|
||||||
|
bool checkRecvBuf();
|
||||||
|
bool isUnicast();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void close();
|
||||||
|
|
||||||
|
int _sockRfcomm;
|
||||||
|
uint8_t _gwAddress[6];
|
||||||
|
uint8_t _channel;
|
||||||
|
bool _disconReq;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NO_ERROR 0
|
||||||
|
#define PACKET_EXCEEDS_LENGTH 1
|
||||||
|
/*===========================================
|
||||||
|
Class Network
|
||||||
|
============================================*/
|
||||||
|
class LNetwork: public LRfcommPort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LNetwork();
|
||||||
|
~LNetwork();
|
||||||
|
|
||||||
|
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
void setGwAddress(void);
|
||||||
|
void resetGwAddress(void);
|
||||||
|
void setFixedGwAddress(void);
|
||||||
|
bool initialize(LRfcommConfig* config);
|
||||||
|
uint8_t* getMessage(int* len);
|
||||||
|
bool isBroadcastable();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setSleep();
|
||||||
|
int readApiFrame(void);
|
||||||
|
|
||||||
|
int _returnCode;
|
||||||
|
bool _sleepflg;
|
||||||
|
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* end of namespace */
|
||||||
|
#endif /* RFCOMM */
|
||||||
|
#endif /* NETWORKRFCOM_H_ */
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
* Contributors:
|
* 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,12 +26,11 @@
|
|||||||
#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;
|
||||||
|
|
||||||
@@ -41,39 +41,51 @@ extern bool theClientMode;
|
|||||||
/*=========================================
|
/*=========================================
|
||||||
Class LNetwork
|
Class LNetwork
|
||||||
=========================================*/
|
=========================================*/
|
||||||
LNetwork::LNetwork(){
|
LNetwork::LNetwork()
|
||||||
|
{
|
||||||
_sleepflg = false;
|
_sleepflg = false;
|
||||||
resetGwAddress();
|
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)
|
||||||
uint8_t* LNetwork::getMessage(int* len){
|
{
|
||||||
*len = 0;
|
*len = 0;
|
||||||
if (checkRecvBuf()){
|
if (checkRecvBuf())
|
||||||
|
{
|
||||||
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
uint16_t recvLen = LUdpPort::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||||
if(_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo)){
|
if (_gwIpAddress && isUnicast() && (_ipAddress != _gwIpAddress) && (_portNo != _gwPortNo))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(recvLen < 0){
|
if (recvLen < 0)
|
||||||
|
{
|
||||||
*len = recvLen;
|
*len = recvLen;
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}
|
||||||
if(_rxDataBuf[0] == 0x01){
|
else
|
||||||
|
{
|
||||||
|
if (_rxDataBuf[0] == 0x01)
|
||||||
|
{
|
||||||
*len = getUint16(_rxDataBuf + 1);
|
*len = getUint16(_rxDataBuf + 1);
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*len = _rxDataBuf[0];
|
*len = _rxDataBuf[0];
|
||||||
}
|
}
|
||||||
//if(recvLen != *len){
|
//if(recvLen != *len){
|
||||||
@@ -87,111 +99,125 @@ uint8_t* LNetwork::getMessage(int* len){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LNetwork::setGwAddress(void){
|
void LNetwork::setGwAddress(void)
|
||||||
|
{
|
||||||
_gwPortNo = _portNo;
|
_gwPortNo = _portNo;
|
||||||
_gwIpAddress = _ipAddress;
|
_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;
|
_gwIpAddress = 0;
|
||||||
_gwPortNo = 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);
|
::close(_sockfdMcast);
|
||||||
_sockfdMcast = -1;
|
_sockfdMcast = -1;
|
||||||
if(_sockfdUcast > 0){
|
if (_sockfdUcast > 0)
|
||||||
|
{
|
||||||
::close(_sockfdUcast);
|
::close(_sockfdUcast);
|
||||||
_sockfdUcast = -1;
|
_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)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||||
return false;
|
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));
|
||||||
|
|
||||||
if(setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP,(char*)&loopch, sizeof(loopch)) <0 ){
|
|
||||||
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
|
||||||
DISPLAY("\033[0m\033[0;31m\nerror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
|
||||||
close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,36 +225,47 @@ bool LUdpPort::open(LUdpConfig config){
|
|||||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||||
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
mreq.imr_multiaddr.s_addr = _gIpAddr;
|
||||||
|
|
||||||
if( setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) )< 0){
|
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||||
|
{
|
||||||
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
D_NWLOG("\033[0m\033[0;31merror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
||||||
DISPLAY("\033[0m\033[0;31m\nerror IP_ADD_MEMBERSHIP in UdpPort::open\033[0m\033[0;37m\n");
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval= 1;
|
||||||
|
if (setsockopt(_sockfdMcast, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror IP_MULTICAST_LOOP in UdpPPort::open\033[0m\033[0;37m\n");
|
||||||
close();
|
close();
|
||||||
return false;
|
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)
|
||||||
int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, uint16_t port ){
|
{
|
||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
dest.sin_family = AF_INET;
|
dest.sin_family = AF_INET;
|
||||||
dest.sin_port = port;
|
dest.sin_port = port;
|
||||||
dest.sin_addr.s_addr = ipAddress;
|
dest.sin_addr.s_addr = ipAddress;
|
||||||
|
|
||||||
int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
int status = ::sendto(_sockfdUcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||||
if( status < 0){
|
if (status < 0)
|
||||||
|
{
|
||||||
D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
|
D_NWLOG("errno == %d in UdpPort::unicast\n", errno);
|
||||||
DISPLAY("errno == %d in UdpPort::unicast\n", errno);
|
|
||||||
}else{
|
|
||||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
|
||||||
for(uint16_t i = 0; i < length ; i++){
|
|
||||||
D_NWLOG(" %02x", *(buf + i));
|
|
||||||
}
|
}
|
||||||
D_NWLOG("\n");
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(port));
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
} D_NWLOG("\n");
|
||||||
|
|
||||||
if (!theClientMode)
|
if (!theClientMode)
|
||||||
{
|
{
|
||||||
@@ -236,7 +273,8 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
|
|||||||
int pos = 0;
|
int pos = 0;
|
||||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
|
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(port));
|
||||||
pos = strlen(sbuf);
|
pos = strlen(sbuf);
|
||||||
for(uint16_t i = 0; i < length ; i++){
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||||
{
|
{
|
||||||
@@ -245,32 +283,32 @@ int LUdpPort::unicast(const uint8_t* buf, uint32_t length, uint32_t ipAddress, u
|
|||||||
pos += 3;
|
pos += 3;
|
||||||
}
|
}
|
||||||
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
theScreen->display(sbuf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LUdpPort::multicast(const uint8_t *buf, uint32_t length)
|
||||||
int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
{
|
||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
dest.sin_family = AF_INET;
|
dest.sin_family = AF_INET;
|
||||||
dest.sin_port = _gPortNo;
|
dest.sin_port = _gPortNo;
|
||||||
dest.sin_addr.s_addr = _gIpAddr;
|
dest.sin_addr.s_addr = _gIpAddr;
|
||||||
|
|
||||||
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
int status = ::sendto(_sockfdMcast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||||
if( status < 0){
|
if (status < 0)
|
||||||
|
{
|
||||||
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
||||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::multicast\033[0m\033[0;37m\n", errno);
|
|
||||||
return errno;
|
return errno;
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
D_NWLOG("sendto %-15s:%-6u",inet_ntoa(dest.sin_addr),htons(_gPortNo));
|
||||||
|
|
||||||
for(uint16_t i = 0; i < length ; i++){
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
D_NWLOG(" %02x", *(buf + i));
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
DISPLAY(" %02x", *(buf + i));
|
} D_NWLOG("\n");
|
||||||
}
|
|
||||||
D_NWLOG("\n");
|
|
||||||
|
|
||||||
if (!theClientMode)
|
if (!theClientMode)
|
||||||
{
|
{
|
||||||
@@ -278,7 +316,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
|||||||
int pos = 0;
|
int pos = 0;
|
||||||
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
sprintf(sbuf, "\033[0;34msendto %-15s:%-6u", inet_ntoa(dest.sin_addr), htons(_gPortNo));
|
||||||
pos = strlen(sbuf);
|
pos = strlen(sbuf);
|
||||||
for(uint16_t i = 0; i < length ; i++){
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
sprintf(sbuf + pos, " %02x", *(buf + i));
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
{
|
{
|
||||||
@@ -294,7 +333,8 @@ int LUdpPort::multicast( const uint8_t* buf, uint32_t length ){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LUdpPort::checkRecvBuf(){
|
bool LUdpPort::checkRecvBuf()
|
||||||
|
{
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 50000; // 50 msec
|
timeout.tv_usec = 50000; // 50 msec
|
||||||
@@ -307,21 +347,29 @@ bool LUdpPort::checkRecvBuf(){
|
|||||||
FD_SET(_sockfdUcast, &recvfds);
|
FD_SET(_sockfdUcast, &recvfds);
|
||||||
FD_SET(_sockfdMcast, &recvfds);
|
FD_SET(_sockfdMcast, &recvfds);
|
||||||
|
|
||||||
if(_sockfdMcast > _sockfdUcast){
|
if (_sockfdMcast > _sockfdUcast)
|
||||||
|
{
|
||||||
maxSock = _sockfdMcast;
|
maxSock = _sockfdMcast;
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
maxSock = _sockfdUcast;
|
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){
|
{
|
||||||
|
if (::recv(_sockfdUcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
_castStat = STAT_UNICAST;
|
_castStat = STAT_UNICAST;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}else if(FD_ISSET(_sockfdMcast, &recvfds)){
|
}
|
||||||
if( ::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0){
|
else if (FD_ISSET(_sockfdMcast, &recvfds))
|
||||||
|
{
|
||||||
|
if (::recv(_sockfdMcast, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
_castStat = STAT_MULTICAST;
|
_castStat = STAT_MULTICAST;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -330,36 +378,47 @@ bool LUdpPort::checkRecvBuf(){
|
|||||||
return false;
|
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;
|
int flags = flg ? MSG_DONTWAIT : 0;
|
||||||
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAddressPtr, uint16_t* portPtr ){
|
int LUdpPort::recvfrom(uint8_t *buf, uint16_t length, int flags, uint32_t *ipAddressPtr, uint16_t *portPtr)
|
||||||
|
{
|
||||||
struct sockaddr_in sender;
|
struct sockaddr_in sender;
|
||||||
int status;
|
int status;
|
||||||
socklen_t addrlen = sizeof(sender);
|
socklen_t addrlen = sizeof(sender);
|
||||||
memset(&sender, 0, addrlen);
|
memset(&sender, 0, addrlen);
|
||||||
|
|
||||||
if(isUnicast()){
|
if (isUnicast())
|
||||||
|
{
|
||||||
|
D_NWLOG("Ucast ");
|
||||||
status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
status = ::recvfrom(_sockfdUcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||||
}else if(_castStat == STAT_MULTICAST){
|
}
|
||||||
|
else if (_castStat == STAT_MULTICAST)
|
||||||
|
{
|
||||||
|
D_NWLOG("Mcast ");
|
||||||
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
status = ::recvfrom(_sockfdMcast, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return 0;
|
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);
|
D_NWLOG("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
DISPLAY("\033[0m\033[0;31merrno == %d in UdpPort::recvfrom \033[0m\033[0;37m\n", errno);
|
}
|
||||||
}else if(status > 0){
|
else if (status > 0)
|
||||||
|
{
|
||||||
*ipAddressPtr = sender.sin_addr.s_addr;
|
*ipAddressPtr = sender.sin_addr.s_addr;
|
||||||
*portPtr = sender.sin_port;
|
*portPtr = sender.sin_port;
|
||||||
D_NWLOG("\nrecved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
D_NWLOG("recved %-15s:%-6u",inet_ntoa(sender.sin_addr), htons(*portPtr));
|
||||||
for(uint16_t i = 0; i < status ; i++){
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
D_NWLOG(" %02x", *(buf + i));
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
}
|
} D_NWLOG("\n");
|
||||||
D_NWLOG("\n");
|
|
||||||
|
|
||||||
if (!theClientMode)
|
if (!theClientMode)
|
||||||
{
|
{
|
||||||
@@ -367,7 +426,8 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
|
|||||||
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));
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
{
|
{
|
||||||
@@ -379,11 +439,13 @@ int LUdpPort::recvfrom (uint8_t* buf, uint16_t length, int flags, uint32_t* ipAd
|
|||||||
theScreen->display(sbuf);
|
theScreen->display(sbuf);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
433
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.cpp
Normal file
@@ -0,0 +1,433 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
#ifdef UDP6
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include "LMqttsnClientApp.h"
|
||||||
|
#include "LNetworkUdp6.h"
|
||||||
|
#include "LTimer.h"
|
||||||
|
#include "LScreen.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace linuxAsyncClient;
|
||||||
|
|
||||||
|
extern uint16_t getUint16(const uint8_t *pos);
|
||||||
|
extern uint32_t getUint32(const uint8_t *pos);
|
||||||
|
extern LScreen *theScreen;
|
||||||
|
extern bool theClientMode;
|
||||||
|
/*=========================================
|
||||||
|
Class LNetwork
|
||||||
|
=========================================*/
|
||||||
|
LNetwork::LNetwork()
|
||||||
|
{
|
||||||
|
_sleepflg = false;
|
||||||
|
resetGwAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
LNetwork::~LNetwork()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::broadcast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LUdp6Port::multicast(xmitData, (uint32_t) dataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LNetwork::unicast(const uint8_t *xmitData, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
return LUdp6Port::unicast(xmitData, dataLen, _gwIpAddress, _gwPortNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* LNetwork::getMessage(int *len)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
if (checkRecvBuf())
|
||||||
|
{
|
||||||
|
uint16_t recvLen = LUdp6Port::recv(_rxDataBuf, MQTTSN_MAX_PACKET_SIZE, false, &_ipAddress, &_portNo);
|
||||||
|
int diffAddr = memcmp(_ipAddress.s6_addr, _gwIpAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||||
|
if (isUnicast() && diffAddr && (_portNo != _gwPortNo))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recvLen < 0)
|
||||||
|
{
|
||||||
|
*len = recvLen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_rxDataBuf[0] == 0x01)
|
||||||
|
{
|
||||||
|
*len = getUint16(_rxDataBuf + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*len = _rxDataBuf[0];
|
||||||
|
}
|
||||||
|
return _rxDataBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setGwAddress(void)
|
||||||
|
{
|
||||||
|
memcpy(_gwIpAddress.s6_addr, _ipAddress.s6_addr, sizeof(_gwIpAddress.s6_addr));
|
||||||
|
_gwPortNo = _portNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::resetGwAddress(void)
|
||||||
|
{
|
||||||
|
memset(_gwIpAddress.s6_addr, 0, sizeof(_gwIpAddress.s6_addr));
|
||||||
|
_gwPortNo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::initialize(LUdp6Config *config)
|
||||||
|
{
|
||||||
|
return LUdp6Port::open(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LNetwork::setSleep()
|
||||||
|
{
|
||||||
|
_sleepflg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LNetwork::isBroadcastable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*=========================================
|
||||||
|
Class udp6Stack
|
||||||
|
=========================================*/
|
||||||
|
LUdp6Port::LUdp6Port()
|
||||||
|
{
|
||||||
|
_disconReq = false;
|
||||||
|
memset(_pollfds, 0, sizeof(_pollfds));
|
||||||
|
_sock = 0;
|
||||||
|
_interface = NULL;
|
||||||
|
_gIpAddrStr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LUdp6Port::~LUdp6Port()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
if (_gIpAddrStr)
|
||||||
|
{
|
||||||
|
free(_gIpAddrStr);
|
||||||
|
}
|
||||||
|
if (_interface)
|
||||||
|
{
|
||||||
|
free(_interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LUdp6Port::close()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (_pollfds[i].fd > 0)
|
||||||
|
{
|
||||||
|
::close(_pollfds[i].fd);
|
||||||
|
_pollfds[i].fd = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LUdp6Port::open(LUdp6Config *config)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
int sock = 0;
|
||||||
|
uint32_t ifindex = 0;
|
||||||
|
sockaddr_in6 addr6;
|
||||||
|
|
||||||
|
_gPortNo = htons(config->gPortNo);
|
||||||
|
_uPortNo = htons(config->uPortNo);
|
||||||
|
|
||||||
|
if (_gPortNo == 0 || _uPortNo == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a unicast socket */
|
||||||
|
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
|
||||||
|
if (strlen(config->interface) > 0)
|
||||||
|
{
|
||||||
|
ifindex = if_nametoindex(config->interface);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex));
|
||||||
|
#else
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, config->interface, strlen(config->interface));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
|
addr6.sin6_family = AF_INET6;
|
||||||
|
addr6.sin6_port = _uPortNo;
|
||||||
|
addr6.sin6_addr = in6addr_any;
|
||||||
|
|
||||||
|
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s ::bind() to unicast address\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_pollfds[0].fd = sock;
|
||||||
|
_pollfds[0].events = POLLIN;
|
||||||
|
|
||||||
|
/* create a multicast socket */
|
||||||
|
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
|
||||||
|
|
||||||
|
memset(&addr6, 0, sizeof(addr6));
|
||||||
|
addr6.sin6_family = AF_INET6;
|
||||||
|
addr6.sin6_port = _gPortNo;
|
||||||
|
addr6.sin6_addr = in6addr_any;
|
||||||
|
|
||||||
|
if (::bind(sock, (sockaddr*) &addr6, sizeof(addr6)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s ::bind() in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ipv6_mreq addrm;
|
||||||
|
addrm.ipv6mr_interface = ifindex;
|
||||||
|
inet_pton(AF_INET6, config->ipAddress, &addrm.ipv6mr_multiaddr);
|
||||||
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &addrm, sizeof(addrm)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s IPV6_ADD_MEMBERSHIP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
optval = 1;
|
||||||
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merror %s IPV6_MULTICAST_LOOP in Udp6Port::open\033[0m\033[0;37m\n", strerror(errno));
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_pollfds[1].fd = sock;
|
||||||
|
_pollfds[1].events = POLLIN;
|
||||||
|
_gIpAddr.sin6_family = AF_INET6;
|
||||||
|
_gIpAddr.sin6_port = _gPortNo;
|
||||||
|
memcpy(&_gIpAddr.sin6_addr, (const void*) &addrm.ipv6mr_multiaddr, sizeof(addrm.ipv6mr_multiaddr));
|
||||||
|
_gIpAddrStr = strdup(config->ipAddress);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LUdp6Port::unicast(const uint8_t *buf, uint32_t length, in6_addr ipAddress, uint16_t port)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 dest;
|
||||||
|
dest.sin6_family = AF_INET6;
|
||||||
|
dest.sin6_port = port;
|
||||||
|
memcpy(dest.sin6_addr.s6_addr, (const void*) ipAddress.s6_addr, sizeof(ipAddress.s6_addr));
|
||||||
|
|
||||||
|
char addrBuf[INET6_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET6, &dest.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||||
|
D_NWLOG("unicast to [%s]:%-6u", addrBuf, htons(port));
|
||||||
|
|
||||||
|
int status = ::sendto(_pollfds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG(" errno = %d %s in Udp6Port::unicast\n", errno, strerror(errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34municast to [%s[:%-6u", addrBuf, htons(port));
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20) // -20 for Escape sequence
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LUdp6Port::multicast(const uint8_t *buf, uint32_t length)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
char portStr[8];
|
||||||
|
sprintf(portStr, "%d", ntohs(_gPortNo));
|
||||||
|
|
||||||
|
int status = ::sendto(_pollfds[1].fd, buf, length, 0, (sockaddr*) &_gIpAddr, sizeof(_gIpAddr));
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
D_NWLOG("multicast to [%s]:%-6s ", _gIpAddrStr, portStr);
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno = %d %s in Udp6Port::multicast\033[0m\033[0;37m\n", errno, strerror(errno));
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_NWLOG("multicast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
D_NWLOG(" %02x", *(buf + i));
|
||||||
|
}
|
||||||
|
D_NWLOG("\n");
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
memset(sbuf, 0, SCREEN_BUFF_SIZE);
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mmulticast to [%s]:%-6s", _gIpAddrStr, portStr);
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LUdp6Port::checkRecvBuf()
|
||||||
|
{
|
||||||
|
uint8_t buf[2];
|
||||||
|
|
||||||
|
int cnt = poll(_pollfds, 2, 50); // Timeout 50m secs
|
||||||
|
if (cnt == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (_pollfds[i].revents & POLLIN)
|
||||||
|
{
|
||||||
|
if (::recv(_pollfds[i].fd, buf, 1, MSG_DONTWAIT | MSG_PEEK) > 0)
|
||||||
|
{
|
||||||
|
_sock = _pollfds[i].fd;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int LUdp6Port::recv(uint8_t *buf, uint16_t len, bool flg, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||||
|
{
|
||||||
|
int flags = flg ? MSG_DONTWAIT : 0;
|
||||||
|
return recvfrom(buf, len, flags, ipAddressPtr, portPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LUdp6Port::recvfrom(uint8_t *buf, uint16_t length, int flags, in6_addr *ipAddressPtr, uint16_t *portPtr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 sender;
|
||||||
|
int status;
|
||||||
|
socklen_t addrlen = sizeof(sender);
|
||||||
|
memset(&sender, 0, addrlen);
|
||||||
|
char addrBuf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
status = ::recvfrom(_sock, buf, length, flags, (struct sockaddr*) &sender, &addrlen);
|
||||||
|
|
||||||
|
if (status < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWLOG("\033[0m\033[0;31merrno == %d in Udp6Port::recvfrom \033[0m\033[0;37m\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status > 0)
|
||||||
|
{
|
||||||
|
inet_ntop(AF_INET6, &sender.sin6_addr, addrBuf, INET6_ADDRSTRLEN);
|
||||||
|
memcpy(ipAddressPtr->s6_addr, (const void*) sender.sin6_addr.s6_addr, sizeof(sender.sin6_addr.s6_addr));
|
||||||
|
*portPtr = sender.sin6_port;
|
||||||
|
|
||||||
|
if (!theClientMode)
|
||||||
|
{
|
||||||
|
char sbuf[SCREEN_BUFF_SIZE];
|
||||||
|
int pos = 0;
|
||||||
|
sprintf(sbuf, "\033[0;34mrecv from [%s]:%-6u", addrBuf, htons(*portPtr));
|
||||||
|
pos = strlen(sbuf);
|
||||||
|
for (uint16_t i = 0; i < status; i++)
|
||||||
|
{
|
||||||
|
sprintf(sbuf + pos, " %02x", *(buf + i));
|
||||||
|
if (strlen(sbuf) > SCREEN_BUFF_SIZE - 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 3;
|
||||||
|
}
|
||||||
|
sprintf(sbuf + strlen(sbuf), "\033[0;37m\n");
|
||||||
|
theScreen->display(sbuf);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LUdp6Port::isUnicast(void)
|
||||||
|
{
|
||||||
|
return (_sock == _pollfds[0].fd && _sock > 0);
|
||||||
|
}
|
||||||
|
#endif /* UDP6 */
|
||||||
|
|
||||||
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
113
MQTTSNGateway/GatewayTester/src/LNetworkUdp6.h
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* Copyright (c) 2021, Tomoaki Yamaguchi
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
*
|
||||||
|
* The Eclipse Public License is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* and the Eclipse Distribution License is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Tomoaki Yamaguchi - initial API and implementation and/or initial documentation
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef NETWORKUDP6_H_
|
||||||
|
#define NETWORKUDP6_H_
|
||||||
|
|
||||||
|
#ifdef UDP6
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define SOCKET_MAXHOSTNAME 200
|
||||||
|
#define SOCKET_MAXCONNECTIONS 5
|
||||||
|
#define SOCKET_MAXRECV 500
|
||||||
|
#define SOCKET_MAXBUFFER_LENGTH 500 // buffer size
|
||||||
|
|
||||||
|
#define STAT_UNICAST 1
|
||||||
|
#define STAT_MULTICAST 2
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace linuxAsyncClient {
|
||||||
|
/*========================================
|
||||||
|
Class LUpd6Port
|
||||||
|
=======================================*/
|
||||||
|
class LUdp6Port
|
||||||
|
{
|
||||||
|
friend class LNetwork;
|
||||||
|
public:
|
||||||
|
LUdp6Port();
|
||||||
|
virtual ~LUdp6Port();
|
||||||
|
|
||||||
|
bool open(LUdp6Config *config);
|
||||||
|
|
||||||
|
int unicast(const uint8_t *buf, uint32_t length, in6_addr ipaddress, uint16_t port);
|
||||||
|
int multicast( const uint8_t* buf, uint32_t length );
|
||||||
|
int recv(uint8_t *buf, uint16_t len, bool nonblock, in6_addr *ipaddress, uint16_t *port);
|
||||||
|
int recv(uint8_t* buf, int flags);
|
||||||
|
bool checkRecvBuf();
|
||||||
|
bool isUnicast();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void close();
|
||||||
|
int recvfrom(uint8_t *buf, uint16_t len, int flags, in6_addr *ipaddress, uint16_t *port);
|
||||||
|
|
||||||
|
pollfd _pollfds[2];
|
||||||
|
uint16_t _gPortNo;
|
||||||
|
uint16_t _uPortNo;
|
||||||
|
sockaddr_in6 _gIpAddr;
|
||||||
|
char *_gIpAddrStr;
|
||||||
|
char* _interface;
|
||||||
|
int _sock;
|
||||||
|
bool _disconReq;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NO_ERROR 0
|
||||||
|
#define PACKET_EXCEEDS_LENGTH 1
|
||||||
|
/*===========================================
|
||||||
|
Class Network
|
||||||
|
============================================*/
|
||||||
|
class LNetwork: public LUdp6Port
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LNetwork();
|
||||||
|
~LNetwork();
|
||||||
|
|
||||||
|
int broadcast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
int unicast(const uint8_t* payload, uint16_t payloadLen);
|
||||||
|
void setGwAddress(void);
|
||||||
|
void resetGwAddress(void);
|
||||||
|
bool initialize(LUdp6Config *config);
|
||||||
|
uint8_t* getMessage(int* len);
|
||||||
|
bool isBroadcastable();
|
||||||
|
private:
|
||||||
|
void setSleep();
|
||||||
|
int readApiFrame(void);
|
||||||
|
|
||||||
|
in6_addr _gwIpAddress;
|
||||||
|
in6_addr _ipAddress;
|
||||||
|
uint16_t _gwPortNo;
|
||||||
|
uint16_t _portNo;
|
||||||
|
int _returnCode;
|
||||||
|
bool _sleepflg;
|
||||||
|
uint8_t _rxDataBuf[MQTTSN_MAX_PACKET_SIZE + 1]; // defined in MqttsnClientApp.h
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* end of namespace */
|
||||||
|
#endif /* UDP6 */
|
||||||
|
#endif /* NETWORKUDP_H_ */
|
||||||
@@ -44,6 +44,7 @@ LPublishManager::LPublishManager()
|
|||||||
_last = 0;
|
_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_autoConnectFlg)
|
||||||
|
{
|
||||||
theClient->getGwProxy()->connect();
|
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;
|
||||||
|
|||||||
@@ -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,6 +85,7 @@ private:
|
|||||||
PubElement* _last;
|
PubElement* _last;
|
||||||
uint8_t _elmCnt;
|
uint8_t _elmCnt;
|
||||||
uint8_t _publishedFlg;
|
uint8_t _publishedFlg;
|
||||||
|
uint8_t _autoConnectFlg;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* tomyAsyncClient */
|
} /* tomyAsyncClient */
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
@@ -34,25 +33,30 @@ extern bool theClientMode;
|
|||||||
/*=====================================
|
/*=====================================
|
||||||
TaskManager
|
TaskManager
|
||||||
======================================*/
|
======================================*/
|
||||||
LTaskManager::LTaskManager(void){
|
LTaskManager::LTaskManager(void)
|
||||||
|
{
|
||||||
_tasks = 0;
|
_tasks = 0;
|
||||||
_tests = 0;
|
_tests = 0;
|
||||||
_index = 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;
|
int i = 0;
|
||||||
char c = 0;
|
char c = 0;
|
||||||
bool cancelFlg = false;
|
bool cancelFlg = false;
|
||||||
@@ -99,9 +103,8 @@ void LTaskManager::run(void){
|
|||||||
{
|
{
|
||||||
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())
|
||||||
{
|
{
|
||||||
@@ -122,8 +125,7 @@ void LTaskManager::run(void){
|
|||||||
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)();
|
||||||
@@ -134,9 +136,8 @@ void LTaskManager::run(void){
|
|||||||
{
|
{
|
||||||
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())
|
||||||
{
|
{
|
||||||
@@ -146,11 +147,13 @@ void LTaskManager::run(void){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -167,7 +170,8 @@ void LTaskManager::done(uint8_t index){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LTaskManager::suspend(uint8_t index){
|
void LTaskManager::suspend(uint8_t index)
|
||||||
|
{
|
||||||
if (_tasks)
|
if (_tasks)
|
||||||
{
|
{
|
||||||
_tasks[index].count++;
|
_tasks[index].count++;
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
PROGNAME := MQTT-SNGateway
|
|
||||||
APPL := mainGateway
|
|
||||||
|
|
||||||
LPROGNAME := MQTT-SNLogmonitor
|
|
||||||
LAPPL := mainLogmonitor
|
|
||||||
|
|
||||||
TESTPROGNAME := testPFW
|
|
||||||
TESTAPPL := mainTestProcess
|
|
||||||
|
|
||||||
CONFIG := gateway.conf
|
|
||||||
CLIENTS := clients.conf
|
|
||||||
PREDEFTOPIC := predefinedTopic.conf
|
|
||||||
|
|
||||||
SRCDIR := src
|
|
||||||
SUBDIR := ../MQTTSNPacket/src
|
|
||||||
|
|
||||||
OS := linux
|
|
||||||
SENSORNET := udp
|
|
||||||
TEST := tests
|
|
||||||
|
|
||||||
INSTALL_DIR=../../
|
|
||||||
CONFIG_DIR=../../
|
|
||||||
|
|
||||||
CPPSRCS := \
|
|
||||||
$(SRCDIR)/MQTTGWConnectionHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTGWPacket.cpp \
|
|
||||||
$(SRCDIR)/MQTTGWPublishHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTGWSubscribeHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGateway.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWBrokerRecvTask.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWBrokerSendTask.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWClient.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWClientRecvTask.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWClientSendTask.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWConnectionHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWLogmonitor.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWPacket.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWPacketHandleTask.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWProcess.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWPublishHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWSubscribeHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWEncapsulatedPacket.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWForwarder.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWQoSm1Proxy.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWAdapter.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWAggregater.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWClientList.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWTopic.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWAdapterManager.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNAggregateConnectionHandler.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWMessageIdTable.cpp \
|
|
||||||
$(SRCDIR)/MQTTSNGWAggregateTopicTable.cpp \
|
|
||||||
$(SRCDIR)/$(OS)/$(SENSORNET)/SensorNetwork.cpp \
|
|
||||||
$(SRCDIR)/$(OS)/Timer.cpp \
|
|
||||||
$(SRCDIR)/$(OS)/Network.cpp \
|
|
||||||
$(SRCDIR)/$(OS)/Threading.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestProcess.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestQue.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestTree23.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestTopics.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestTopicIdMap.cpp \
|
|
||||||
$(SRCDIR)/$(TEST)/TestTask.cpp
|
|
||||||
|
|
||||||
|
|
||||||
CSRCS := $(SUBDIR)/MQTTSNConnectClient.c \
|
|
||||||
$(SUBDIR)/MQTTSNConnectServer.c \
|
|
||||||
$(SUBDIR)/MQTTSNDeserializePublish.c \
|
|
||||||
$(SUBDIR)/MQTTSNPacket.c \
|
|
||||||
$(SUBDIR)/MQTTSNSearchClient.c \
|
|
||||||
$(SUBDIR)/MQTTSNSearchServer.c \
|
|
||||||
$(SUBDIR)/MQTTSNSerializePublish.c \
|
|
||||||
$(SUBDIR)/MQTTSNSubscribeClient.c \
|
|
||||||
$(SUBDIR)/MQTTSNSubscribeServer.c \
|
|
||||||
$(SUBDIR)/MQTTSNUnsubscribeClient.c \
|
|
||||||
$(SUBDIR)/MQTTSNUnsubscribeServer.c
|
|
||||||
|
|
||||||
CPPFLAGS +=
|
|
||||||
|
|
||||||
INCLUDE :=
|
|
||||||
INCLUDES += $(INCLUDE) -I$(SRCDIR) \
|
|
||||||
-I$(SRCDIR)/$(OS) \
|
|
||||||
-I$(SRCDIR)/$(OS)/$(SENSORNET) \
|
|
||||||
-I$(SUBDIR) \
|
|
||||||
-I$(SRCDIR)/$(TEST) \
|
|
||||||
-I/usr/local/opt/openssl/include/
|
|
||||||
|
|
||||||
# preprocessor defines
|
|
||||||
DEFS :=
|
|
||||||
|
|
||||||
CXX := g++
|
|
||||||
|
|
||||||
LIB :=
|
|
||||||
LIBS += $(LIB) -L/usr/local/lib -L/usr/local/opt/openssl/lib/
|
|
||||||
|
|
||||||
LDFLAGS :=
|
|
||||||
CXXFLAGS := -Wall -O3 -std=c++11
|
|
||||||
LDADD := -lpthread -lssl -lcrypto
|
|
||||||
OUTDIR := Build
|
|
||||||
|
|
||||||
PROG := $(OUTDIR)/$(PROGNAME)
|
|
||||||
LPROG := $(OUTDIR)/$(LPROGNAME)
|
|
||||||
TPROG := $(OUTDIR)/$(TESTPROGNAME)
|
|
||||||
|
|
||||||
OBJS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.o)
|
|
||||||
OBJS += $(CSRCS:%.c=$(OUTDIR)/%.o)
|
|
||||||
DEPS := $(CPPSRCS:%.cpp=$(OUTDIR)/%.d)
|
|
||||||
DEPS += $(CSRCS:%.c=$(OUTDIR)/%.d)
|
|
||||||
|
|
||||||
.PHONY: install clean exectest
|
|
||||||
|
|
||||||
all: $(PROG) $(LPROG) $(TPROG)
|
|
||||||
|
|
||||||
monitor: $(LPROG)
|
|
||||||
|
|
||||||
test: $(TPROG) $(LPROG) exectest
|
|
||||||
|
|
||||||
|
|
||||||
-include $(DEPS)
|
|
||||||
|
|
||||||
$(PROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(APPL).o
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
|
||||||
|
|
||||||
$(LPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(LAPPL).o
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
|
||||||
|
|
||||||
$(TPROG): $(OBJS) $(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS) $(LDADD)
|
|
||||||
|
|
||||||
|
|
||||||
$(OUTDIR)/$(SRCDIR)/%.o:$(SRCDIR)/%.cpp
|
|
||||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
|
||||||
|
|
||||||
$(OUTDIR)/$(SRCDIR)/$(APPL).o:$(SRCDIR)/$(APPL).cpp
|
|
||||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
|
||||||
|
|
||||||
$(OUTDIR)/$(SRCDIR)/$(TEST)/$(TESTAPPL).o:$(SRCDIR)/$(TEST)/$(TESTAPPL).cpp
|
|
||||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
|
||||||
|
|
||||||
$(OUTDIR)/$(SRCDIR)/$(LAPPL).o:$(SRCDIR)/$(LAPPL).cpp
|
|
||||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
|
||||||
|
|
||||||
$(OUTDIR)/$(SUBDIR)/%.o:$(SUBDIR)/%.c
|
|
||||||
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
|
|
||||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(DEFS) -o $@ -c -MMD -MP -MF $(@:%.o=%.d) $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OUTDIR)
|
|
||||||
|
|
||||||
install:
|
|
||||||
cp -pf $(PROG) $(INSTALL_DIR)
|
|
||||||
cp -pf $(LPROG) $(INSTALL_DIR)
|
|
||||||
cp -pf $(CONFIG) $(CONFIG_DIR)
|
|
||||||
cp -pf $(CLIENTS) $(CONFIG_DIR)
|
|
||||||
cp -pf $(PREDEFTOPIC) $(CONFIG_DIR)
|
|
||||||
|
|
||||||
|
|
||||||
exectest:
|
|
||||||
./$(OUTDIR)/$(TESTPROGNAME) -f ./gateway.conf
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,145 +1,211 @@
|
|||||||
# MQTT-SN Transparent / Aggregating Gateway
|
# MQTT-SN 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** requires a MQTT-SN Gateway which acts as a protocol converter to convert **MQTT-SN messages to MQTT messages**. MQTT-SN client over SensorNetwork can not communicate directly with MQTT broker(TCP/IP).
|
MQTT-SN 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.
|
This Gateway can run as a transparent or aggregating Gateway by specifying the gateway.conf.
|
||||||
|
### step1. Build the gateway
|
||||||
### **step1. Build the gateway**
|
copy and expand source code then,
|
||||||
````
|
```
|
||||||
$ git clone -b develop https://github.com/eclipse/paho.mqtt-sn.embedded-c
|
|
||||||
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
$ cd paho.mqtt-sn.embedded-c/MQTTSNGateway
|
||||||
$ make [SENSORNET={udp6|xbee|loralink}]
|
```
|
||||||
$ make install
|
In order to build a gateway, one sensor network argument is required.
|
||||||
$ make clean
|
```
|
||||||
````
|
$ ./build.sh [udp|udp6|xbee|loralink|rfcomm|dtls|dtls6]
|
||||||
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.
|
MQTT-SNGateway and MQTT-SNLogmonitor (executable programs) are built in ./bin 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.
|
||||||
|
|
||||||
### **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
|
||||||
|
MulticastIP=225.1.1.1
|
||||||
MulticastTTL=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
42
MQTTSNGateway/build.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
build () {
|
||||||
|
echo "Start building MQTT-SN Gateway $1"
|
||||||
|
|
||||||
|
cd $SCRIPT_DIR/..
|
||||||
|
BDIR='build.gateway'
|
||||||
|
if [ ! -d ./$BDIR ]; then
|
||||||
|
mkdir $BDIR
|
||||||
|
fi
|
||||||
|
cd $BDIR
|
||||||
|
cmake .. -DSENSORNET=$1 -DDEFS="${2} ${3}"
|
||||||
|
make MQTTSNPacket
|
||||||
|
make MQTT-SNGateway
|
||||||
|
make MQTT-SNLogmonitor
|
||||||
|
cd ../MQTTSNGateway
|
||||||
|
cp *.conf ./bin/
|
||||||
|
}
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(cd $(dirname $0); pwd)
|
||||||
|
|
||||||
|
if [ $1 == "udp" ] ; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "udp6" ] ; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "xbee" ] ; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "loralink" ]; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "rfcomm" ] ; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "dtls" ] ; then
|
||||||
|
build $1 $2 $3
|
||||||
|
elif [ $1 == "dtls6" ] ; then
|
||||||
|
build dtls "${2} ${3} -DDTLS6"
|
||||||
|
elif [ $1 == "clean" ] ; then
|
||||||
|
rm -rf ../builg.gateway
|
||||||
|
else
|
||||||
|
echo "Usage: build.sh [ udp | udp6 | xbee | loralink | rfcomm | dtls | dtls6 | clean]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -15,10 +15,10 @@
|
|||||||
# Lines bigning with # are comment line.
|
# 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
151
MQTTSNGateway/src/CMakeLists.txt
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#*******************************************************************************
|
||||||
|
# Copyright (c) 2022 a1lu
|
||||||
|
#
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||||
|
#
|
||||||
|
# The Eclipse Public License is available at
|
||||||
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
# and the Eclipse Distribution License is available at
|
||||||
|
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
#
|
||||||
|
# Contributors:
|
||||||
|
# a1lu - initial version
|
||||||
|
# ty4tw - modify
|
||||||
|
#*******************************************************************************/
|
||||||
|
PROJECT(mqtt-sn-gateway CXX)
|
||||||
|
|
||||||
|
SET(GW_VERSION_MAJOR 1)
|
||||||
|
SET(GW_VERSION_MINOR 5)
|
||||||
|
SET(GW_VERSION_PATCH 1)
|
||||||
|
|
||||||
|
SET(GATEWAY_VERSION ${GW_VERSION_MAJOR}.${GW_VERSION_MINOR}.${GW_VERSION_PATCH})
|
||||||
|
MESSAGE(STATUS "VERSION : ${GATEWAY_VERSION}")
|
||||||
|
|
||||||
|
configure_file( MQTTSNGWVersion.h.in ${CMAKE_CURRENT_SOURCE_DIR}/MQTTSNGWVersion.h )
|
||||||
|
|
||||||
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../bin)
|
||||||
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
SET(OS linux)
|
||||||
|
|
||||||
|
IF(NOT DEFINED SENSORNET)
|
||||||
|
SET(SENSORNET udp)
|
||||||
|
ENDIF()
|
||||||
|
MESSAGE(STATUS "SENSORNET: " ${SENSORNET})
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(${DEFS})
|
||||||
|
MESSAGE(STATUS "Definitions: " ${DEFS})
|
||||||
|
|
||||||
|
ADD_LIBRARY(mqtt-sngateway_common
|
||||||
|
MQTTGWConnectionHandler.cpp
|
||||||
|
MQTTGWPacket.cpp
|
||||||
|
MQTTGWPublishHandler.cpp
|
||||||
|
MQTTGWSubscribeHandler.cpp
|
||||||
|
MQTTSNGateway.cpp
|
||||||
|
MQTTSNGWBrokerRecvTask.cpp
|
||||||
|
MQTTSNGWBrokerSendTask.cpp
|
||||||
|
MQTTSNGWClient.cpp
|
||||||
|
MQTTSNGWClientRecvTask.cpp
|
||||||
|
MQTTSNGWClientSendTask.cpp
|
||||||
|
MQTTSNGWConnectionHandler.cpp
|
||||||
|
MQTTSNGWLogmonitor.cpp
|
||||||
|
MQTTSNGWPacket.cpp
|
||||||
|
MQTTSNGWPacketHandleTask.cpp
|
||||||
|
MQTTSNGWProcess.cpp
|
||||||
|
MQTTSNGWPublishHandler.cpp
|
||||||
|
MQTTSNGWSubscribeHandler.cpp
|
||||||
|
MQTTSNGWEncapsulatedPacket.cpp
|
||||||
|
MQTTSNGWForwarder.cpp
|
||||||
|
MQTTSNGWQoSm1Proxy.cpp
|
||||||
|
MQTTSNGWAdapter.cpp
|
||||||
|
MQTTSNGWAggregater.cpp
|
||||||
|
MQTTSNGWClientList.cpp
|
||||||
|
MQTTSNGWTopic.cpp
|
||||||
|
MQTTSNGWAdapterManager.cpp
|
||||||
|
MQTTSNAggregateConnectionHandler.cpp
|
||||||
|
MQTTSNGWMessageIdTable.cpp
|
||||||
|
MQTTSNGWAggregateTopicTable.cpp
|
||||||
|
${OS}/${SENSORNET}/SensorNetwork.cpp
|
||||||
|
${OS}/${SENSORNET}/SensorNetwork.h
|
||||||
|
${OS}/Timer.cpp
|
||||||
|
${OS}/Timer.h
|
||||||
|
${OS}/Network.cpp
|
||||||
|
${OS}/Network.h
|
||||||
|
${OS}/Threading.cpp
|
||||||
|
${OS}/Threading.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# linux
|
||||||
|
link_directories("/usr/local/lib")
|
||||||
|
|
||||||
|
# Mac
|
||||||
|
link_directories("/usr/local/opt/openssl/lib")
|
||||||
|
|
||||||
|
|
||||||
|
TARGET_INCLUDE_DIRECTORIES(mqtt-sngateway_common
|
||||||
|
PUBLIC
|
||||||
|
.
|
||||||
|
${OS}
|
||||||
|
${OS}/${SENSORNET}
|
||||||
|
../../MQTTSNPacket/src
|
||||||
|
/usr/local/include
|
||||||
|
/usr/local/opt/openssl/include
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(SENSORNET MATCHES "rfcomm")
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||||
|
PRIVATE
|
||||||
|
MQTTSNPacket
|
||||||
|
pthread
|
||||||
|
ssl
|
||||||
|
crypto
|
||||||
|
bluetooth
|
||||||
|
)
|
||||||
|
ELSE()
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(mqtt-sngateway_common
|
||||||
|
PRIVATE
|
||||||
|
MQTTSNPacket
|
||||||
|
pthread
|
||||||
|
ssl
|
||||||
|
crypto
|
||||||
|
)
|
||||||
|
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(MQTT-SNGateway
|
||||||
|
mainGateway.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(MQTT-SNGateway
|
||||||
|
mqtt-sngateway_common
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(MQTT-SNLogmonitor
|
||||||
|
mainLogmonitor.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(MQTT-SNLogmonitor
|
||||||
|
mqtt-sngateway_common
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(testPFW
|
||||||
|
tests/mainTestProcess.cpp
|
||||||
|
tests/TestProcess.cpp
|
||||||
|
tests/TestQue.cpp
|
||||||
|
tests/TestTree23.cpp
|
||||||
|
tests/TestTopics.cpp
|
||||||
|
tests/TestTopicIdMap.cpp
|
||||||
|
tests/TestTask.cpp
|
||||||
|
)
|
||||||
|
TARGET_LINK_LIBRARIES(testPFW
|
||||||
|
mqtt-sngateway_common
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ADD_TEST(NAME testPFW
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/..
|
||||||
|
COMMAND testPFW -f ./gateway.conf)
|
||||||
@@ -49,8 +49,7 @@ void MQTTGWConnectionHandler::handleConnack(Client* client, MQTTGWPacket* packet
|
|||||||
else if (resp.rc == MQTT_IDENTIFIER_REJECTED)
|
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -49,7 +48,8 @@ int MQTTPacket_encode(char* buf, int length)
|
|||||||
if (length > 0)
|
if (length > 0)
|
||||||
d |= 0x80;
|
d |= 0x80;
|
||||||
buf[rc++] = d;
|
buf[rc++] = d;
|
||||||
} while (length > 0);
|
}
|
||||||
|
while (length > 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,8 @@ int MQTTGWPacket::recv(Network* network)
|
|||||||
}
|
}
|
||||||
_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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,18 +31,29 @@ 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
|
||||||
{
|
{
|
||||||
@@ -62,12 +73,12 @@ typedef union
|
|||||||
#endif
|
#endif
|
||||||
} Header;
|
} Header;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data for a connect packet.
|
* Data for a connect packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum MQTT_connackCodes{
|
enum MQTT_connackCodes
|
||||||
|
{
|
||||||
MQTT_CONNECTION_ACCEPTED,
|
MQTT_CONNECTION_ACCEPTED,
|
||||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
MQTT_UNACCEPTABLE_PROTOCOL_VERSION,
|
||||||
MQTT_IDENTIFIER_REJECTED,
|
MQTT_IDENTIFIER_REJECTED,
|
||||||
@@ -121,8 +132,6 @@ 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.
|
||||||
*/
|
*/
|
||||||
@@ -160,7 +169,6 @@ typedef struct
|
|||||||
char rc; /**< connack return code */
|
char rc; /**< connack return code */
|
||||||
} Connack;
|
} Connack;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data for a publish packet.
|
* Data for a publish packet.
|
||||||
*/
|
*/
|
||||||
@@ -214,11 +222,13 @@ public:
|
|||||||
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,
|
||||||
|
unsigned char* password);
|
||||||
int setPUBLISH(Publish* pub);
|
int setPUBLISH(Publish* pub);
|
||||||
int setAck(unsigned char msgType, unsigned short msgid);
|
int setAck(unsigned char msgType, unsigned short msgid);
|
||||||
int setHeader(unsigned char msgType);
|
int setHeader(unsigned char msgType);
|
||||||
int setSUBSCRIBE(const char* topic, unsigned char qos, unsigned short msgId);
|
int setSUBSCRIBE(const char* topic, unsigned char qos,
|
||||||
|
unsigned short msgId);
|
||||||
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
int setUNSUBSCRIBE(const char* topics, unsigned short msgid);
|
||||||
|
|
||||||
UTF8String getTopic(void);
|
UTF8String getTopic(void);
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
|||||||
{
|
{
|
||||||
if (!client->isActive() && !client->isSleep() && !client->isAwake())
|
if (!client->isActive() && !client->isSleep() && !client->isAwake())
|
||||||
{
|
{
|
||||||
WRITELOG("%s The client is neither active nor sleep %s%s\n", ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
WRITELOG("%s The client is neither active nor sleep %s%s\n",
|
||||||
|
ERRMSG_HEADER, client->getStatus(), ERRMSG_FOOTER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +66,8 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
|||||||
*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",
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
delete msg;
|
delete msg;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -99,16 +101,17 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
|||||||
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)
|
|
||||||
|
if (topic == nullptr && client->isCleanSession())
|
||||||
{
|
{
|
||||||
WRITELOG(" Invalid Topic. PUBLISH message is canceled.\n");
|
WRITELOG("%sMQTTGWPublishHandler Invalid Topic. PUBLISH message is discarded.%s\n",
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
if (pub.header.bits.qos == 1)
|
if (pub.header.bits.qos == 1)
|
||||||
{
|
{
|
||||||
replyACK(client, &pub, PUBACK);
|
replyACK(client, &pub, PUBACK);
|
||||||
@@ -122,10 +125,25 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (topic == nullptr)
|
||||||
|
{
|
||||||
|
topicId.type = MQTTSN_TOPIC_TYPE_NORMAL;
|
||||||
|
topicId.data.long_.len = pub.topiclen;
|
||||||
|
topicId.data.long_.name = pub.topic;
|
||||||
|
topicId.data.id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* add the Topic and get a TopicId */
|
/* add the Topic and get a TopicId */
|
||||||
topic = client->getTopics()->add(&topicId);
|
topic = client->getTopics()->add(&topicId);
|
||||||
|
if (topic == nullptr)
|
||||||
|
{
|
||||||
|
WRITELOG(
|
||||||
|
"%sMQTTGWPublishHandler Can't Add a Topic. MAX_TOPIC_PAR_CLIENT is exceeded. PUBLISH message is discarded.%s\n",
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
|
delete snPacket;
|
||||||
|
return;
|
||||||
|
}
|
||||||
id = topic->getTopicId();
|
id = topic->getTopicId();
|
||||||
|
|
||||||
if (id > 0)
|
if (id > 0)
|
||||||
{
|
{
|
||||||
/* create REGISTER */
|
/* create REGISTER */
|
||||||
@@ -145,15 +163,15 @@ void MQTTGWPublishHandler::handlePublish(Client* client, MQTTGWPacket* packet)
|
|||||||
|
|
||||||
/* send PUBLISH */
|
/* send PUBLISH */
|
||||||
topicId.data.id = id;
|
topicId.data.id = id;
|
||||||
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos,
|
snPacket->setPUBLISH((uint8_t) pub.header.bits.dup, (int) pub.header.bits.qos, (uint8_t) pub.header.bits.retain,
|
||||||
(uint8_t) pub.header.bits.retain, (uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload,
|
(uint16_t) pub.msgId, topicId, (uint8_t*) pub.payload, pub.payloadlen);
|
||||||
pub.payloadlen);
|
|
||||||
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
client->getWaitREGACKPacketList()->setPacket(snPacket, regackMsgId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
WRITELOG("%sMQTTGWPublishHandler Can't create a Topic. PUBLISH message is discarded.%s\n",
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
delete snPacket;
|
delete snPacket;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -193,7 +211,8 @@ void MQTTGWPublishHandler::handlePuback(Client* client, MQTTGWPacket* packet)
|
|||||||
_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)
|
||||||
@@ -234,8 +253,6 @@ void MQTTGWPublishHandler::handleAck(Client* client, MQTTGWPacket* packet, int t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
|
void MQTTGWPublishHandler::handleAggregatePuback(Client* client, MQTTGWPacket* packet)
|
||||||
{
|
{
|
||||||
uint16_t msgId = packet->getMsgId();
|
uint16_t msgId = packet->getMsgId();
|
||||||
@@ -272,7 +289,6 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket*
|
|||||||
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
|
string* topicName = new string(pub.topic, pub.topiclen); // topic deletes topicName when the topic is deleted
|
||||||
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
Topic topic = Topic(topicName, MQTTSN_TOPIC_TYPE_NORMAL);
|
||||||
|
|
||||||
@@ -287,7 +303,8 @@ void MQTTGWPublishHandler::handleAggregatePublish(Client* client, MQTTGWPacket*
|
|||||||
|
|
||||||
if (msg->getType() == 0)
|
if (msg->getType() == 0)
|
||||||
{
|
{
|
||||||
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n", ERRMSG_HEADER,ERRMSG_FOOTER);
|
WRITELOG("%s MQTTGWPublishHandler::handleAggregatePublish can't allocate memories for Packet.%s\n",
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
delete msg;
|
delete msg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTGWPUBLISHHANDLER_H_ */
|
#endif /* MQTTGWPUBLISHHANDLER_H_ */
|
||||||
|
|||||||
@@ -96,4 +96,3 @@ void MQTTGWSubscribeHandler::handleAggregateUnsuback(Client* client, MQTTGWPacke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ MQTTSNAggregateConnectionHandler::~MQTTSNAggregateConnectionHandler()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CONNECT
|
* CONNECT
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +69,6 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
|||||||
|
|
||||||
/* CONNECT was not sent yet. prepare Connect data */
|
/* CONNECT was not sent yet. prepare Connect data */
|
||||||
|
|
||||||
|
|
||||||
client->setSessionStatus(false);
|
client->setSessionStatus(false);
|
||||||
if (data.cleansession)
|
if (data.cleansession)
|
||||||
{
|
{
|
||||||
@@ -120,7 +118,6 @@ void MQTTSNAggregateConnectionHandler::handleConnect(Client* client, MQTTSNPacke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WILLMSG
|
* WILLMSG
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
using namespace MQTTSNGW;
|
using namespace MQTTSNGW;
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Adapter
|
Class Adapter
|
||||||
=====================================*/
|
=====================================*/
|
||||||
@@ -48,7 +47,6 @@ Adapter::~Adapter(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
||||||
{
|
{
|
||||||
_isSecure = false;
|
_isSecure = false;
|
||||||
@@ -69,12 +67,12 @@ void Adapter::setup(const char* adpterName, AdapterType adapterType)
|
|||||||
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,
|
||||||
|
TRANSPEARENT_TYPE);
|
||||||
setClient(client, true);
|
setClient(client, true);
|
||||||
client->setAdapterType(adapterType);
|
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);
|
||||||
@@ -174,7 +172,8 @@ void Adapter::send(MQTTSNPacket* packet, Client* client)
|
|||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +211,6 @@ void Adapter::savePacket(Client* client, MQTTSNPacket* packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Client* Adapter::getAdapterClient(Client* client)
|
Client* Adapter::getAdapterClient(Client* client)
|
||||||
{
|
{
|
||||||
if (client->isSecureNetwork())
|
if (client->isSecureNetwork())
|
||||||
@@ -276,7 +274,6 @@ void Proxy::checkConnection(Client* client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Proxy::resetPingTimer(void)
|
void Proxy::resetPingTimer(void)
|
||||||
{
|
{
|
||||||
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
|
_keepAliveTimer.start(PROXY_KEEPALIVE_DURATION * 1000UL);
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ 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
|
Atype_QoSm1Proxy, Atype_Aggregater
|
||||||
} AdapterType;
|
} AdapterType;
|
||||||
|
|
||||||
@@ -69,7 +70,6 @@ private:
|
|||||||
bool _isSecure { false };
|
bool _isSecure { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Proxy
|
Class Proxy
|
||||||
=====================================*/
|
=====================================*/
|
||||||
@@ -88,7 +88,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void sendSuspendedPacket(void);
|
void sendSuspendedPacket(void);
|
||||||
Gateway* _gateway;
|
Gateway* _gateway;
|
||||||
EventQue* _suspendedPacketEventQue {nullptr};
|
EventQue* _suspendedPacketEventQue
|
||||||
|
{ nullptr };
|
||||||
Timer _keepAliveTimer;
|
Timer _keepAliveTimer;
|
||||||
Timer _responseTimer;
|
Timer _responseTimer;
|
||||||
bool _isWaitingResp { false };
|
bool _isWaitingResp { false };
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ AdapterManager::AdapterManager(Gateway* 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)
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ 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:
|
||||||
@@ -59,8 +60,5 @@ private:
|
|||||||
Aggregater* _aggregater { nullptr };
|
Aggregater* _aggregater { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWADAPTERMANAGER_H_ */
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ 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);
|
||||||
|
|
||||||
@@ -103,6 +104,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATETOPICTABLE_H_ */
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
|
|
||||||
using namespace MQTTSNGW;
|
using namespace MQTTSNGW;
|
||||||
|
|
||||||
Aggregater::Aggregater(Gateway* gw) : Adapter(gw)
|
Aggregater::Aggregater(Gateway* gw) :
|
||||||
|
Adapter(gw)
|
||||||
{
|
{
|
||||||
_gateway = gw;
|
_gateway = gw;
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,6 @@ 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.*/
|
||||||
@@ -89,7 +89,6 @@ AggregateTopicElement* Aggregater::addAggregateTopic(Topic* topic, Client* clien
|
|||||||
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);
|
||||||
|
|||||||
@@ -73,10 +73,6 @@ private:
|
|||||||
bool _isSecure { false };
|
bool _isSecure { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWAGGREGATER_H_ */
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -32,11 +33,11 @@ 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()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +65,7 @@ void BrokerRecvTask::run(void)
|
|||||||
_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;
|
||||||
@@ -100,6 +101,7 @@ void BrokerRecvTask::run(void)
|
|||||||
{
|
{
|
||||||
/* 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)
|
if (activity > 0)
|
||||||
{
|
{
|
||||||
client = _gateway->getClientList()->getClient(0);
|
client = _gateway->getClientList()->getClient(0);
|
||||||
@@ -134,47 +136,43 @@ void BrokerRecvTask::run(void)
|
|||||||
{
|
{
|
||||||
if (rc == 0) // Disconnected
|
if (rc == 0) // Disconnected
|
||||||
{
|
{
|
||||||
|
WRITELOG("%s BrokerRecvTask %s is disconnected by the broker.%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
client->getNetwork()->close();
|
client->getNetwork()->close();
|
||||||
delete packet;
|
client->disconnected();
|
||||||
|
|
||||||
/* delete client when the client is not authorized & session is clean */
|
|
||||||
_gateway->getClientList()->erase(client);
|
|
||||||
|
|
||||||
if ( client )
|
|
||||||
{
|
|
||||||
client = client->getNextClient();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else if (rc == -1)
|
else if (rc == -1)
|
||||||
{
|
{
|
||||||
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n", ERRMSG_HEADER, errno, client->getClientId(), ERRMSG_FOOTER);
|
WRITELOG("%s BrokerRecvTask can't receive a packet from the broker errno=%d %s%s\n",
|
||||||
|
ERRMSG_HEADER, errno, client->getClientId(),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
}
|
}
|
||||||
else if (rc == -2)
|
else if (rc == -2)
|
||||||
{
|
{
|
||||||
WRITELOG("%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n", ERRMSG_HEADER, client->getClientId(),ERRMSG_FOOTER);
|
WRITELOG(
|
||||||
|
"%s BrokerRecvTask receive invalid length of packet from the broker. DISCONNECT %s %s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
}
|
}
|
||||||
else if (rc == -3)
|
else if (rc == -3)
|
||||||
{
|
{
|
||||||
WRITELOG("%s BrokerRecvTask can't get memories for the packet %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
WRITELOG("%s BrokerRecvTask can't allocate memories for the packet %s%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete packet;
|
delete packet;
|
||||||
|
|
||||||
if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
|
if ((rc == -1 || rc == -2) && (client->isActive() || client->isSleep() || client->isAwake()))
|
||||||
{
|
{
|
||||||
/* disconnect the client */
|
client->getNetwork()->close();
|
||||||
packet = new MQTTGWPacket();
|
client->disconnected();
|
||||||
packet->setHeader(DISCONNECT);
|
|
||||||
ev = new Event();
|
|
||||||
ev->setBrokerRecvEvent(client, packet);
|
|
||||||
_gateway->getPacketEventQue()->post(ev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextClient:
|
nextClient: client = client->getNextClient();
|
||||||
client = client->getNextClient();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,17 +194,20 @@ int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
|||||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
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,
|
||||||
|
client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case PUBACK:
|
case PUBACK:
|
||||||
case PUBREC:
|
case PUBREC:
|
||||||
case PUBREL:
|
case PUBREL:
|
||||||
case PUBCOMP:
|
case PUBCOMP:
|
||||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||||
|
client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case SUBACK:
|
case SUBACK:
|
||||||
case UNSUBACK:
|
case UNSUBACK:
|
||||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), LEFTARROWB,
|
||||||
|
client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case PINGRESP:
|
case PINGRESP:
|
||||||
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));
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ 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();
|
||||||
@@ -44,5 +44,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGWBROKERRECVTASK_H_ */
|
#endif /* MQTTSNGWBROKERRECVTASK_H_ */
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ BrokerSendTask::BrokerSendTask(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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +70,7 @@ void BrokerSendTask::run()
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -94,8 +94,9 @@ void BrokerSendTask::run()
|
|||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
@@ -151,7 +152,6 @@ void BrokerSendTask::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* write message content into stdout or Ringbuffer
|
* write message content into stdout or Ringbuffer
|
||||||
*/
|
*/
|
||||||
@@ -163,10 +163,12 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
|||||||
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(),
|
||||||
|
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case PUBLISH:
|
case PUBLISH:
|
||||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||||
|
client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case SUBSCRIBE:
|
case SUBSCRIBE:
|
||||||
case UNSUBSCRIBE:
|
case UNSUBSCRIBE:
|
||||||
@@ -174,13 +176,16 @@ void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
|||||||
case PUBREC:
|
case PUBREC:
|
||||||
case PUBREL:
|
case PUBREL:
|
||||||
case PUBCOMP:
|
case PUBCOMP:
|
||||||
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_Y_W, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROWB,
|
||||||
|
client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case PINGREQ:
|
case PINGREQ:
|
||||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||||
|
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case DISCONNECT:
|
case DISCONNECT:
|
||||||
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(), RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
WRITELOG(FORMAT_Y_Y_W, currentDateTime(), packet->getName(),
|
||||||
|
RIGHTARROWB, client->getClientId(), packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -28,17 +28,17 @@
|
|||||||
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;
|
||||||
@@ -58,7 +58,7 @@ Client::Client(bool secure)
|
|||||||
_hasPredefTopic = false;
|
_hasPredefTopic = false;
|
||||||
_holdPingRequest = false;
|
_holdPingRequest = false;
|
||||||
_forwarder = nullptr;
|
_forwarder = nullptr;
|
||||||
_clientType = Ctype_Regular;
|
_clientType = Ctype_Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
@@ -177,13 +177,14 @@ 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)
|
||||||
@@ -280,8 +281,7 @@ void Client::updateStatus(MQTTSNPacket* packet)
|
|||||||
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)
|
||||||
@@ -317,6 +317,11 @@ 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)
|
||||||
@@ -537,7 +542,7 @@ void Client::setAdapterType(AdapterType type)
|
|||||||
_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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,8 +582,6 @@ bool Client::isHoldPingReqest(void)
|
|||||||
return _holdPingRequest;
|
return _holdPingRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class WaitREGACKPacket
|
Class WaitREGACKPacket
|
||||||
=====================================*/
|
=====================================*/
|
||||||
@@ -691,4 +694,3 @@ uint8_t WaitREGACKPacketList::getCount(void)
|
|||||||
return _cnt;
|
return _cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,19 +147,29 @@ 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,
|
||||||
|
Ctype_Forwarded,
|
||||||
|
Ctype_QoS_1,
|
||||||
|
Ctype_Aggregated,
|
||||||
|
Ctype_Proxy,
|
||||||
|
Ctype_Aggregater
|
||||||
} ClientType;
|
} ClientType;
|
||||||
|
|
||||||
class Forwarder;
|
class Forwarder;
|
||||||
@@ -171,6 +177,7 @@ 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);
|
||||||
@@ -193,8 +200,8 @@ public:
|
|||||||
|
|
||||||
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);
|
||||||
@@ -299,7 +307,5 @@ private:
|
|||||||
Client* _prevClient;
|
Client* _prevClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* MQTTSNGWCLIENT_H_ */
|
#endif /* MQTTSNGWCLIENT_H_ */
|
||||||
|
|||||||
@@ -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,12 +48,20 @@ 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)
|
||||||
@@ -62,7 +72,7 @@ void ClientList::initialize(bool aggregate)
|
|||||||
_authorize = true;
|
_authorize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( theGateway->getGWParams()->predefinedTopic )
|
if (_gateway->getGWParams()->predefinedTopic)
|
||||||
{
|
{
|
||||||
setPredefinedTopics(aggregate);
|
setPredefinedTopics(aggregate);
|
||||||
}
|
}
|
||||||
@@ -70,17 +80,17 @@ void ClientList::initialize(bool 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +164,7 @@ bool ClientList::createList(const char* fileName, int 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)
|
||||||
{
|
{
|
||||||
@@ -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)
|
||||||
@@ -297,7 +308,6 @@ Client* ClientList::getClient(int index)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Client* ClientList::getClient(MQTTSNString* clientId)
|
Client* ClientList::getClient(MQTTSNString* clientId)
|
||||||
{
|
{
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
@@ -329,22 +339,23 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
/* anonimous clients */
|
|
||||||
if ( _clientCnt > MAX_CLIENTS )
|
|
||||||
{
|
|
||||||
return 0; // full of clients
|
|
||||||
}
|
|
||||||
|
|
||||||
client = getClient(addr);
|
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creat a new client */
|
/* acquire a free client */
|
||||||
client = new Client(secure);
|
client = _clientsPool->getClient();
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
|
||||||
|
ERRMSG_HEADER, ERRMSG_FOOTER);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->disconnected();
|
||||||
if (addr)
|
if (addr)
|
||||||
{
|
{
|
||||||
client->setClientAddress(addr);
|
client->setClientAddress(addr);
|
||||||
@@ -370,6 +381,7 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
|||||||
{
|
{
|
||||||
client->setQoSm1();
|
client->setQoSm1();
|
||||||
}
|
}
|
||||||
|
client->getNetwork()->setSecure(secure);
|
||||||
|
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
|
|
||||||
@@ -400,7 +412,7 @@ Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicN
|
|||||||
|
|
||||||
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
|
||||||
@@ -412,37 +424,11 @@ Client* ClientList::createPredefinedTopic( MQTTSNString* clientId, string topicN
|
|||||||
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 */
|
|
||||||
if ( _firstClient == nullptr )
|
|
||||||
{
|
|
||||||
_firstClient = client;
|
|
||||||
_endClient = client;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_endClient->_nextClient = client;
|
|
||||||
client->_prevClient = _endClient;
|
|
||||||
_endClient = client;
|
|
||||||
}
|
|
||||||
_clientCnt++;
|
|
||||||
_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create Topic & Add it
|
// create Topic & Add it
|
||||||
@@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
uint16_t _maxClients;
|
||||||
bool _authorize { false };
|
bool _authorize { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWCLIENTLIST_H_ */
|
||||||
|
|||||||
@@ -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);
|
||||||
/*=====================================
|
/*=====================================
|
||||||
@@ -32,27 +30,20 @@ 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()
|
||||||
@@ -63,6 +54,7 @@ void ClientRecvTask::run()
|
|||||||
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];
|
||||||
|
|
||||||
@@ -77,7 +69,7 @@ void ClientRecvTask::run()
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -104,12 +96,11 @@ void ClientRecvTask::run()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SensorNetAddress senderAddr = *_gateway->getSensorNetwork()->getSenderAddress();
|
||||||
SensorNetAddress* senderAddr = _gateway->getSensorNetwork()->getSenderAddress();
|
|
||||||
|
|
||||||
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
if (packet->getType() == MQTTSN_ENCAPSULATED)
|
||||||
{
|
{
|
||||||
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(senderAddr);
|
fwd = _gateway->getAdapterManager()->getForwarderList()->getForwarder(&senderAddr);
|
||||||
|
|
||||||
if (fwd != nullptr)
|
if (fwd != nullptr)
|
||||||
{
|
{
|
||||||
@@ -131,7 +122,7 @@ void ClientRecvTask::run()
|
|||||||
|
|
||||||
if (qosm1Proxy->isActive())
|
if (qosm1Proxy->isActive())
|
||||||
{
|
{
|
||||||
const char* clientName = qosm1Proxy->getClientId(senderAddr);
|
const char *clientName = qosm1Proxy->getClientId(&senderAddr);
|
||||||
|
|
||||||
if (clientName != nullptr)
|
if (clientName != nullptr)
|
||||||
{
|
{
|
||||||
@@ -140,7 +131,8 @@ void ClientRecvTask::run()
|
|||||||
if (!packet->isQoSMinusPUBLISH())
|
if (!packet->isQoSMinusPUBLISH())
|
||||||
{
|
{
|
||||||
log(clientName, packet);
|
log(clientName, packet);
|
||||||
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n", ERRMSG_HEADER, clientName, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
WRITELOG("%s %s %s can send only PUBLISH with QoS-1.%s\n",
|
||||||
|
ERRMSG_HEADER, clientName, senderAddr.sprint(buf), ERRMSG_FOOTER);
|
||||||
delete packet;
|
delete packet;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -149,18 +141,35 @@ void ClientRecvTask::run()
|
|||||||
|
|
||||||
if (client == nullptr)
|
if (client == nullptr)
|
||||||
{
|
{
|
||||||
client = _gateway->getClientList()->getClient(senderAddr);
|
client = _gateway->getClientList()->getClient(&senderAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client != nullptr)
|
if (client != nullptr)
|
||||||
{
|
{
|
||||||
/* write log and post Event */
|
|
||||||
log(client, packet, 0);
|
log(client, packet, 0);
|
||||||
|
|
||||||
|
if (client->isDisconnect() && packet->getType() != MQTTSN_CONNECT)
|
||||||
|
{
|
||||||
|
WRITELOG("%s MQTTSNGWClientRecvTask %s is not connecting.%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||||
|
|
||||||
|
/* send DISCONNECT to the client, if it is not connected */
|
||||||
|
MQTTSNPacket* snPacket = new MQTTSNPacket();
|
||||||
|
snPacket->setDISCONNECT(0);
|
||||||
|
ev = new Event();
|
||||||
|
ev->setClientSendEvent(client, snPacket);
|
||||||
|
clientsendQue->post(ev);
|
||||||
|
delete packet;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ev = new Event();
|
ev = new Event();
|
||||||
ev->setClientRecvEvent(client, packet);
|
ev->setClientRecvEvent(client, packet);
|
||||||
packetEventQue->post(ev);
|
packetEventQue->post(ev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* new client */
|
/* new client */
|
||||||
@@ -171,7 +180,9 @@ void ClientRecvTask::run()
|
|||||||
if (!packet->getCONNECT(&data))
|
if (!packet->getCONNECT(&data))
|
||||||
{
|
{
|
||||||
log(0, packet, &data.clientID);
|
log(0, packet, &data.clientID);
|
||||||
WRITELOG("%s CONNECT message form %s is incorrect.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
WRITELOG("%s CONNECT message form %s is incorrect.%s\n",
|
||||||
|
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
delete packet;
|
delete packet;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -195,13 +206,13 @@ void ClientRecvTask::run()
|
|||||||
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +220,9 @@ void ClientRecvTask::run()
|
|||||||
|
|
||||||
if (client == nullptr)
|
if (client == nullptr)
|
||||||
{
|
{
|
||||||
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
WRITELOG("%s Client(%s) was rejected. CONNECT message has been discarded.%s\n",
|
||||||
|
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
delete packet;
|
delete packet;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -224,11 +237,16 @@ void ClientRecvTask::run()
|
|||||||
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",
|
||||||
|
ERRMSG_HEADER, _sensorNetwork->getSenderAddress()->sprint(buf),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n", ERRMSG_HEADER, senderAddr->sprint(buf), ERRMSG_FOOTER);
|
WRITELOG("%s MQTTSNGWClientRecvTask Client(%s) is not connecting. message has been discarded.%s\n",
|
||||||
|
ERRMSG_HEADER, senderAddr.sprint(buf),
|
||||||
|
ERRMSG_FOOTER);
|
||||||
}
|
}
|
||||||
delete packet;
|
delete 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,14 +312,16 @@ 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));
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ 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()
|
||||||
@@ -51,7 +51,7 @@ void ClientSendTask::run()
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,8 @@ void ClientSendTask::run()
|
|||||||
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;
|
||||||
@@ -102,7 +103,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
|||||||
{
|
{
|
||||||
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,
|
||||||
|
CLIENTS, packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case MQTTSN_CONNACK:
|
case MQTTSN_CONNACK:
|
||||||
case MQTTSN_DISCONNECT:
|
case MQTTSN_DISCONNECT:
|
||||||
@@ -115,7 +117,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
|||||||
break;
|
break;
|
||||||
case MQTTSN_REGISTER:
|
case MQTTSN_REGISTER:
|
||||||
case MQTTSN_PUBLISH:
|
case MQTTSN_PUBLISH:
|
||||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||||
|
packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
case MQTTSN_REGACK:
|
case MQTTSN_REGACK:
|
||||||
case MQTTSN_PUBACK:
|
case MQTTSN_PUBACK:
|
||||||
@@ -124,7 +127,8 @@ void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
|||||||
case MQTTSN_PUBCOMP:
|
case MQTTSN_PUBCOMP:
|
||||||
case MQTTSN_SUBACK:
|
case MQTTSN_SUBACK:
|
||||||
case MQTTSN_UNSUBACK:
|
case MQTTSN_UNSUBACK:
|
||||||
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId, packet->print(pbuf));
|
WRITELOG(FORMAT_W_MSGID_W_G, currentDateTime(), packet->getName(), packet->getMsgId(msgId), RIGHTARROW, clientId,
|
||||||
|
packet->print(pbuf));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
|||||||
/* renew the TopicList */
|
/* renew the TopicList */
|
||||||
if (topics)
|
if (topics)
|
||||||
{
|
{
|
||||||
topics->eraseNormal();;
|
topics->eraseNormal();
|
||||||
|
;
|
||||||
}
|
}
|
||||||
client->setSessionStatus(true);
|
client->setSessionStatus(true);
|
||||||
}
|
}
|
||||||
@@ -146,7 +147,8 @@ void MQTTSNConnectionHandler::handleConnect(Client* client, MQTTSNPacket* packet
|
|||||||
/* 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,
|
||||||
|
(unsigned char*) _gateway->getGWParams()->password);
|
||||||
Event* ev1 = new Event();
|
Event* ev1 = new Event();
|
||||||
ev1->setBrokerSendEvent(client, mqMsg);
|
ev1->setBrokerSendEvent(client, mqMsg);
|
||||||
_gateway->getBrokerSendQue()->post(ev1);
|
_gateway->getBrokerSendQue()->post(ev1);
|
||||||
@@ -209,7 +211,8 @@ void MQTTSNConnectionHandler::handleWillmsg(Client* client, MQTTSNPacket* packet
|
|||||||
/* 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();
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -60,14 +60,19 @@ 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_ */
|
||||||
|
|||||||
@@ -21,10 +21,8 @@
|
|||||||
using namespace MQTTSNGW;
|
using namespace MQTTSNGW;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
WirelessNodeId::WirelessNodeId()
|
WirelessNodeId::WirelessNodeId() :
|
||||||
:
|
_len { 0 }, _nodeId { 0 }
|
||||||
_len{0},
|
|
||||||
_nodeId{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}
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWENCAPSULATEDPACKET_H_ */
|
||||||
|
|||||||
@@ -44,14 +44,12 @@ 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;
|
||||||
@@ -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}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "MQTTSNGWEncapsulatedPacket.h"
|
#include "MQTTSNGWEncapsulatedPacket.h"
|
||||||
#include "SensorNetwork.h"
|
#include "SensorNetwork.h"
|
||||||
|
|
||||||
|
|
||||||
namespace MQTTSNGW
|
namespace MQTTSNGW
|
||||||
{
|
{
|
||||||
class Gateway;
|
class Gateway;
|
||||||
@@ -94,6 +93,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWFORWARDER_H_ */
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ MessageIdElement* MessageIdTable::find(Client* client, uint16_t clientMsgId)
|
|||||||
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;
|
||||||
@@ -179,7 +178,6 @@ void MessageIdTable::clear(MessageIdElement* elm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -194,18 +192,14 @@ uint16_t MessageIdTable::getMsgId(Client* client, uint16_t clientMsgId)
|
|||||||
/*===============================
|
/*===============================
|
||||||
* 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;
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public:
|
|||||||
MessageIdTable();
|
MessageIdTable();
|
||||||
~MessageIdTable();
|
~MessageIdTable();
|
||||||
|
|
||||||
MessageIdElement* add(Aggregater* aggregater, Client* client, uint16_t clientMsgId);
|
MessageIdElement* add(Aggregater* aggregater, Client* client,
|
||||||
|
uint16_t clientMsgId);
|
||||||
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
Client* getClientMsgId(uint16_t msgId, uint16_t* clientMsgId);
|
||||||
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
uint16_t getMsgId(Client* client, uint16_t clientMsgId);
|
||||||
void erase(uint16_t msgId);
|
void erase(uint16_t msgId);
|
||||||
@@ -72,7 +73,6 @@ private:
|
|||||||
MessageIdElement* _prev;
|
MessageIdElement* _prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWMESSAGEIDTABLE_H_ */
|
||||||
|
|||||||
@@ -100,10 +100,6 @@ int MQTTSNPacket::recv(SensorNetwork* network)
|
|||||||
{
|
{
|
||||||
len = desirialize(buf, len);
|
len = desirialize(buf, len);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -149,8 +145,7 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,8 +200,7 @@ int MQTTSNPacket::setREGISTER(uint16_t topicId, uint16_t msgId, MQTTSNString* to
|
|||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,18 +208,17 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,8 +226,7 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,8 +258,8 @@ int MQTTSNPacket::setSUBACK(int qos, uint16_t topicId, uint16_t msgId, uint8_t r
|
|||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,26 +346,26 @@ int MQTTSNPacket::getWILLMSG(MQTTSNString* willmsg)
|
|||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace MQTTSNGW
|
namespace MQTTSNGW
|
||||||
{
|
{
|
||||||
|
class SensorNetwork;
|
||||||
|
|
||||||
class MQTTSNPacket
|
class MQTTSNPacket
|
||||||
{
|
{
|
||||||
@@ -53,7 +54,8 @@ public:
|
|||||||
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,
|
||||||
|
uint8_t returnCode);
|
||||||
int setUNSUBACK(uint16_t msgId);
|
int setUNSUBACK(uint16_t msgId);
|
||||||
int setPINGRESP(void);
|
int setPINGRESP(void);
|
||||||
int setDISCONNECT(uint16_t duration);
|
int setDISCONNECT(uint16_t duration);
|
||||||
@@ -66,19 +68,23 @@ public:
|
|||||||
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,
|
||||||
|
MQTTSNString* willTopic);
|
||||||
int getWILLMSG(MQTTSNString* willmsg);
|
int getWILLMSG(MQTTSNString* willmsg);
|
||||||
int getREGISTER(uint16_t* topicId, uint16_t* msgId, MQTTSNString* topicName);
|
int getREGISTER(uint16_t* topicId, uint16_t* msgId,
|
||||||
|
MQTTSNString* topicName);
|
||||||
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
int getREGACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||||
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
int getPUBLISH(uint8_t* dup, int* qos, uint8_t* retained, uint16_t* msgId,
|
||||||
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
MQTTSN_topicid* topic, unsigned char** payload, int* payloadlen);
|
||||||
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
int getPUBACK(uint16_t* topicId, uint16_t* msgId, uint8_t* returnCode);
|
||||||
int getACK(uint16_t* msgId);
|
int getACK(uint16_t* msgId);
|
||||||
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
int getSUBSCRIBE(uint8_t* dup, int* qos, uint16_t* msgId,
|
||||||
|
MQTTSN_topicid* topicFilter);
|
||||||
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
int getUNSUBSCRIBE(uint16_t* msgId, MQTTSN_topicid* topicFilter);
|
||||||
int getPINGREQ(void);
|
int getPINGREQ(void);
|
||||||
int getDISCONNECT(uint16_t* duration);
|
int getDISCONNECT(uint16_t* duration);
|
||||||
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain, MQTTSNString* willTopic);
|
int getWILLTOPICUPD(uint8_t* willQoS, uint8_t* willRetain,
|
||||||
|
MQTTSNString* willTopic);
|
||||||
int getWILLMSGUPD(MQTTSNString* willMsg);
|
int getWILLMSGUPD(MQTTSNString* willMsg);
|
||||||
|
|
||||||
bool isAccepted(void);
|
bool isAccepted(void);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ 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
|
||||||
=====================================*/
|
=====================================*/
|
||||||
@@ -54,6 +55,7 @@ PacketHandleTask::PacketHandleTask(Gateway* gateway)
|
|||||||
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
_mqttsnSubscribe = new MQTTSNSubscribeHandler(_gateway);
|
||||||
|
|
||||||
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
_mqttsnAggrConnection = new MQTTSNAggregateConnectionHandler(_gateway);
|
||||||
|
setTaskName("PacketHandleTask");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,7 +115,7 @@ void PacketHandleTask::run()
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -155,7 +157,6 @@ void PacketHandleTask::run()
|
|||||||
transparentPacketHandler(client, snPacket);
|
transparentPacketHandler(client, snPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset the Timer for PINGREQ. */
|
/* Reset the Timer for PINGREQ. */
|
||||||
client->updateStatus(snPacket);
|
client->updateStatus(snPacket);
|
||||||
}
|
}
|
||||||
@@ -166,7 +167,6 @@ void PacketHandleTask::run()
|
|||||||
brPacket = ev->getMQTTGWPacket();
|
brPacket = ev->getMQTTGWPacket();
|
||||||
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
DEBUGLOG(" PacketHandleTask gets %s %s from the broker.\n", brPacket->getName(), brPacket->getMsgId(msgId));
|
||||||
|
|
||||||
|
|
||||||
if (client->isAggregater())
|
if (client->isAggregater())
|
||||||
{
|
{
|
||||||
aggregatePacketHandler(client, brPacket);
|
aggregatePacketHandler(client, brPacket);
|
||||||
@@ -180,8 +180,6 @@ void PacketHandleTask::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
|
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packet)
|
||||||
{
|
{
|
||||||
switch (packet->getType())
|
switch (packet->getType())
|
||||||
@@ -239,7 +237,6 @@ void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTSNPacket* packe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
|
void PacketHandleTask::aggregatePacketHandler(Client*client, MQTTGWPacket* packet)
|
||||||
{
|
{
|
||||||
switch (packet->getType())
|
switch (packet->getType())
|
||||||
@@ -333,7 +330,6 @@ void PacketHandleTask::transparentPacketHandler(Client*client, MQTTSNPacket* pac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
|
void PacketHandleTask::transparentPacketHandler(Client*client, MQTTGWPacket* packet)
|
||||||
{
|
{
|
||||||
switch (packet->getType())
|
switch (packet->getType())
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ private:
|
|||||||
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
|
||||||
|
{ nullptr };
|
||||||
Timer _advertiseTimer;
|
Timer _advertiseTimer;
|
||||||
Timer _sendUnixTimer;
|
Timer _sendUnixTimer;
|
||||||
MQTTGWConnectionHandler* _mqttConnection { nullptr };
|
MQTTGWConnectionHandler* _mqttConnection { nullptr };
|
||||||
@@ -69,11 +70,9 @@ private:
|
|||||||
MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
|
MQTTSNConnectionHandler* _mqttsnConnection { nullptr };
|
||||||
MQTTSNPublishHandler* _mqttsnPublish { nullptr };
|
MQTTSNPublishHandler* _mqttsnPublish { nullptr };
|
||||||
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
|
MQTTSNSubscribeHandler* _mqttsnSubscribe { nullptr };
|
||||||
|
|
||||||
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
|
MQTTSNAggregateConnectionHandler* _mqttsnAggrConnection { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */
|
#endif /* MQTTSNGWPACKETHANDLETASK_H_ */
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -57,6 +57,8 @@ Process::Process()
|
|||||||
_configDir = CONFIG_DIRECTORY;
|
_configDir = CONFIG_DIRECTORY;
|
||||||
_configFile = CONFIG_FILE;
|
_configFile = CONFIG_FILE;
|
||||||
_log = 0;
|
_log = 0;
|
||||||
|
_rbsem = NULL;
|
||||||
|
_rb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::~Process()
|
Process::~Process()
|
||||||
@@ -98,7 +100,7 @@ void Process::initialize(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,6 +157,8 @@ 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];
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
memset(param, 0, sizeof(param));
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
@@ -162,27 +166,41 @@ int Process::getParam(const char* parameter, char* value)
|
|||||||
|
|
||||||
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
if ((fp = fopen(configPath.c_str(), "r")) == NULL)
|
||||||
{
|
{
|
||||||
throw Exception("No config file:[" + configPath + "]\n");
|
throw Exception("Config file not found:\n\nUsage: Command -f path/config_file_name\n", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int paramlen = strlen(parameter);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
int pos = 0;
|
||||||
|
int len = 0;
|
||||||
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
if (fgets(str, MQTTSNGW_PARAM_MAX - 1, fp) == NULL)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
if (!strncmp(str, parameter, strlen(parameter)))
|
if (str[0] == '#' || str[0] == '\n')
|
||||||
{
|
{
|
||||||
while (str[i++] != '=')
|
continue;
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
while (str[i] != '\n')
|
|
||||||
|
len = strlen(str);
|
||||||
|
for (pos = 0; i < len; pos++)
|
||||||
{
|
{
|
||||||
param[j++] = str[i++];
|
if (str[pos] == '=')
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
param[j] = '\0';
|
}
|
||||||
|
|
||||||
|
if (pos == paramlen)
|
||||||
|
{
|
||||||
|
if (strncmp(str, parameter, paramlen) == 0)
|
||||||
|
{
|
||||||
|
strcpy(param, str + pos + 1);
|
||||||
|
param[len - pos - 2] = '\0';
|
||||||
|
|
||||||
|
|
||||||
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
for (i = strlen(param) - 1; i >= 0 && isspace(param[i]); i--)
|
||||||
;
|
;
|
||||||
@@ -201,6 +219,7 @@ int Process::getParam(const char* parameter, char* value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
@@ -277,8 +296,6 @@ void MultiTaskProcess::run(void)
|
|||||||
_threadList[i]->start();
|
_threadList[i]->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (theProcess->checkSignal() == SIGINT)
|
if (theProcess->checkSignal() == SIGINT)
|
||||||
@@ -288,15 +305,6 @@ void MultiTaskProcess::run(void)
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception* ex)
|
|
||||||
{
|
|
||||||
ex->writeMessage();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultiTaskProcess::waitStop(void)
|
void MultiTaskProcess::waitStop(void)
|
||||||
{
|
{
|
||||||
@@ -314,6 +322,11 @@ void MultiTaskProcess::threadStopped(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MultiTaskProcess::abort(void)
|
||||||
|
{
|
||||||
|
signalHandler(SIGINT);
|
||||||
|
}
|
||||||
|
|
||||||
void MultiTaskProcess::attach(Thread* thread)
|
void MultiTaskProcess::attach(Thread* thread)
|
||||||
{
|
{
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
@@ -325,7 +338,7 @@ void MultiTaskProcess::attach(Thread* thread)
|
|||||||
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();
|
||||||
}
|
}
|
||||||
@@ -335,40 +348,26 @@ 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)
|
|
||||||
{
|
|
||||||
throw Exception("No config file.");
|
|
||||||
}
|
|
||||||
return rc;
|
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;
|
|
||||||
_functionName = 0;
|
|
||||||
_line = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exception::Exception(const int exNo, const string& message)
|
|
||||||
{
|
|
||||||
_message = message;
|
|
||||||
_exNo = exNo;
|
|
||||||
_fileName = nullptr;
|
_fileName = nullptr;
|
||||||
_functionName = nullptr;
|
_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, const char* file,
|
|
||||||
const char* function, const int line)
|
|
||||||
{
|
{
|
||||||
_message = message;
|
_message = message;
|
||||||
_exNo = exNo;
|
_errNo = errNo;
|
||||||
_fileName = file;
|
_fileName = getFileName(file);
|
||||||
|
;
|
||||||
_functionName = function;
|
_functionName = function;
|
||||||
_line = line;
|
_line = line;
|
||||||
}
|
}
|
||||||
@@ -380,7 +379,7 @@ 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()
|
||||||
@@ -398,20 +397,49 @@ 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)
|
||||||
|
{
|
||||||
|
WRITELOG("%s%s %s%s\n", currentDateTime(), RED_HDR, _message, CLR_HDR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITELOG("%s:%-6d %s line %-4d %s() : %s\n", currentDateTime(), getExceptionNo(),
|
WRITELOG("%s%s %s.\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message, _errNo,
|
||||||
getFileName(), getLineNo(), getFunctionName(), what());
|
strerror(_errNo), CLR_HDR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_errNo == 0)
|
||||||
|
{
|
||||||
|
WRITELOG("%s%s %s. %s line %-4d %s()%s\n", currentDateTime(), RED_HDR, _message, _fileName, _line, _functionName,
|
||||||
|
CLR_HDR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WRITELOG("%s%s %s. %s line %-4d %s()\n errno=%d : %s%s\n", currentDateTime(), RED_HDR, _message,
|
||||||
|
_fileName, _line, _functionName, _errNo, strerror(_errNo), CLR_HDR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Exception::getFileName(const char* file)
|
||||||
|
{
|
||||||
|
for (int len = strlen(file); len > 0; len--)
|
||||||
|
{
|
||||||
|
if (*(file + len) == '/')
|
||||||
|
{
|
||||||
|
return file + len + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ namespace MQTTSNGW
|
|||||||
#define WRITELOG theProcess->putLog
|
#define WRITELOG theProcess->putLog
|
||||||
#define CHK_SIGINT (theProcess->checkSignal() == SIGINT)
|
#define CHK_SIGINT (theProcess->checkSignal() == SIGINT)
|
||||||
#define UNUSED(x) ((void)(x))
|
#define UNUSED(x) ((void)(x))
|
||||||
|
#define EXCEPTION(...) Exception(__VA_ARGS__, __FILE__, __func__, __LINE__)
|
||||||
|
|
||||||
/*=================================
|
/*=================================
|
||||||
Class Process
|
Class Process
|
||||||
==================================*/
|
==================================*/
|
||||||
@@ -86,6 +88,7 @@ public:
|
|||||||
void waitStop(void);
|
void waitStop(void);
|
||||||
void threadStopped(void);
|
void threadStopped(void);
|
||||||
void attach(Thread* thread);
|
void attach(Thread* thread);
|
||||||
|
void abort(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread* _threadList[MQTTSNGW_MAX_TASK];
|
Thread* _threadList[MQTTSNGW_MAX_TASK];
|
||||||
@@ -100,27 +103,25 @@ private:
|
|||||||
class Exception: public exception
|
class Exception: public exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Exception(const string& message);
|
Exception(const char* message, const int errNo);
|
||||||
Exception(const int exNo, const string& message);
|
Exception(const char* message, const int errNo, const char* file, const char* func, int line);
|
||||||
Exception(const int exNo, const string& message,
|
|
||||||
const char* file, const char* func, const int line);
|
|
||||||
virtual ~Exception() throw ();
|
virtual ~Exception() throw ();
|
||||||
const char* getFileName();
|
const char* getFileName();
|
||||||
const char* getFunctionName();
|
const char* getFunctionName();
|
||||||
const int getLineNo();
|
const int getLineNo();
|
||||||
const int getExceptionNo();
|
const int getErrNo();
|
||||||
virtual const char* what() const throw ();
|
virtual const char* what() const throw ();
|
||||||
void writeMessage();
|
void writeMessage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _exNo;
|
const char* getFileName(const char* file);
|
||||||
string _message;
|
int _errNo;
|
||||||
|
const char* _message;
|
||||||
const char* _fileName;
|
const char* _fileName;
|
||||||
const char* _functionName;
|
const char* _functionName;
|
||||||
int _line;
|
int _line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class QueElement
|
Class QueElement
|
||||||
====================================*/
|
====================================*/
|
||||||
@@ -263,7 +264,8 @@ private:
|
|||||||
#define TREE23_TRI_NODE (3)
|
#define TREE23_TRI_NODE (3)
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class Tree23Elm{
|
class Tree23Elm
|
||||||
|
{
|
||||||
template<typename T, typename U> friend class Tree23;
|
template<typename T, typename U> friend class Tree23;
|
||||||
public:
|
public:
|
||||||
Tree23Elm()
|
Tree23Elm()
|
||||||
@@ -292,9 +294,9 @@ private:
|
|||||||
V* _val;
|
V* _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class Tree23Node{
|
class Tree23Node
|
||||||
|
{
|
||||||
template<typename S, typename W> friend class Tree23;
|
template<typename S, typename W> friend class Tree23;
|
||||||
public:
|
public:
|
||||||
Tree23Node(const int type)
|
Tree23Node(const int type)
|
||||||
@@ -320,7 +322,8 @@ public:
|
|||||||
_left = _midle = _right = NULL;
|
_left = _midle = _right = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left, Tree23Node<K, V>* right)
|
Tree23Node(const int type, Tree23Elm<K, V>* telm, Tree23Node<K, V>* left,
|
||||||
|
Tree23Node<K, V>* right)
|
||||||
{
|
{
|
||||||
_type = type;
|
_type = type;
|
||||||
_telm0 = telm;
|
_telm0 = telm;
|
||||||
@@ -330,7 +333,9 @@ public:
|
|||||||
_right = right;
|
_right = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1, Tree23Node<K, V>* left, Tree23Node<K, V>* midle, Tree23Node<K, V>* right)
|
Tree23Node(const int type, Tree23Elm<K, V>* telm0, Tree23Elm<K, V>* telm1,
|
||||||
|
Tree23Node<K, V>* left, Tree23Node<K, V>* midle,
|
||||||
|
Tree23Node<K, V>* right)
|
||||||
{
|
{
|
||||||
_type = type;
|
_type = type;
|
||||||
_telm0 = telm0;
|
_telm0 = telm0;
|
||||||
@@ -355,7 +360,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class Tree23{
|
class Tree23
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Tree23()
|
Tree23()
|
||||||
{
|
{
|
||||||
@@ -534,7 +540,8 @@ public:
|
|||||||
switch (node->_type)
|
switch (node->_type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
if ( cmp0 < 0 ) node = node->_left;
|
if (cmp0 < 0)
|
||||||
|
node = node->_left;
|
||||||
else if (cmp0 == 0)
|
else if (cmp0 == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -574,7 +581,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
V* getVal(K* key)
|
V* getVal(K* key)
|
||||||
{
|
{
|
||||||
Tree23Node<K, V>* node = _root;
|
Tree23Node<K, V>* node = _root;
|
||||||
@@ -634,7 +640,8 @@ private:
|
|||||||
Tree23Node<K, V>* n = node->_left;
|
Tree23Node<K, V>* n = node->_left;
|
||||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||||
{
|
{
|
||||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, n->_telm0, node->_telm0, n->_left, n->_right, node->_right);
|
return new Tree23Node<K, V>(TREE23_TRI_NODE, n->_telm0,
|
||||||
|
node->_telm0, n->_left, n->_right, node->_right);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -645,8 +652,10 @@ private:
|
|||||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||||
{
|
{
|
||||||
n->_type = TREE23_BI_NODE;
|
n->_type = TREE23_BI_NODE;
|
||||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, node->_midle, node->_right);
|
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n, nn);
|
node->_telm1, node->_midle, node->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm0, n,
|
||||||
|
nn);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -656,7 +665,8 @@ private:
|
|||||||
Tree23Node<K, V>* n = node->_right;
|
Tree23Node<K, V>* n = node->_right;
|
||||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||||
{
|
{
|
||||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, n->_telm0, node->_left, n->_left, n->_right);
|
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||||
|
n->_telm0, node->_left, n->_left, n->_right);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -664,10 +674,13 @@ private:
|
|||||||
Tree23Node<K, V>* addRight3(Tree23Node<K, V>* node)
|
Tree23Node<K, V>* addRight3(Tree23Node<K, V>* node)
|
||||||
{
|
{
|
||||||
Tree23Node<K, V>* n = node->_right;
|
Tree23Node<K, V>* n = node->_right;
|
||||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE) {
|
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||||
|
{
|
||||||
n->_type = TREE23_BI_NODE;
|
n->_type = TREE23_BI_NODE;
|
||||||
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, node->_midle);
|
Tree23Node<K, V>* nn = new Tree23Node<K, V>(TREE23_BI_NODE,
|
||||||
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn, n);
|
node->_telm0, node->_left, node->_midle);
|
||||||
|
return new Tree23Node<K, V>(TREE23_INSERT_ACTIVE, node->_telm1, nn,
|
||||||
|
n);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -677,14 +690,15 @@ private:
|
|||||||
Tree23Node<K, V>* n = node->_midle;
|
Tree23Node<K, V>* n = node->_midle;
|
||||||
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
if (n != NULL && n->_type == TREE23_INSERT_ACTIVE)
|
||||||
{
|
{
|
||||||
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, node->_left, n->_left);
|
n->_left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||||
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_right, node->_right);
|
node->_left, n->_left);
|
||||||
|
n->_right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||||
|
n->_right, node->_right);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Tree23Node<K, V>* removeMax(Tree23Node<K, V>* node, Tree23Elm<K, V>* elm)
|
Tree23Node<K, V>* removeMax(Tree23Node<K, V>* node, Tree23Elm<K, V>* elm)
|
||||||
{
|
{
|
||||||
if (node->_right == NULL)
|
if (node->_right == NULL)
|
||||||
@@ -719,7 +733,6 @@ private:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Tree23Node<K, V>* removeLeft2(Tree23Node<K, V>* node)
|
Tree23Node<K, V>* removeLeft2(Tree23Node<K, V>* node)
|
||||||
{
|
{
|
||||||
Tree23Node<K, V>* n = node->_left;
|
Tree23Node<K, V>* n = node->_left;
|
||||||
@@ -733,12 +746,16 @@ private:
|
|||||||
switch (r->_type)
|
switch (r->_type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, n->_midle, r->_left, r->_right);
|
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||||
|
r->_telm0, n->_midle, r->_left, r->_right);
|
||||||
return new Tree23Node<K, V>(TREE23_DELETE_ACTIVE, midle);
|
return new Tree23Node<K, V>(TREE23_DELETE_ACTIVE, midle);
|
||||||
case 3:
|
case 3:
|
||||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, r->_left);
|
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
n->_midle, r->_left);
|
||||||
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left, right);
|
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||||
|
r->_midle, r->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm0, left,
|
||||||
|
right);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -759,12 +776,16 @@ private:
|
|||||||
switch (l->_type)
|
switch (l->_type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0, node->_telm0, l->_left, l->_right, n->_midle);
|
midle = new Tree23Node<K, V>(TREE23_TRI_NODE, l->_telm0,
|
||||||
|
node->_telm0, l->_left, l->_right, n->_midle);
|
||||||
return new Tree23Node<K, V>(-1, midle);
|
return new Tree23Node<K, V>(-1, midle);
|
||||||
case 3:
|
case 3:
|
||||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l->_right, n->_midle);
|
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left, l->_midle);
|
l->_right, n->_midle);
|
||||||
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left, right);
|
left = new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm0, l->_left,
|
||||||
|
l->_midle);
|
||||||
|
return new Tree23Node<K, V>(TREE23_BI_NODE, l->_telm1, left,
|
||||||
|
right);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -782,14 +803,20 @@ private:
|
|||||||
Tree23Node<K, V>* left;
|
Tree23Node<K, V>* left;
|
||||||
Tree23Node<K, V>* midle;
|
Tree23Node<K, V>* midle;
|
||||||
|
|
||||||
switch (m->_type) {
|
switch (m->_type)
|
||||||
|
{
|
||||||
case 2:
|
case 2:
|
||||||
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm0, n->_midle, m->_left, m->_right);
|
left = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left, r);
|
m->_telm0, n->_midle, m->_left, m->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, left,
|
||||||
|
r);
|
||||||
case 3:
|
case 3:
|
||||||
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, n->_midle, m->_left);
|
left = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0,
|
||||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1, m->_midle, m->_right);
|
n->_midle, m->_left);
|
||||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, left, midle, r);
|
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm1,
|
||||||
|
m->_midle, m->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||||
|
node->_telm1, left, midle, r);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -809,12 +836,17 @@ private:
|
|||||||
switch (r->_type)
|
switch (r->_type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1, r->_telm0, n->_midle, r->_left, r->_right);
|
right = new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm1,
|
||||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
r->_telm0, n->_midle, r->_left, r->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||||
|
right);
|
||||||
case 3:
|
case 3:
|
||||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, n->_midle, r->_left);
|
midle = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1, r->_midle, r->_right);
|
n->_midle, r->_left);
|
||||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, r->_telm0, l, midle, right);
|
right = new Tree23Node<K, V>(TREE23_BI_NODE, r->_telm1,
|
||||||
|
r->_midle, r->_right);
|
||||||
|
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||||
|
r->_telm0, l, midle, right);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -834,12 +866,17 @@ private:
|
|||||||
switch (m->_type)
|
switch (m->_type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0, node->_telm1, m->_left, m->_right, n->_midle);
|
right = new Tree23Node<K, V>(TREE23_TRI_NODE, m->_telm0,
|
||||||
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l, right);
|
node->_telm1, m->_left, m->_right, n->_midle);
|
||||||
|
return new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm0, l,
|
||||||
|
right);
|
||||||
case 3:
|
case 3:
|
||||||
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1, m->_right, n->_midle);
|
right = new Tree23Node<K, V>(TREE23_BI_NODE, node->_telm1,
|
||||||
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0, m->_left, m->_midle);
|
m->_right, n->_midle);
|
||||||
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0, m->_telm1, l, midle, right);
|
midle = new Tree23Node<K, V>(TREE23_BI_NODE, m->_telm0,
|
||||||
|
m->_left, m->_midle);
|
||||||
|
return new Tree23Node<K, V>(TREE23_TRI_NODE, node->_telm0,
|
||||||
|
m->_telm1, l, midle, right);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -847,7 +884,6 @@ private:
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Tree23Node<K, V>* _root;
|
Tree23Node<K, V>* _root;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -873,18 +909,23 @@ public:
|
|||||||
{
|
{
|
||||||
return _elm;
|
return _elm;
|
||||||
}
|
}
|
||||||
~ListElm(){}
|
~ListElm()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListElm<T>* getNext(void){return _next;}
|
ListElm<T>* getNext(void)
|
||||||
|
{
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
T* _elm;
|
T* _elm;
|
||||||
ListElm<T>* _prev;
|
ListElm<T>* _prev;
|
||||||
ListElm<T>* _next;
|
ListElm<T>* _next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class List{
|
class List
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
List()
|
List()
|
||||||
{
|
{
|
||||||
@@ -970,14 +1011,12 @@ public:
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListElm<T>* _head;
|
ListElm<T>* _head;
|
||||||
ListElm<T>* _tail;
|
ListElm<T>* _tail;
|
||||||
int _size;
|
int _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern Process* theProcess;
|
extern Process* theProcess;
|
||||||
extern MultiTaskProcess* theMultiTaskProcess;
|
extern MultiTaskProcess* theMultiTaskProcess;
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
|||||||
int qos;
|
int qos;
|
||||||
uint8_t retained;
|
uint8_t retained;
|
||||||
uint16_t msgId;
|
uint16_t msgId;
|
||||||
|
uint16_t tid;
|
||||||
uint8_t* payload;
|
uint8_t* payload;
|
||||||
MQTTSN_topicid topicid;
|
MQTTSN_topicid topicid;
|
||||||
int payloadlen;
|
int payloadlen;
|
||||||
@@ -66,6 +67,7 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
|||||||
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;
|
||||||
|
|
||||||
@@ -114,12 +116,14 @@ MQTTGWPacket* MQTTSNPublishHandler::handlePublish(Client* client, MQTTSNPacket*
|
|||||||
{
|
{
|
||||||
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 */
|
/* Save a msgId & a TopicId pare for PUBACK */
|
||||||
if (msgId && qos > 0 && qos < 3)
|
if (msgId && qos > 0 && qos < 3)
|
||||||
{
|
{
|
||||||
client->setWaitedPubTopicId(msgId, topicid.data.id, topicid.type);
|
client->setWaitedPubTopicId(msgId, tid, &topicid);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub.payload = (char*) payload;
|
pub.payload = (char*) payload;
|
||||||
@@ -194,7 +198,8 @@ void MQTTSNPublishHandler::handleRegister(Client* client, MQTTSNPacket* packet)
|
|||||||
{
|
{
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
uint16_t msgId;
|
uint16_t msgId;
|
||||||
MQTTSNString topicName = MQTTSNString_initializer;;
|
MQTTSNString topicName = MQTTSNString_initializer;
|
||||||
|
;
|
||||||
MQTTSN_topicid topicid;
|
MQTTSN_topicid topicid;
|
||||||
|
|
||||||
if (client->isActive() || client->isAwake())
|
if (client->isActive() || client->isAwake())
|
||||||
@@ -230,6 +235,7 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get PUBLISH message */
|
||||||
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
|
MQTTSNPacket* regAck = client->getWaitREGACKPacketList()->getPacket(msgId);
|
||||||
|
|
||||||
if (regAck != nullptr)
|
if (regAck != nullptr)
|
||||||
@@ -239,6 +245,7 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
|||||||
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 */
|
||||||
@@ -253,9 +260,6 @@ void MQTTSNPublishHandler::handleRegAck( Client* client, MQTTSNPacket* packet)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
|
void MQTTSNPublishHandler::handleAggregatePublish(Client* client, MQTTSNPacket* packet)
|
||||||
{
|
{
|
||||||
int msgId = 0;
|
int msgId = 0;
|
||||||
|
|||||||
@@ -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,7 +37,6 @@ QoSm1Proxy::~QoSm1Proxy(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QoSm1Proxy::initialize(char* gwName)
|
void QoSm1Proxy::initialize(char* gwName)
|
||||||
{
|
{
|
||||||
if (_gateway->hasSecureConnection())
|
if (_gateway->hasSecureConnection())
|
||||||
@@ -54,7 +53,6 @@ void QoSm1Proxy::initialize(char* gwName)
|
|||||||
_isActive = true;
|
_isActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QoSm1Proxy::isActive(void)
|
bool QoSm1Proxy::isActive(void)
|
||||||
{
|
{
|
||||||
return _isActive;
|
return _isActive;
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ private:
|
|||||||
bool _isSecure { false };
|
bool _isSecure { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */
|
#endif /* MQTTSNGATEWAY_SRC_MQTTSNGWQOSM1PROXY_H_ */
|
||||||
|
|||||||
@@ -62,10 +62,17 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
|||||||
|
|
||||||
if (!topic)
|
if (!topic)
|
||||||
{
|
{
|
||||||
|
/* Search the topic in Client common topic table */
|
||||||
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
topic = _gateway->getTopics()->getTopicById(&topicFilter);
|
||||||
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 == nullptr)
|
||||||
|
{
|
||||||
|
WRITELOG("%s Client(%s) can't add the Topic.%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||||
|
goto RespExit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -85,8 +92,9 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
|||||||
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();
|
||||||
@@ -106,7 +114,7 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
|||||||
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())
|
||||||
{
|
{
|
||||||
@@ -120,10 +128,8 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleSubscribe(Client* client, MQTTSNPack
|
|||||||
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();
|
|
||||||
sSuback->setSUBACK(qos, topicFilter.data.id, msgId, MQTTSN_RC_NOT_SUPPORTED);
|
|
||||||
evsuback = new Event();
|
evsuback = new Event();
|
||||||
evsuback->setClientSendEvent(client, sSuback);
|
evsuback->setClientSendEvent(client, sSuback);
|
||||||
_gateway->getClientSendQue()->post(evsuback);
|
_gateway->getClientSendQue()->post(evsuback);
|
||||||
@@ -146,7 +152,6 @@ MQTTGWPacket* MQTTSNSubscribeHandler::handleUnsubscribe(Client* client, MQTTSNPa
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
if (topicFilter.type == MQTTSN_TOPIC_TYPE_SHORT)
|
||||||
{
|
{
|
||||||
char shortTopic[3];
|
char shortTopic[3];
|
||||||
@@ -216,7 +221,8 @@ void MQTTSNSubscribeHandler::handleAggregateSubscribe(Client* client, MQTTSNPack
|
|||||||
|
|
||||||
if (msgId == 0)
|
if (msgId == 0)
|
||||||
{
|
{
|
||||||
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
WRITELOG("%s MQTTSNSubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +256,8 @@ void MQTTSNSubscribeHandler::handleAggregateUnsubscribe(Client* client, MQTTSNPa
|
|||||||
|
|
||||||
if (msgId == 0)
|
if (msgId == 0)
|
||||||
{
|
{
|
||||||
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n", ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
WRITELOG("%s MQTTSNUnsubscribeHandler can't create MessageIdTableElement %s%s\n",
|
||||||
|
ERRMSG_HEADER, client->getClientId(), ERRMSG_FOOTER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,5 +42,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */
|
#endif /* MQTTSNGWSUBSCRIBEHANDLER_H_ */
|
||||||
|
|||||||
@@ -252,7 +252,6 @@ Topic* Topics::add(const char* topicName, uint16_t id)
|
|||||||
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)
|
||||||
@@ -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;
|
||||||
@@ -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()
|
||||||
@@ -418,9 +425,16 @@ MQTTSN_topicTypes TopicIdMapElement::getTopicType(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t TopicIdMapElement::getTopicId(void)
|
uint16_t TopicIdMapElement::getTopicId(void)
|
||||||
|
{
|
||||||
|
if (_wildcard > 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return _topicId;
|
return _topicId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TopicIdMap::TopicIdMap()
|
TopicIdMap::TopicIdMap()
|
||||||
{
|
{
|
||||||
@@ -456,9 +470,9 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -467,7 +481,7 @@ TopicIdMapElement* TopicIdMap::add(uint16_t msgId, uint16_t topicId, MQTTSN_topi
|
|||||||
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;
|
||||||
@@ -534,5 +548,3 @@ void TopicIdMap::clear(void)
|
|||||||
_cnt = 0;
|
_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
namespace MQTTSNGW
|
namespace MQTTSNGW
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Topic
|
Class Topic
|
||||||
======================================*/
|
======================================*/
|
||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -95,11 +95,22 @@ Gateway::~Gateway()
|
|||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -109,12 +120,10 @@ Gateway::~Gateway()
|
|||||||
{
|
{
|
||||||
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)
|
||||||
@@ -174,6 +183,14 @@ void Gateway::initialize(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
_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)
|
||||||
{
|
{
|
||||||
@@ -182,7 +199,7 @@ void Gateway::initialize(int argc, char** argv)
|
|||||||
|
|
||||||
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)
|
||||||
@@ -192,7 +209,7 @@ void Gateway::initialize(int argc, char** argv)
|
|||||||
|
|
||||||
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;
|
||||||
@@ -201,7 +218,7 @@ void Gateway::initialize(int argc, char** argv)
|
|||||||
_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);
|
||||||
@@ -272,12 +289,28 @@ void Gateway::initialize(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_params.maxClients = MAX_CLIENTS;
|
||||||
|
if (getParam("MaxNumberOfClients", param) == 0)
|
||||||
|
{
|
||||||
|
_params.maxClients = atoi(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getParam("RFCOMMAddress", param) == 0)
|
||||||
|
{
|
||||||
|
_params.rfcommAddr = strdup(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup max PacketEventQue size */
|
||||||
|
_packetEventQue.setMaxSize(_params.maxInflightMsgs * _params.maxClients);
|
||||||
|
|
||||||
/* Initialize adapters */
|
/* Initialize adapters */
|
||||||
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
_adapterManager->initialize(_params.gatewayName, _params.aggregatingGw, _params.forwarder, _params.qosMinus1);
|
||||||
|
|
||||||
/* Setup ClientList and Predefined topics */
|
/* Setup ClientList and Predefined topics */
|
||||||
_clientList->initialize(_params.aggregatingGw);
|
_clientList->initialize(_params.aggregatingGw);
|
||||||
|
|
||||||
|
/* SensorNetwork initialize */
|
||||||
|
_sensorNetwork.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gateway::run(void)
|
void Gateway::run(void)
|
||||||
@@ -291,7 +324,6 @@ void Gateway::run(void)
|
|||||||
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)
|
||||||
@@ -304,18 +336,24 @@ void Gateway::run(void)
|
|||||||
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
WRITELOG(" PreDefFile : %s\n", _params.predefinedTopicFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITELOG(" SensorN/W: %s\n", _sensorNetwork.getDescription());
|
|
||||||
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
WRITELOG(" Broker : %s : %s, %s\n", _params.brokerName, _params.port, _params.portSecure);
|
||||||
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
WRITELOG(" RootCApath : %s\n", _params.rootCApath);
|
||||||
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
WRITELOG(" RootCAfile : %s\n", _params.rootCAfile);
|
||||||
WRITELOG(" CertKey : %s\n", _params.certKey);
|
WRITELOG(" CertKey : %s\n", _params.certKey);
|
||||||
WRITELOG(" PrivateKey: %s\n\n\n", _params.privateKey);
|
WRITELOG(" PrivateKey : %s\n", _params.privateKey);
|
||||||
|
WRITELOG(" SensorN/W : %s\n", _sensorNetwork.getDescription());
|
||||||
|
#ifdef DTLS
|
||||||
|
WRITELOG(" DtlsCertsKey: %s\n", _params.gwCertskey);
|
||||||
|
WRITELOG(" DtlsPrivKey : %s\n", _params.gwPrivatekey);
|
||||||
|
#endif
|
||||||
|
WRITELOG(" Max Clients : %d\n\n", _params.maxClients);
|
||||||
|
WRITELOG("%s %s starts running.\n\n", currentDateTime(), _params.gatewayName);
|
||||||
|
|
||||||
_stopFlg = false;
|
_stopFlg = false;
|
||||||
|
|
||||||
/* Run Tasks until CTRL+C entred */
|
/* Run Tasks until CTRL+C entered or Exception occurred */
|
||||||
MultiTaskProcess::run();
|
MultiTaskProcess::run();
|
||||||
|
WRITELOG("\n");
|
||||||
_stopFlg = true;
|
_stopFlg = true;
|
||||||
|
|
||||||
/* stop Tasks */
|
/* stop Tasks */
|
||||||
@@ -332,7 +370,7 @@ void Gateway::run(void)
|
|||||||
/* 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,17 +426,14 @@ 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()
|
||||||
@@ -483,7 +518,6 @@ int EventQue::size()
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Event
|
Class Event
|
||||||
=====================================*/
|
=====================================*/
|
||||||
@@ -586,4 +620,3 @@ MQTTGWPacket* Event::getMQTTGWPacket(void)
|
|||||||
return _mqttGWPacket;
|
return _mqttGWPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "MQTTSNGWProcess.h"
|
#include "MQTTSNGWProcess.h"
|
||||||
#include "MQTTSNPacket.h"
|
#include "MQTTSNPacket.h"
|
||||||
#include "MQTTSNGWClient.h"
|
#include "MQTTSNGWClient.h"
|
||||||
|
#include "MQTTSNGWProcess.h"
|
||||||
|
|
||||||
namespace MQTTSNGW
|
namespace MQTTSNGW
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ namespace MQTTSNGW
|
|||||||
==================================*/
|
==================================*/
|
||||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway"
|
#define PAHO_COPYRIGHT0 " * MQTT-SN Gateway"
|
||||||
#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 " ***************************************************************************"
|
||||||
/*==========================================================
|
/*==========================================================
|
||||||
@@ -76,7 +77,8 @@ namespace MQTTSNGW
|
|||||||
====================================*/
|
====================================*/
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
enum EventType{
|
enum EventType
|
||||||
|
{
|
||||||
Et_NA = 0,
|
Et_NA = 0,
|
||||||
EtStop,
|
EtStop,
|
||||||
EtTimeout,
|
EtTimeout,
|
||||||
@@ -88,8 +90,8 @@ enum EventType{
|
|||||||
EtSensornetSend
|
EtSensornetSend
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Event
|
||||||
class Event{
|
{
|
||||||
public:
|
public:
|
||||||
Event();
|
Event();
|
||||||
~Event();
|
~Event();
|
||||||
@@ -115,7 +117,6 @@ private:
|
|||||||
MQTTGWPacket* _mqttGWPacket { nullptr };
|
MQTTGWPacket* _mqttGWPacket { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class EventQue
|
Class EventQue
|
||||||
====================================*/
|
====================================*/
|
||||||
@@ -136,8 +137,6 @@ private:
|
|||||||
Semaphore _sem;
|
Semaphore _sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class GatewayParams
|
Class GatewayParams
|
||||||
====================================*/
|
====================================*/
|
||||||
@@ -168,17 +167,21 @@ public:
|
|||||||
bool aggregatingGw { false };
|
bool aggregatingGw { false };
|
||||||
bool qosMinus1 { false };
|
bool qosMinus1 { false };
|
||||||
bool forwarder { false };
|
bool forwarder { false };
|
||||||
|
int maxClients {0};
|
||||||
|
char* rfcommAddr { nullptr };
|
||||||
|
char* gwCertskey { nullptr };
|
||||||
|
char* gwPrivatekey { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Gateway
|
Class Gateway
|
||||||
=====================================*/
|
=====================================*/
|
||||||
class AdapterManager;
|
class AdapterManager;
|
||||||
class ClientList;
|
class ClientList;
|
||||||
|
class ClientsPool;
|
||||||
|
|
||||||
class Gateway: public MultiTaskProcess{
|
class Gateway: public MultiTaskProcess
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Gateway(void);
|
Gateway(void);
|
||||||
~Gateway();
|
~Gateway();
|
||||||
@@ -196,24 +199,23 @@ public:
|
|||||||
int getParam(const char* parameter, char* value);
|
int getParam(const char* parameter, char* value);
|
||||||
char* getClientListFileName(void);
|
char* getClientListFileName(void);
|
||||||
char* getPredefinedTopicFileName(void);
|
char* getPredefinedTopicFileName(void);
|
||||||
|
|
||||||
bool hasSecureConnection(void);
|
bool hasSecureConnection(void);
|
||||||
Topics* getTopics(void);
|
Topics* getTopics(void);
|
||||||
bool IsStopping(void);
|
bool IsStopping(void);
|
||||||
|
void requestSensorNetSubTask(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GatewayParams _params;
|
GatewayParams _params;
|
||||||
ClientList* _clientList {nullptr};
|
ClientList* _clientList;
|
||||||
EventQue _packetEventQue;
|
EventQue _packetEventQue;
|
||||||
EventQue _brokerSendQue;
|
EventQue _brokerSendQue;
|
||||||
EventQue _clientSendQue;
|
EventQue _clientSendQue;
|
||||||
LightIndicator _lightIndicator;
|
LightIndicator _lightIndicator;
|
||||||
SensorNetwork _sensorNetwork;
|
SensorNetwork _sensorNetwork;
|
||||||
AdapterManager* _adapterManager {nullptr};
|
AdapterManager* _adapterManager;
|
||||||
Topics* _topics;
|
Topics* _topics;
|
||||||
bool _stopFlg;
|
bool _stopFlg;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MQTTSNGATEWAY_H_ */
|
#endif /* MQTTSNGATEWAY_H_ */
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
|||||||
char errmsg[256];
|
char errmsg[256];
|
||||||
char peer_CN[256];
|
char peer_CN[256];
|
||||||
bool rc;
|
bool rc;
|
||||||
|
X509* peer = nullptr;
|
||||||
|
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
try
|
try
|
||||||
@@ -385,7 +386,7 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
|||||||
throw false;
|
throw false;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509* peer = SSL_get_peer_certificate(_ssl);
|
peer = SSL_get_peer_certificate(_ssl);
|
||||||
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);
|
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);
|
||||||
char* pos = peer_CN;
|
char* pos = peer_CN;
|
||||||
if ( *pos == '*')
|
if ( *pos == '*')
|
||||||
@@ -413,7 +414,12 @@ bool Network::connect(const char* host, const char* port, const char* caPath, co
|
|||||||
{
|
{
|
||||||
rc = x;
|
rc = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
|
if (peer != nullptr)
|
||||||
|
{
|
||||||
|
X509_free(peer);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,3 +656,7 @@ bool Network::isSecure()
|
|||||||
return _secureFlg;
|
return _secureFlg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Network::setSecure(bool secureFlg)
|
||||||
|
{
|
||||||
|
_secureFlg = secureFlg;
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public:
|
|||||||
bool isValid(void);
|
bool isValid(void);
|
||||||
bool isSecure(void);
|
bool isSecure(void);
|
||||||
int getSock(void);
|
int getSock(void);
|
||||||
|
void setSecure(bool secureFlg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static SSL_CTX* _ctx;
|
static SSL_CTX* _ctx;
|
||||||
|
|||||||
@@ -79,23 +79,23 @@ Mutex::Mutex(const char* fileName)
|
|||||||
|
|
||||||
if ((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0)
|
if ((_shmid = shmget(key, sizeof(pthread_mutex_t), IPC_CREAT | 0666)) < 0)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Mutex can't create a shared memory.");
|
throw Exception("Mutex can't create a shared memory.", -1);
|
||||||
}
|
}
|
||||||
_pmutex = (pthread_mutex_t*) shmat(_shmid, NULL, 0);
|
_pmutex = (pthread_mutex_t*) shmat(_shmid, NULL, 0);
|
||||||
if (_pmutex == (void*) -1)
|
if (_pmutex == (void*) -1)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Mutex can't attach shared memory.");
|
throw Exception("Mutex can't attach shared memory.", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
|
|
||||||
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0)
|
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Mutex can't set the process-shared flag");
|
throw Exception("Mutex can't set the process-shared flag", -1);
|
||||||
}
|
}
|
||||||
if (pthread_mutex_init(_pmutex, &attr) != 0)
|
if (pthread_mutex_init(_pmutex, &attr) != 0)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Mutex can't initialize.");
|
throw Exception("Mutex can't initialize.", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,44 +121,37 @@ Mutex::~Mutex(void)
|
|||||||
|
|
||||||
void Mutex::lock(void)
|
void Mutex::lock(void)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
if (_pmutex)
|
if (_pmutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(_pmutex);
|
rc = pthread_mutex_lock(_pmutex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
rc = pthread_mutex_lock(&_mutex);
|
||||||
{
|
|
||||||
if (pthread_mutex_lock(&_mutex))
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
} catch (char* errmsg)
|
|
||||||
|
if (rc)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "The same thread can't aquire a mutex twice.");
|
throw Exception("Mutex lock error", errno);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::unlock(void)
|
void Mutex::unlock(void)
|
||||||
{
|
{
|
||||||
|
int rc = 0;
|
||||||
if (_pmutex)
|
if (_pmutex)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(_pmutex);
|
rc = pthread_mutex_unlock(_pmutex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
rc = pthread_mutex_unlock(&_mutex);
|
||||||
{
|
|
||||||
if (pthread_mutex_unlock(&_mutex))
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
} catch (char* errmsg)
|
|
||||||
|
if (rc)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Mutex can't unlock.");
|
throw Exception("Mutex lock error", errno);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,12 +218,12 @@ NamedSemaphore::NamedSemaphore(const char* name, unsigned int val)
|
|||||||
_psem = sem_open(name, O_CREAT, 0666, val);
|
_psem = sem_open(name, O_CREAT, 0666, val);
|
||||||
if (_psem == SEM_FAILED)
|
if (_psem == SEM_FAILED)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Semaphore can't be created.");
|
throw Exception("Semaphore can't be created.", -1);
|
||||||
}
|
}
|
||||||
_name = strdup(name);
|
_name = strdup(name);
|
||||||
if (_name == NULL)
|
if (_name == NULL)
|
||||||
{
|
{
|
||||||
throw Exception( -1, "Semaphore can't allocate memories.");
|
throw Exception("Semaphore can't allocate memories.", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,11 +256,6 @@ void NamedSemaphore::timedwait(uint16_t millsec)
|
|||||||
/*=========================================
|
/*=========================================
|
||||||
Class RingBuffer
|
Class RingBuffer
|
||||||
=========================================*/
|
=========================================*/
|
||||||
RingBuffer::RingBuffer()
|
|
||||||
{
|
|
||||||
RingBuffer(MQTTSNGW_KEY_DIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
RingBuffer::RingBuffer(const char* keyDirectory)
|
RingBuffer::RingBuffer(const char* keyDirectory)
|
||||||
{
|
{
|
||||||
int fp = 0;
|
int fp = 0;
|
||||||
@@ -303,7 +291,7 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(-1, "RingBuffer can't attach shared memory.");
|
throw Exception("RingBuffer can't attach shared memory.", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((_shmid = shmget(key, PROCESS_LOG_BUFFER_SIZE, IPC_CREAT | 0666)) != -1)
|
else if ((_shmid = shmget(key, PROCESS_LOG_BUFFER_SIZE, IPC_CREAT | 0666)) != -1)
|
||||||
@@ -318,12 +306,12 @@ RingBuffer::RingBuffer(const char* keyDirectory)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
throw Exception("RingBuffer can't create a shared memory.", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(-1, "RingBuffer can't create a shared memory.");
|
throw Exception( "RingBuffer can't create a shared memory.", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pmx = new Mutex(MQTTSNGW_RB_MUTEX_KEY);
|
_pmx = new Mutex(MQTTSNGW_RB_MUTEX_KEY);
|
||||||
@@ -495,7 +483,7 @@ void RingBuffer::reset()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(-1, "RingBuffer can't reset. need to clear shared memory.");
|
throw Exception("RingBuffer can't reset. need to clear shared memory.", -1);
|
||||||
}
|
}
|
||||||
_pmx->unlock();
|
_pmx->unlock();
|
||||||
}
|
}
|
||||||
@@ -506,6 +494,7 @@ void RingBuffer::reset()
|
|||||||
Thread::Thread()
|
Thread::Thread()
|
||||||
{
|
{
|
||||||
_threadID = 0;
|
_threadID = 0;
|
||||||
|
_taskName = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::~Thread()
|
Thread::~Thread()
|
||||||
@@ -539,11 +528,6 @@ int Thread::start(void)
|
|||||||
return pthread_create(&_threadID, 0, _run, runnable);
|
return pthread_create(&_threadID, 0, _run, runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::stopProcess(void)
|
|
||||||
{
|
|
||||||
theMultiTaskProcess->threadStopped();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::stop(void)
|
void Thread::stop(void)
|
||||||
{
|
{
|
||||||
if ( _threadID )
|
if ( _threadID )
|
||||||
@@ -552,3 +536,13 @@ void Thread::stop(void)
|
|||||||
_threadID = 0;
|
_threadID = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thread::setTaskName(const char* name)
|
||||||
|
{
|
||||||
|
_taskName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Thread::getTaskName(void)
|
||||||
|
{
|
||||||
|
return _taskName;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ namespace MQTTSNGW
|
|||||||
#define MQTTSNGW_RB_MUTEX_KEY "rbmutex.key"
|
#define MQTTSNGW_RB_MUTEX_KEY "rbmutex.key"
|
||||||
#define MQTTSNGW_RB_SEMAPHOR_NAME "/rbsemaphor"
|
#define MQTTSNGW_RB_SEMAPHOR_NAME "/rbsemaphor"
|
||||||
|
|
||||||
|
#define RED_HDR "\033[0m\033[0;31m"
|
||||||
|
#define CLR_HDR "\033[0m\033[0;37m"
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
Class Mutex
|
Class Mutex
|
||||||
====================================*/
|
====================================*/
|
||||||
@@ -92,8 +95,7 @@ private:
|
|||||||
class RingBuffer
|
class RingBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RingBuffer();
|
RingBuffer(const char* keyDirectory = MQTTSNGW_KEY_DIRECTORY);
|
||||||
RingBuffer(const char* keyDirctory);
|
|
||||||
~RingBuffer();
|
~RingBuffer();
|
||||||
void put(char* buffer);
|
void put(char* buffer);
|
||||||
int get(char* buffer, int bufferLength);
|
int get(char* buffer, int bufferLength);
|
||||||
@@ -127,12 +129,14 @@ public: void EXECRUN() \
|
|||||||
try \
|
try \
|
||||||
{ \
|
{ \
|
||||||
run(); \
|
run(); \
|
||||||
stopProcess(); \
|
|
||||||
} \
|
} \
|
||||||
catch(...) \
|
catch ( Exception &ex ) \
|
||||||
{ \
|
{ \
|
||||||
throw; \
|
ex.writeMessage(); \
|
||||||
|
WRITELOG("%s%s caught an exception and stopped.%s\n", RED_HDR, getTaskName(), CLR_HDR); \
|
||||||
|
theMultiTaskProcess->abort(); \
|
||||||
} \
|
} \
|
||||||
|
theMultiTaskProcess->threadStopped(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=====================================
|
/*=====================================
|
||||||
@@ -146,12 +150,15 @@ public:
|
|||||||
static pthread_t getID();
|
static pthread_t getID();
|
||||||
static bool equals(pthread_t*, pthread_t*);
|
static bool equals(pthread_t*, pthread_t*);
|
||||||
virtual void initialize(int argc, char** argv);
|
virtual void initialize(int argc, char** argv);
|
||||||
void stopProcess(void);
|
|
||||||
void waitStop(void);
|
void waitStop(void);
|
||||||
void stop(void);
|
void stop(void);
|
||||||
|
const char* getTaskName(void);
|
||||||
|
void setTaskName(const char* name);
|
||||||
|
void abort(int threadNo);
|
||||||
private:
|
private:
|
||||||
static void* _run(void*);
|
static void* _run(void*);
|
||||||
pthread_t _threadID;
|
pthread_t _threadID;
|
||||||
|
const char* _taskName;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
1386
MQTTSNGateway/src/linux/dtls/SensorNetwork.cpp
Normal file
File diff suppressed because it is too large
Load Diff
163
MQTTSNGateway/src/linux/dtls/SensorNetwork.h
Normal file
163
MQTTSNGateway/src/linux/dtls/SensorNetwork.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* 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 SENSORNETWORK_H_
|
||||||
|
#define SENSORNETWORK_H_
|
||||||
|
|
||||||
|
#include "MQTTSNGWDefines.h"
|
||||||
|
#include "Threading.h"
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <string>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace MQTTSNGW
|
||||||
|
{
|
||||||
|
/*===========================================
|
||||||
|
Class SensorNetAddreess
|
||||||
|
============================================*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int af;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct in_addr ad4;
|
||||||
|
struct in6_addr ad6;
|
||||||
|
} addr;
|
||||||
|
} ipAddr_t;
|
||||||
|
|
||||||
|
class SensorNetAddress
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SensorNetAddress();
|
||||||
|
~SensorNetAddress();
|
||||||
|
void setAddress(ipAddr_t *Address, uint16_t port);
|
||||||
|
int setAddress(string *ipAddrPort);
|
||||||
|
int setIpAddress(string *IpAddress);
|
||||||
|
void setFamily(int type);
|
||||||
|
int getFamily(void);
|
||||||
|
void setPort(in_port_t port);
|
||||||
|
void setSockaddr4(sockaddr_in *sockaddr);
|
||||||
|
void setSockaddr6(sockaddr_in6 *sockaddr);
|
||||||
|
void cpyAddr4(sockaddr_in *sockaddr);
|
||||||
|
void cpyAddr6(sockaddr_in6 *sockaddr);
|
||||||
|
void cpyAddr(SensorNetAddress *addr);
|
||||||
|
in_port_t getPort(void);
|
||||||
|
ipAddr_t* getIpAddress(void);
|
||||||
|
void setIndex(int index);
|
||||||
|
int getIndex(void);
|
||||||
|
|
||||||
|
void clear(void);
|
||||||
|
|
||||||
|
bool isMatch(SensorNetAddress *addr);
|
||||||
|
SensorNetAddress& operator =(SensorNetAddress &addr);
|
||||||
|
char* sprint(char *buf);
|
||||||
|
private:
|
||||||
|
int _pfdsIndex;
|
||||||
|
in_port_t _portNo;
|
||||||
|
ipAddr_t _ipAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
Class Connections
|
||||||
|
============================================*/
|
||||||
|
#define POLL_UCAST 0
|
||||||
|
#define POLL_MCAST 1
|
||||||
|
#define POLL_SSL 2
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int af;
|
||||||
|
SSL *ssl;
|
||||||
|
} afSSL_t;
|
||||||
|
|
||||||
|
class Connections
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Connections();
|
||||||
|
~Connections();
|
||||||
|
void initialize(int maxClient);
|
||||||
|
void close(int index);
|
||||||
|
int poll(int timeout);
|
||||||
|
int addClientSock(int sock);
|
||||||
|
int addClientSSL(SSL *ssl, int sock);
|
||||||
|
void setSockMulticast(int sock);
|
||||||
|
void setSockUnicast(int sock);
|
||||||
|
int getNumOfConnections(void);
|
||||||
|
int getNumOfClients(void);
|
||||||
|
SSL* getClientSSL(int index);
|
||||||
|
int getEventClient(int index);
|
||||||
|
int getSockClient(int index);
|
||||||
|
int getSockMulticast(void);
|
||||||
|
int getSockUnicast(void);
|
||||||
|
int getEventMulticast(void);
|
||||||
|
int getEventUnicast(void);
|
||||||
|
int getEventListen(void);
|
||||||
|
void closeSSL(int index);
|
||||||
|
void print(void);
|
||||||
|
private:
|
||||||
|
pollfd *_pollfds;
|
||||||
|
SSL **_ssls;
|
||||||
|
int _maxfds;
|
||||||
|
int _numfds;
|
||||||
|
Mutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
Class SensorNetwork
|
||||||
|
============================================*/
|
||||||
|
class SensorNetwork
|
||||||
|
{
|
||||||
|
friend class SensorNetSubTask;
|
||||||
|
public:
|
||||||
|
SensorNetwork();
|
||||||
|
~SensorNetwork();
|
||||||
|
|
||||||
|
int unicast(const uint8_t *payload, uint16_t payloadLength, SensorNetAddress *sendto);
|
||||||
|
int broadcast(const uint8_t *payload, uint16_t payloadLength);
|
||||||
|
int read(uint8_t *buf, uint16_t bufLen);
|
||||||
|
void initialize(void);
|
||||||
|
const char* getDescription(void);
|
||||||
|
SensorNetAddress* getSenderAddress(void);
|
||||||
|
Connections* getConnections(void);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int openV4(string *ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t ttl);
|
||||||
|
int openV6(string *ipAddress, string *interface, uint16_t multiPortNo, uint16_t uniPortNo, uint32_t hops);
|
||||||
|
int multicastRecv(uint8_t *buf, uint16_t len);
|
||||||
|
int getSendClient(int index, SensorNetAddress *addr);
|
||||||
|
int getSenderAddress(int sock, SensorNetAddress *addr);
|
||||||
|
int getUnicastClient(SensorNetAddress *addr);
|
||||||
|
void clearRecvData(int sock);
|
||||||
|
|
||||||
|
Mutex _mutex;
|
||||||
|
SensorNetAddress _senderAddr;
|
||||||
|
SensorNetAddress _multicastAddr;
|
||||||
|
SensorNetAddress _unicastAddr;
|
||||||
|
string _description;
|
||||||
|
SSL_CTX *_dtlsctx;
|
||||||
|
Connections *_conns;
|
||||||
|
sockaddr_in _serverAddr4;
|
||||||
|
sockaddr_in6 _serverAddr6;
|
||||||
|
int _af;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* SENSORNETWORK_H_ */
|
||||||
@@ -119,7 +119,7 @@ int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
|
|||||||
return LoRaLink::recv(buf, bufLen, &_clientAddr);
|
return LoRaLink::recv(buf, bufLen, &_clientAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SensorNetwork::initialize(void)
|
void SensorNetwork::initialize(void)
|
||||||
{
|
{
|
||||||
char param[MQTTSNGW_PARAM_MAX];
|
char param[MQTTSNGW_PARAM_MAX];
|
||||||
uint32_t baudrate = 115200;
|
uint32_t baudrate = 115200;
|
||||||
@@ -135,15 +135,22 @@ int SensorNetwork::initialize(void)
|
|||||||
theProcess->getParam("DeviceRxLoRaLink", param);
|
theProcess->getParam("DeviceRxLoRaLink", param);
|
||||||
_description += ", SerialRx ";
|
_description += ", SerialRx ";
|
||||||
_description += param;
|
_description += param;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
if ( LoRaLink::open(LORALINK_MODEM_RX, param, baudrate) < 0 )
|
if ( LoRaLink::open(LORALINK_MODEM_RX, param, baudrate) < 0 )
|
||||||
{
|
{
|
||||||
return -1;
|
throw EXCEPTION("Can't open a LoRaLink", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
theProcess->getParam("DeviceTxLoRaLink", param);
|
theProcess->getParam("DeviceTxLoRaLink", param);
|
||||||
_description += ", SerialTx ";
|
_description += ", SerialTx ";
|
||||||
_description += param;
|
_description += param;
|
||||||
return LoRaLink::open(LORALINK_MODEM_TX, param, baudrate);
|
errno = 0;
|
||||||
|
|
||||||
|
if ( LoRaLink::open(LORALINK_MODEM_TX, param, baudrate) < 0 )
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Can't open a LoRaLink", errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SensorNetwork::getDescription(void)
|
const char* SensorNetwork::getDescription(void)
|
||||||
@@ -376,7 +383,7 @@ bool LoRaLink::readApiFrame(LoRaLinkFrame_t* api, LoRaLinkReadParameters_t* para
|
|||||||
|
|
||||||
int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t pLen, SensorNetAddress* addr)
|
int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t pLen, SensorNetAddress* addr)
|
||||||
{
|
{
|
||||||
D_NWSTACK("\r\n===> Send: ");
|
D_LRSTACK("\r\n===> Send: ");
|
||||||
uint8_t buf[2] = { 0 };
|
uint8_t buf[2] = { 0 };
|
||||||
uint8_t chks = 0;
|
uint8_t chks = 0;
|
||||||
uint16_t len = pLen + 3; // 3 = DestAddr[1] + PayloadType[1] + Crc[1]
|
uint16_t len = pLen + 3; // 3 = DestAddr[1] + PayloadType[1] + Crc[1]
|
||||||
@@ -397,7 +404,7 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
|
|||||||
send(type);
|
send(type);
|
||||||
chks += type;
|
chks += type;
|
||||||
|
|
||||||
D_NWSTACK("\r\n Payload: ");
|
D_LRSTACK("\r\n Payload: ");
|
||||||
|
|
||||||
for ( uint8_t i = 0; i < pLen; i++ ){
|
for ( uint8_t i = 0; i < pLen; i++ ){
|
||||||
send(payload[i]); // Payload
|
send(payload[i]); // Payload
|
||||||
@@ -405,21 +412,21 @@ int LoRaLink::send(LoRaLinkPayloadType_t type, const uint8_t* payload, uint16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
chks = 0xff - chks;
|
chks = 0xff - chks;
|
||||||
D_NWSTACK(" checksum ");
|
D_LRSTACK(" checksum ");
|
||||||
send(chks);
|
send(chks);
|
||||||
D_NWSTACK("\r\n");
|
D_LRSTACK("\r\n");
|
||||||
|
|
||||||
/* wait ACK */
|
/* wait ACK */
|
||||||
_sem.timedwait(LORALINK_TIMEOUT_ACK);
|
_sem.timedwait(LORALINK_TIMEOUT_ACK);
|
||||||
|
|
||||||
if ( _respCd == LORALINK_NO_FREE_CH )
|
if ( _respCd == LORALINK_NO_FREE_CH )
|
||||||
{
|
{
|
||||||
D_NWSTACK(" Channel isn't free\r\n");
|
D_LRSTACK(" Channel isn't free\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if ( _respCd != LORALINK_ACK )
|
else if ( _respCd != LORALINK_ACK )
|
||||||
{
|
{
|
||||||
D_NWSTACK(" Not Acknowleged\r\n");
|
D_LRSTACK(" Not Acknowleged\r\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (int)pLen;
|
return (int)pLen;
|
||||||
@@ -472,7 +479,7 @@ int LoRaLink::recv(uint8_t* buf)
|
|||||||
/*
|
/*
|
||||||
if ( *buf == ESCAPE )
|
if ( *buf == ESCAPE )
|
||||||
{
|
{
|
||||||
D_NWSTACK( " %02x",buf[0] );
|
D_LRSTACK( " %02x",buf[0] );
|
||||||
if ( read(fd, buf, 1) == 1 )
|
if ( read(fd, buf, 1) == 1 )
|
||||||
{
|
{
|
||||||
*buf = PAD ^ *buf;
|
*buf = PAD ^ *buf;
|
||||||
@@ -484,7 +491,7 @@ int LoRaLink::recv(uint8_t* buf)
|
|||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
D_NWSTACK( " %02x",buf[0] );
|
D_LRSTACK(" %02x", buf[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,7 +552,7 @@ bool SerialPort::send(unsigned char b)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D_NWSTACK( " %02x", b);
|
D_LRSTACK(" %02x", b);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,11 @@ using namespace std;
|
|||||||
|
|
||||||
namespace MQTTSNGW
|
namespace MQTTSNGW
|
||||||
{
|
{
|
||||||
//#define DEBUG_NWSTACK
|
|
||||||
|
|
||||||
#ifdef DEBUG_NWSTACK
|
#ifdef DEBUG_NW
|
||||||
#define D_NWSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
#define D_LRSTACK(...) printf(__VA_ARGS__); fflush(stdout)
|
||||||
#else
|
#else
|
||||||
#define D_NWSTACK(...)
|
#define D_LRSTACK(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -173,7 +172,7 @@ public:
|
|||||||
int unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendto);
|
int unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendto);
|
||||||
int broadcast(const uint8_t* payload, uint16_t payloadLength);
|
int broadcast(const uint8_t* payload, uint16_t payloadLength);
|
||||||
int read(uint8_t* buf, uint16_t bufLen);
|
int read(uint8_t* buf, uint16_t bufLen);
|
||||||
int initialize(void);
|
void initialize(void);
|
||||||
const char* getDescription(void);
|
const char* getDescription(void);
|
||||||
SensorNetAddress* getSenderAddress(void);
|
SensorNetAddress* getSenderAddress(void);
|
||||||
|
|
||||||
|
|||||||
422
MQTTSNGateway/src/linux/rfcomm/SensorNetwork.cpp
Normal file
422
MQTTSNGateway/src/linux/rfcomm/SensorNetwork.cpp
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* 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
|
||||||
|
**************************************************************************************/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/rfcomm.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "SensorNetwork.h"
|
||||||
|
#include "MQTTSNGWProcess.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace MQTTSNGW;
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
* Class SensorNetAddreess
|
||||||
|
|
||||||
|
* These 4 methods are minimum requirements for the SensorNetAddress class.
|
||||||
|
* isMatch(SensorNetAddress* )
|
||||||
|
* operator =(SensorNetAddress& )
|
||||||
|
* setAddress(string* )
|
||||||
|
* sprint(char* )
|
||||||
|
|
||||||
|
* BlePort class requires these 3 methods.
|
||||||
|
* getIpAddress(void)
|
||||||
|
* getPortNo(void)
|
||||||
|
* setAddress(uint32_t BtAddr, uint16_t channel)
|
||||||
|
|
||||||
|
============================================*/
|
||||||
|
bdaddr_t NullAddr = { 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
SensorNetAddress::SensorNetAddress()
|
||||||
|
{
|
||||||
|
_channel = 0;
|
||||||
|
bacpy(&_bdAddr, &NullAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorNetAddress::~SensorNetAddress()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bdaddr_t* SensorNetAddress::getAddress(void)
|
||||||
|
{
|
||||||
|
return &_bdAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SensorNetAddress::getPortNo(void)
|
||||||
|
{
|
||||||
|
return _channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SensorNetAddress::setAddress(bdaddr_t BdAddr, uint16_t channel)
|
||||||
|
{
|
||||||
|
bacpy(&_bdAddr, &BdAddr);
|
||||||
|
_channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Address data to SensorNetAddress
|
||||||
|
*
|
||||||
|
* @param *dev_channel is "Device_Address.Channel" format string
|
||||||
|
* @return success = 0, Invalid format = -1
|
||||||
|
*
|
||||||
|
* Valid channels are 1 to 30.
|
||||||
|
*
|
||||||
|
* Client01,XX:XX:XX:XX:XX:XX.1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int SensorNetAddress::setAddress(string* dev_channel)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
size_t pos = dev_channel->find_first_of(".");
|
||||||
|
|
||||||
|
if (pos == string::npos)
|
||||||
|
{
|
||||||
|
_channel = 0;
|
||||||
|
memset(&_bdAddr, 0, sizeof(bdaddr_t));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
string dvAddr = dev_channel->substr(0, pos);
|
||||||
|
string strchannel = dev_channel->substr(pos + 1);
|
||||||
|
if (strchannel == "*")
|
||||||
|
{
|
||||||
|
_channel = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_channel = atoi(strchannel.c_str());
|
||||||
|
}
|
||||||
|
str2ba(dvAddr.c_str(), &_bdAddr);
|
||||||
|
|
||||||
|
if ((_channel < 0 && _channel > 30) || bacmp(&_bdAddr, &NullAddr) == 0)
|
||||||
|
{
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SensorNetAddress::isMatch(SensorNetAddress* addr)
|
||||||
|
{
|
||||||
|
return ((this->_channel == addr->_channel) && bacmp(&this->_bdAddr, &addr->_bdAddr) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorNetAddress& SensorNetAddress::operator =(SensorNetAddress& addr)
|
||||||
|
{
|
||||||
|
this->_channel = addr._channel;
|
||||||
|
this->_bdAddr = addr._bdAddr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SensorNetAddress::sprint(char* buf)
|
||||||
|
{
|
||||||
|
ba2str(const_cast<bdaddr_t*>(&_bdAddr), buf);
|
||||||
|
sprintf(buf + strlen(buf), ".%d", _channel);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*================================================================
|
||||||
|
Class SensorNetwork
|
||||||
|
|
||||||
|
getDescpription( ) is used by Gateway::initialize( )
|
||||||
|
initialize( ) is used by Gateway::initialize( )
|
||||||
|
getSenderAddress( ) is used by ClientRecvTask::run( )
|
||||||
|
broadcast( ) is used by MQTTSNPacket::broadcast( )
|
||||||
|
unicast( ) is used by MQTTSNPacket::unicast( )
|
||||||
|
read( ) is used by MQTTSNPacket::recv( )
|
||||||
|
|
||||||
|
================================================================*/
|
||||||
|
|
||||||
|
SensorNetwork::SensorNetwork()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorNetwork::~SensorNetwork()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SensorNetwork::unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendToAddr)
|
||||||
|
{
|
||||||
|
uint16_t ch = sendToAddr->getPortNo();
|
||||||
|
RfcommPort* blep = &_rfPorts[ch - 1];
|
||||||
|
int rc = 0;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if ((rc = blep->send(payload, (uint32_t) payloadLength)) < 0)
|
||||||
|
{
|
||||||
|
D_NWSTACK("errno == %d in BlePort::sendto %d\n", errno, ch);
|
||||||
|
} D_NWSTACK("sendto %u length = %d\n", ch, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SensorNetwork::broadcast(const uint8_t* payload, uint16_t payloadLength)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RFCOMM_CH; i++)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
if (_rfPorts[i].getSock() > 0)
|
||||||
|
{
|
||||||
|
if ((rc = _rfPorts[i].send(payload, (uint32_t) payloadLength)) < 0)
|
||||||
|
{
|
||||||
|
D_NWSTACK("errno == %d in BlePort::sendto %d\n", errno, i + 1);
|
||||||
|
}D_NWSTACK("sendto %u length = %d\n", i + 1, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set recvfds;
|
||||||
|
int maxSock = 0;
|
||||||
|
|
||||||
|
timeout.tv_sec = 1;
|
||||||
|
timeout.tv_usec = 0; // 1 sec
|
||||||
|
FD_ZERO(&recvfds);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RFCOMM_CH; i++)
|
||||||
|
{
|
||||||
|
if (_rfPorts[i]._rfCommSock > 0)
|
||||||
|
{
|
||||||
|
if (maxSock < _rfPorts[i]._rfCommSock)
|
||||||
|
{
|
||||||
|
maxSock = _rfPorts[i]._rfCommSock;
|
||||||
|
}
|
||||||
|
FD_SET(_rfPorts[i]._rfCommSock, &recvfds);
|
||||||
|
}
|
||||||
|
else if (_rfPorts[i]._listenSock > 0)
|
||||||
|
{
|
||||||
|
if (maxSock < _rfPorts[i]._listenSock)
|
||||||
|
{
|
||||||
|
maxSock = _rfPorts[i]._listenSock;
|
||||||
|
}
|
||||||
|
FD_SET(_rfPorts[i]._listenSock, &recvfds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
if (select(maxSock + 1, &recvfds, 0, 0, &timeout) > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_RFCOMM_CH; i++)
|
||||||
|
{
|
||||||
|
if (_rfPorts[i]._rfCommSock > 0)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(_rfPorts[i]._rfCommSock, &recvfds))
|
||||||
|
{
|
||||||
|
rc = _rfPorts[i].recv(buf, bufLen);
|
||||||
|
if (rc == -1)
|
||||||
|
{
|
||||||
|
_rfPorts[i].close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_rfPorts[i]._listenSock > 0)
|
||||||
|
{
|
||||||
|
if (FD_ISSET(_rfPorts[i]._listenSock, &recvfds))
|
||||||
|
{
|
||||||
|
int sock = _rfPorts[i].accept(&_senderAddr);
|
||||||
|
if (sock > 0)
|
||||||
|
{
|
||||||
|
_rfPorts[i]._rfCommSock = sock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare UDP sockets and description of SensorNetwork like
|
||||||
|
* "UDP Multicast 225.1.1.1:1883 Gateway Port 10000".
|
||||||
|
* The description is for a start up prompt.
|
||||||
|
*/
|
||||||
|
void SensorNetwork::initialize(void)
|
||||||
|
{
|
||||||
|
char param[MQTTSNGW_PARAM_MAX];
|
||||||
|
string devAddr;
|
||||||
|
SensorNetAddress sa;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* theProcess->getParam( ) copies
|
||||||
|
* a text specified by "Key" into param[] from the Gateway.conf
|
||||||
|
*
|
||||||
|
* in Gateway.conf e.g.
|
||||||
|
*
|
||||||
|
* # BLE
|
||||||
|
* RFCOMM=XX:XX:XX:XX:XX:XX.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (theProcess->getParam("RFCOMMAddress", param) == 0)
|
||||||
|
{
|
||||||
|
devAddr = param;
|
||||||
|
_description = "Bluetooth RFCOMM ";
|
||||||
|
_description += param;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (sa.setAddress(&devAddr) == -1)
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Invalid Bluetooth Address", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare BLE sockets */
|
||||||
|
WRITELOG("Initialize RFCOMM\n");
|
||||||
|
int rc = MAX_RFCOMM_CH;
|
||||||
|
for (uint16_t i = 0; i < MAX_RFCOMM_CH; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
rc += _rfPorts[i].open(sa.getAddress(), i + 1);
|
||||||
|
}
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Can't open Bluetooth RFComms", errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* SensorNetwork::getDescription(void)
|
||||||
|
{
|
||||||
|
return _description.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||||
|
{
|
||||||
|
return &_senderAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
Class BleStack
|
||||||
|
=========================================*/
|
||||||
|
|
||||||
|
RfcommPort::RfcommPort()
|
||||||
|
{
|
||||||
|
_disconReq = false;
|
||||||
|
_rfCommSock = 0;
|
||||||
|
_listenSock = 0;
|
||||||
|
_channel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RfcommPort::~RfcommPort()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (_listenSock > 0)
|
||||||
|
{
|
||||||
|
::close(_listenSock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RfcommPort::close(void)
|
||||||
|
{
|
||||||
|
if (_rfCommSock > 0)
|
||||||
|
{
|
||||||
|
::close(_rfCommSock);
|
||||||
|
_rfCommSock = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int RfcommPort::open(bdaddr_t* devAddr, uint16_t channel)
|
||||||
|
{
|
||||||
|
const int reuse = 1;
|
||||||
|
|
||||||
|
if (channel < 1 || channel > 30)
|
||||||
|
{
|
||||||
|
D_NWSTACK("error Channel undefined in BlePort::open\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------ Create unicast socket --------*/
|
||||||
|
_listenSock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||||
|
if (_listenSock < 0)
|
||||||
|
{
|
||||||
|
D_NWSTACK("error can't create Rfcomm socket in BlePort::open\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_rc addru;
|
||||||
|
addru.rc_family = AF_BLUETOOTH;
|
||||||
|
addru.rc_channel = channel;
|
||||||
|
bacpy(&addru.rc_bdaddr, devAddr);
|
||||||
|
|
||||||
|
uint8_t buf[20];
|
||||||
|
ba2str(devAddr, (char*) buf);
|
||||||
|
setsockopt(_listenSock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||||
|
errno = 0;
|
||||||
|
if (::bind(_listenSock, (sockaddr*) &addru, sizeof(addru)) < 0)
|
||||||
|
{
|
||||||
|
WRITELOG("\033[0m\033[0;31mCan't bind RFCOMM CH = %d %s\033[0m\033[0;37m\n", channel, strerror(errno));
|
||||||
|
::close(_listenSock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_channel = channel;
|
||||||
|
::listen(_listenSock, 1);
|
||||||
|
WRITELOG("Listen RFCOMM CH = %d\n", channel);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RfcommPort::send(const uint8_t* buf, uint32_t length)
|
||||||
|
{
|
||||||
|
return ::send(_rfCommSock, buf, length, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RfcommPort::recv(uint8_t* buf, uint16_t len)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
rc = ::read(_rfCommSock, buf, len);
|
||||||
|
if (rc < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWSTACK("errno = %d in BlePort::recv\n", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RfcommPort::accept(SensorNetAddress* addr)
|
||||||
|
{
|
||||||
|
struct sockaddr_rc devAddr = { 0 };
|
||||||
|
socklen_t opt = sizeof(devAddr);
|
||||||
|
|
||||||
|
int sock = 0;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
sock = ::accept(_listenSock, (sockaddr *) &devAddr, &opt);
|
||||||
|
if (sock < 0 && errno != EAGAIN)
|
||||||
|
{
|
||||||
|
D_NWSTACK("errno == %d in BlePort::recv\n", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bdaddr_t bdAddr = devAddr.rc_bdaddr;
|
||||||
|
addr->setAddress(bdAddr, _channel);
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RfcommPort::getSock(void)
|
||||||
|
{
|
||||||
|
return _rfCommSock;
|
||||||
|
}
|
||||||
98
MQTTSNGateway/src/linux/rfcomm/SensorNetwork.h
Normal file
98
MQTTSNGateway/src/linux/rfcomm/SensorNetwork.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**************************************************************************************
|
||||||
|
* 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 SENSORNETWORK_H_
|
||||||
|
#define SENSORNETWORK_H_
|
||||||
|
|
||||||
|
#include "MQTTSNGWDefines.h"
|
||||||
|
#include <string>
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace MQTTSNGW
|
||||||
|
{
|
||||||
|
|
||||||
|
#define MAX_RFCOMM_CH 30
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
Class SensorNetAddreess
|
||||||
|
============================================*/
|
||||||
|
class SensorNetAddress
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SensorNetAddress();
|
||||||
|
~SensorNetAddress();
|
||||||
|
void setAddress(bdaddr_t bdAddr, uint16_t channel);
|
||||||
|
int setAddress(string* data);
|
||||||
|
uint16_t getPortNo(void);
|
||||||
|
bdaddr_t* getAddress(void);
|
||||||
|
bool isMatch(SensorNetAddress* addr);
|
||||||
|
SensorNetAddress& operator =(SensorNetAddress& addr);
|
||||||
|
char* sprint(char* buf);
|
||||||
|
private:
|
||||||
|
uint16_t _channel;
|
||||||
|
bdaddr_t _bdAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*========================================
|
||||||
|
Class RfcommPort
|
||||||
|
=======================================*/
|
||||||
|
class RfcommPort
|
||||||
|
{
|
||||||
|
friend class SensorNetwork;
|
||||||
|
public:
|
||||||
|
RfcommPort();
|
||||||
|
virtual ~RfcommPort();
|
||||||
|
|
||||||
|
int open(bdaddr_t* devAddress, uint16_t channel);
|
||||||
|
void close(void);
|
||||||
|
int send(const uint8_t* buf, uint32_t length);
|
||||||
|
int recv(uint8_t* buf, uint16_t len);
|
||||||
|
int getSock(void);
|
||||||
|
int accept(SensorNetAddress* addr);
|
||||||
|
private:
|
||||||
|
int _rfCommSock;
|
||||||
|
int _listenSock;
|
||||||
|
uint16_t _channel;
|
||||||
|
bool _disconReq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
Class SensorNetwork
|
||||||
|
============================================*/
|
||||||
|
class SensorNetwork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SensorNetwork();
|
||||||
|
~SensorNetwork();
|
||||||
|
|
||||||
|
int unicast(const uint8_t* payload, uint16_t payloadLength, SensorNetAddress* sendto);
|
||||||
|
int broadcast(const uint8_t* payload, uint16_t payloadLength);
|
||||||
|
int read(uint8_t* buf, uint16_t bufLen);
|
||||||
|
void initialize(void);
|
||||||
|
const char* getDescription(void);
|
||||||
|
SensorNetAddress* getSenderAddress(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// sockets for RFCOMM
|
||||||
|
RfcommPort _rfPorts[MAX_RFCOMM_CH];
|
||||||
|
SensorNetAddress _senderAddr;
|
||||||
|
string _description;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* SENSORNETWORK_H_ */
|
||||||
@@ -20,10 +20,13 @@
|
|||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <poll.h>
|
||||||
#include "SensorNetwork.h"
|
#include "SensorNetwork.h"
|
||||||
#include "MQTTSNGWProcess.h"
|
#include "MQTTSNGWProcess.h"
|
||||||
|
|
||||||
@@ -142,7 +145,7 @@ char* SensorNetAddress::sprint(char* buf)
|
|||||||
In Gateway version 1.0
|
In Gateway version 1.0
|
||||||
|
|
||||||
getDescpription( ) is used by Gateway::initialize( )
|
getDescpription( ) is used by Gateway::initialize( )
|
||||||
initialize( ) is used by ClientSendTask::initialize( )
|
initialize( ) is used by Gateway::initialize( )
|
||||||
getSenderAddress( ) is used by ClientRecvTask::run( )
|
getSenderAddress( ) is used by ClientRecvTask::run( )
|
||||||
broadcast( ) is used by MQTTSNPacket::broadcast( )
|
broadcast( ) is used by MQTTSNPacket::broadcast( )
|
||||||
unicast( ) is used by MQTTSNPacket::unicast( )
|
unicast( ) is used by MQTTSNPacket::unicast( )
|
||||||
@@ -170,16 +173,15 @@ int SensorNetwork::broadcast(const uint8_t* payload, uint16_t payloadLength)
|
|||||||
|
|
||||||
int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
|
int SensorNetwork::read(uint8_t* buf, uint16_t bufLen)
|
||||||
{
|
{
|
||||||
return UDPPort::recv(buf, bufLen, &_clientAddr);
|
return UDPPort::recv(buf, bufLen, &_senderAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare UDP sockets and description of SensorNetwork like
|
* Prepare UDP sockets and description of SensorNetwork like
|
||||||
* "UDP Multicast 225.1.1.1:1883 Gateway Port 10000".
|
* "UDP Multicast 225.1.1.1:1883 Gateway Port 10000".
|
||||||
* The description is for a start up prompt.
|
* The description is for a start up prompt.
|
||||||
* @return success = 0, error = -1
|
|
||||||
*/
|
*/
|
||||||
int SensorNetwork::initialize(void)
|
void SensorNetwork::initialize(void)
|
||||||
{
|
{
|
||||||
char param[MQTTSNGW_PARAM_MAX];
|
char param[MQTTSNGW_PARAM_MAX];
|
||||||
uint16_t multicastPortNo = 0;
|
uint16_t multicastPortNo = 0;
|
||||||
@@ -213,18 +215,22 @@ int SensorNetwork::initialize(void)
|
|||||||
if (theProcess->getParam("GatewayPortNo", param) == 0)
|
if (theProcess->getParam("GatewayPortNo", param) == 0)
|
||||||
{
|
{
|
||||||
unicastPortNo = atoi(param);
|
unicastPortNo = atoi(param);
|
||||||
_description += " Gateway Port ";
|
_description += ", Gateway Port:";
|
||||||
_description += param;
|
_description += param;
|
||||||
}
|
}
|
||||||
if (theProcess->getParam("MulticastTTL", param) == 0)
|
if (theProcess->getParam("MulticastTTL", param) == 0)
|
||||||
{
|
{
|
||||||
ttl = atoi(param);
|
ttl = atoi(param);
|
||||||
_description += " TTL: ";
|
_description += ", TTL:";
|
||||||
_description += param;
|
_description += param;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare UDP sockets */
|
/* setup UDP sockets */
|
||||||
return UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl);
|
errno = 0;
|
||||||
|
if ( UDPPort::open(ip.c_str(), multicastPortNo, unicastPortNo, ttl) < 0 )
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Can't open a UDP", errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SensorNetwork::getDescription(void)
|
const char* SensorNetwork::getDescription(void)
|
||||||
@@ -234,7 +240,7 @@ const char* SensorNetwork::getDescription(void)
|
|||||||
|
|
||||||
SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
||||||
{
|
{
|
||||||
return &_clientAddr;
|
return &_senderAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=========================================
|
/*=========================================
|
||||||
@@ -244,8 +250,7 @@ SensorNetAddress* SensorNetwork::getSenderAddress(void)
|
|||||||
UDPPort::UDPPort()
|
UDPPort::UDPPort()
|
||||||
{
|
{
|
||||||
_disconReq = false;
|
_disconReq = false;
|
||||||
_sockfdUnicast = -1;
|
memset(_pollFds, 0, sizeof(_pollFds));
|
||||||
_sockfdMulticast = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPPort::~UDPPort()
|
UDPPort::~UDPPort()
|
||||||
@@ -255,22 +260,20 @@ UDPPort::~UDPPort()
|
|||||||
|
|
||||||
void UDPPort::close(void)
|
void UDPPort::close(void)
|
||||||
{
|
{
|
||||||
if (_sockfdUnicast > 0)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
::close(_sockfdUnicast);
|
if (_pollFds[i].fd > 0)
|
||||||
_sockfdUnicast = -1;
|
{
|
||||||
|
::close(_pollFds[i].fd);
|
||||||
|
_pollFds[i].fd = 0;
|
||||||
}
|
}
|
||||||
if (_sockfdMulticast > 0)
|
|
||||||
{
|
|
||||||
::close(_sockfdMulticast);
|
|
||||||
_sockfdMulticast = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl)
|
int UDPPort::open(const char *multicastIP, uint16_t multiPortNo, uint16_t uniPortNo, unsigned int ttl)
|
||||||
{
|
{
|
||||||
char loopch = 0;
|
int optval = 0;
|
||||||
const int reuse = 1;
|
int sock = 0;
|
||||||
|
|
||||||
if (uniPortNo == 0 || multiPortNo == 0)
|
if (uniPortNo == 0 || multiPortNo == 0)
|
||||||
{
|
{
|
||||||
@@ -278,90 +281,87 @@ int UDPPort::open(const char* ipAddress, uint16_t multiPortNo, uint16_t uniPortN
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ip = inet_addr(ipAddress);
|
|
||||||
_grpAddr.setAddress(ip, htons(multiPortNo));
|
|
||||||
_clientAddr.setAddress(ip, htons(uniPortNo));
|
|
||||||
_ttl = ttl;
|
|
||||||
|
|
||||||
/*------ Create unicast socket --------*/
|
/*------ Create unicast socket --------*/
|
||||||
_sockfdUnicast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (_sockfdUnicast < 0)
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
|
D_NWSTACK("error can't create unicast socket in UDPPort::open\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt(_sockfdUnicast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
|
||||||
|
|
||||||
sockaddr_in addru;
|
sockaddr_in addru;
|
||||||
addru.sin_family = AF_INET;
|
addru.sin_family = AF_INET;
|
||||||
addru.sin_port = htons(uniPortNo);
|
addru.sin_port = htons(uniPortNo);
|
||||||
addru.sin_addr.s_addr = INADDR_ANY;
|
addru.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
if (::bind(_sockfdUnicast, (sockaddr*) &addru, sizeof(addru)) < 0)
|
if (::bind(sock, (sockaddr*) &addru, sizeof(addru)) < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("error can't bind unicast socket in UDPPort::open\n");
|
D_NWSTACK("error can't bind unicast socket in UDPPort::open\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
|
|
||||||
{
|
_pollFds[0].fd = sock;
|
||||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
_pollFds[0].events = POLLIN;
|
||||||
close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------ Create Multicast socket --------*/
|
/*------ Create Multicast socket --------*/
|
||||||
_sockfdMulticast = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (_sockfdMulticast < 0)
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("error can't create multicast socket in UDPPort::open\n");
|
D_NWSTACK("error can't create multicast socket in UDPPort::open\n");
|
||||||
close();
|
close();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt(_sockfdMulticast, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
optval = 1;
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||||
|
|
||||||
sockaddr_in addrm;
|
sockaddr_in addrm;
|
||||||
addrm.sin_family = AF_INET;
|
addrm.sin_family = AF_INET;
|
||||||
addrm.sin_port = _grpAddr.getPortNo();
|
addrm.sin_port = htons(multiPortNo);
|
||||||
addrm.sin_addr.s_addr = INADDR_ANY;
|
addrm.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
if (::bind(_sockfdMulticast, (sockaddr*) &addrm, sizeof(addrm)) < 0)
|
if (::bind(sock, (sockaddr*) &addrm, sizeof(addrm)) < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("error can't bind multicast socket in UDPPort::open\n");
|
D_NWSTACK("error can't bind multicast socket in UDPPort::open\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_LOOP, (char*) &loopch, sizeof(loopch)) < 0)
|
|
||||||
|
ip_mreq mreq;
|
||||||
|
memset(&mreq, 0, sizeof(mreq));
|
||||||
|
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||||
|
mreq.imr_multiaddr.s_addr = inet_addr(multicastIP);
|
||||||
|
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||||
|
{
|
||||||
|
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
|
||||||
|
close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
|
||||||
|
{
|
||||||
|
D_NWSTACK("error Multicast IP_MULTICAST_TTL in UDPPort::open\n");
|
||||||
|
close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_NW
|
||||||
|
optval = 1;
|
||||||
|
#else
|
||||||
|
optval = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &optval, sizeof(optval)) < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
D_NWSTACK("error IP_MULTICAST_LOOP in UDPPort::open\n");
|
||||||
close();
|
close();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_mreq mreq;
|
_multicastAddr.setAddress(inet_addr(multicastIP), htons(multiPortNo));
|
||||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
_pollFds[1].fd = sock;
|
||||||
mreq.imr_multiaddr.s_addr = _grpAddr.getIpAddress();
|
_pollFds[1].events = POLLIN;
|
||||||
|
|
||||||
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
|
||||||
{
|
|
||||||
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
|
|
||||||
close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setsockopt(_sockfdMulticast, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,sizeof(ttl)) < 0)
|
|
||||||
{
|
|
||||||
D_NWSTACK("error Multicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
|
|
||||||
close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setsockopt(_sockfdUnicast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
|
||||||
{
|
|
||||||
D_NWSTACK("error Unicast IP_ADD_MEMBERSHIP in UDPPort::open\n");
|
|
||||||
close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,52 +372,33 @@ int UDPPort::unicast(const uint8_t* buf, uint32_t length, SensorNetAddress* addr
|
|||||||
dest.sin_port = addr->getPortNo();
|
dest.sin_port = addr->getPortNo();
|
||||||
dest.sin_addr.s_addr = addr->getIpAddress();
|
dest.sin_addr.s_addr = addr->getIpAddress();
|
||||||
|
|
||||||
int status = ::sendto(_sockfdUnicast, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
int status = ::sendto(_pollFds[0].fd, buf, length, 0, (const sockaddr*) &dest, sizeof(dest));
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
D_NWSTACK("errno == %d in UDPPort::sendto\n", errno);
|
D_NWSTACK("errno == %d in UDPPort::sendto\n", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status);
|
D_NWSTACK("sendto %s:%u length = %d\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPPort::broadcast(const uint8_t* buf, uint32_t length)
|
int UDPPort::broadcast(const uint8_t* buf, uint32_t length)
|
||||||
{
|
{
|
||||||
return unicast(buf, length, &_grpAddr);
|
return unicast(buf, length, &_multicastAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPPort::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
|
int UDPPort::recv(uint8_t* buf, uint16_t len, SensorNetAddress* addr)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
|
||||||
fd_set recvfds;
|
|
||||||
int maxSock = 0;
|
|
||||||
|
|
||||||
timeout.tv_sec = 1;
|
|
||||||
timeout.tv_usec = 0; // 1 sec
|
|
||||||
FD_ZERO(&recvfds);
|
|
||||||
FD_SET(_sockfdUnicast, &recvfds);
|
|
||||||
FD_SET(_sockfdMulticast, &recvfds);
|
|
||||||
|
|
||||||
if (_sockfdMulticast > _sockfdUnicast)
|
|
||||||
{
|
|
||||||
maxSock = _sockfdMulticast;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxSock = _sockfdUnicast;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if ( select(maxSock + 1, &recvfds, 0, 0, &timeout) > 0 )
|
poll(_pollFds, 2, 2000); // Timeout 2 seconds
|
||||||
|
|
||||||
|
if (_pollFds[0].revents == POLLIN)
|
||||||
{
|
{
|
||||||
if (FD_ISSET(_sockfdUnicast, &recvfds))
|
rc = recvfrom(_pollFds[0].fd, buf, len, 0, addr);
|
||||||
{
|
|
||||||
rc = recvfrom(_sockfdUnicast, buf, len, 0, addr);
|
|
||||||
}
|
}
|
||||||
else if (FD_ISSET(_sockfdMulticast, &recvfds))
|
else if (_pollFds[1].revents == POLLIN)
|
||||||
{
|
{
|
||||||
rc = recvfrom(_sockfdMulticast, buf, len, 0, &_grpAddr);
|
rc = recvfrom(_pollFds[1].fd, buf, len, 0, addr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user